Skip to main content

Default Configs

Use whenyou need the exact value the transport starts from before overriding it.

You getevery stream, consumer and connection default, and the exported constant that holds it.

Override any of these through module configuration. Your values merge on top of the defaults, so name only what you change.

Stream Defaults​

Every stream is created with storage: File, num_replicas: 1 (see replicas in production), discard: Old, allow_direct: true and compression: S2. What differs per kind:

PropertyEventCommandBroadcastOrderedScheduleDLQ
retentionWorkqueueWorkqueueLimitsLimitsWorkqueueLimits
allow_rollup_hdrstruefalsetruefalsetruefalse
max_consumers10050200100100100
max_msg_size1 MB1 MB1 MB1 MB1 MB1 MB
max_msgs_per_subject100,00010,00050,000500,000unlimited50,000
max_msgs1,000,000100,000500,0005,000,000unlimited500,000
max_bytes512 MB64 MB256 MB1 GB64 MB256 MB
max_age7 days3 minutes1 hour1 daynone30 days
duplicate_window2 minutes30 seconds2 minutes2 minutes2 minutes2 minutes

max_bytes is what the account is charged for, not what the stream currently holds: JetStream counts it against the account's storage budget the moment the stream is created. A service that provisions events plus a DLQ reserves 768 MB, and one that also uses ordered delivery reserves 1.75 GB, so a 10 GB file store carries roughly a dozen services instead of one.

max_msg_size matches the NATS server's own max_payload default of 1 MB. A larger value here has no effect until the server is reconfigured to accept larger payloads.

Sizes are binary: 1 MB is 1,048,576 bytes, 512 MB is 536,870,912 bytes. Durations are written with toNanos, so max_age: toNanos(7, 'days').

What each kind is for:

  • Event carries workqueue events. A message is removed once a consumer acks it.
  • Command carries RPC requests in JetStream RPC mode only. It is short-lived: a request nobody answered within three minutes is a request nobody wants answered.
  • Broadcast is one stream shared by every service. An hour of max_age gives a starting pod enough catch-up without letting config updates pile up.
  • Ordered keeps messages for a day under Limits retention, because an ordered consumer replays a subject from the beginning instead of consuming it away.
  • Schedule holds recurring schedules and their ticks, and exists only when a handler declares schedule. It also sets allow_msg_schedules and allow_msg_ttl. max_age stays off because an aged-out holder silently stops its schedule; ticks expire through their own TTL instead.
  • DLQ is created unless you pass dlq: false. Thirty days under Limits retention: reading a dead letter must not remove it. See Dead Letter Queue.
S2 compression

S2 is a Snappy-compatible codec with better ratios. It trades some CPU, depending on payload size and entropy, for less disk I/O and storage. Override per kind:

import { StoreCompression } from '@nats-io/jetstream';

events: {
stream: { compression: StoreCompression.None },
}
Scheduling

To enable message scheduling, add allow_msg_schedules: true to the event stream config. On a server too old for it, startup throws JetstreamCapabilityError; see NATS server versions.

Consumer Defaults​

Every durable consumer uses ack_policy: Explicit, deliver_policy: All and replay_policy: Instant. What differs:

PropertyEventCommandBroadcastSchedule
ack_wait10 seconds5 minutes10 seconds10 seconds
max_deliver3133
max_ack_pending100100100100

An event that fails three times is dead-lettered. Between attempts the transport naks with a delay from the retry curve ([2000, 10000] ms), so the three attempts span roughly twelve seconds instead of burning out in milliseconds.

The delay is applied client-side, which leaves ack_wait at its full value, so a slow handler is not redelivered while it still runs. Tune the curve per kind with retry, or pass false to nak immediately.

A command is delivered once and never retried, so an RPC failure reaches the caller instead of being repeated behind their back.

note

Ordered consumers have no durable configuration: they are ephemeral and managed by the @nats-io/jetstream client.

Connection Defaults​

PropertyValueNotes
maxReconnectAttempts-1Unlimited reconnection attempts
reconnectTimeWait10001 second between reconnection attempts

The transport keeps reconnecting after a network failure. Override either value through connectionOptions.

Timeouts​

TimeoutDefaultConstant
Core RPC (standard request-reply)30 secondsDEFAULT_RPC_TIMEOUT
JetStream RPC (persistent)3 minutesDEFAULT_JETSTREAM_RPC_TIMEOUT
Graceful shutdown drain10 secondsDEFAULT_SHUTDOWN_TIMEOUT

The JetStream RPC timeout is longer on purpose: the message is persisted to a stream first, and the consumer may take a while to reach it.

The shutdown value bounds drain() on each NATS connection, which waits for in-flight messages; when it runs out, the transport closes the connection anyway. Raise it only if drains hit the ceiling. See Graceful Shutdown.

Replicas in production​

The default num_replicas: 1 suits development and single-node NATS. On a production cluster, set num_replicas: 3 so data survives a node failure:

JetstreamModule.forRoot({
name: 'orders',
servers: ['nats://nats-1:4222', 'nats://nats-2:4222', 'nats://nats-3:4222'],
events: { stream: { num_replicas: 3 } },
broadcast: { stream: { num_replicas: 3 } },
ordered: { stream: { num_replicas: 3 } },
schedule: { stream: { num_replicas: 3 } },
rpc: { mode: 'jetstream', stream: { num_replicas: 3 } },
dlq: { stream: { num_replicas: 3 } },
});
tip

num_replicas is mutable: NATS adds or removes replicas on an existing stream without downtime or recreation.

Immutable vs mutable stream properties​

Mutable (can be changed at any time)​

num_replicas, max_age, max_bytes, max_msgs, max_msg_size, max_msgs_per_subject, discard, duplicate_window, subjects, compression, description, allow_rollup_hdrs, allow_direct

The transport applies mutable changes on startup: update the value in forRoot() and restart.

Enable-only (can be turned on, but never off)​

A normal update enables these on an existing stream, without recreating it or losing messages. Once on, they cannot be turned off.

PropertyDefaultNotes
allow_msg_schedulesfalseEnables message scheduling. true on the schedule stream
allow_msg_ttlfalseEnables per-message TTL. true on the schedule stream
deny_deletefalsePrevents message deletion through the API
deny_purgefalsePrevents stream purging through the API

Immutable (locked after creation)​

PropertyDefaultMigratableNotes
namederived from service nameNoCannot be renamed
retentionWorkqueue or LimitsNoControlled by the transport: a mismatch is always an error
storageFileYesMigrated with provisioning.allowDestructiveMigration

The transport migrates storage through blue-green stream recreation. The Stream Migration guide covers how it works, rolling updates and limitations.

retention is never migratable

retention follows the kind (Workqueue for events, commands and schedules, Limits for broadcast, ordered and DLQ). A running stream with a different policy fails startup, whatever provisioning.allowDestructiveMigration says.

Exported constants​

Every default above is exported as a typed constant, for composing overrides or writing tests.

Stream and consumer defaults:

ConstantContents
DEFAULT_EVENT_STREAM_CONFIGEvent (workqueue) stream defaults
DEFAULT_BROADCAST_STREAM_CONFIGBroadcast stream defaults (shared broadcast-stream)
DEFAULT_ORDERED_STREAM_CONFIGOrdered stream defaults
DEFAULT_SCHEDULE_STREAM_CONFIGSchedule stream defaults
DEFAULT_COMMAND_STREAM_CONFIGJetStream RPC command stream defaults
DEFAULT_DLQ_STREAM_CONFIGDead Letter Queue stream defaults
DEFAULT_EVENT_CONSUMER_CONFIGEvent consumer defaults
DEFAULT_BROADCAST_CONSUMER_CONFIGBroadcast consumer defaults
DEFAULT_COMMAND_CONSUMER_CONFIGJetStream RPC command consumer defaults
DEFAULT_SCHEDULE_CONSUMER_CONFIGSchedule tick consumer defaults

Timeouts and the handler metadata registry:

ConstantValueMeaning
DEFAULT_RPC_TIMEOUT30_000Core RPC timeout, ms
DEFAULT_JETSTREAM_RPC_TIMEOUT180_000JetStream RPC timeout, ms
DEFAULT_SHUTDOWN_TIMEOUT10_000Graceful shutdown drain, ms
DEFAULT_METADATA_BUCKET'handler_registry'KV bucket holding handler entries
DEFAULT_METADATA_REPLICAS1KV bucket replicas
DEFAULT_METADATA_HISTORY1KV history depth: latest only
DEFAULT_METADATA_TTL30_000Entry TTL, refreshed by heartbeat, ms
MIN_METADATA_TTL5_000Lowest TTL the module accepts, ms

Other:

  • RESERVED_HEADERS; the Set<string> of header names blocked by JetstreamRecordBuilder.setHeader(). See Record Builder.
import { DEFAULT_EVENT_STREAM_CONFIG, toNanos } from '@horizon-republic/nestjs-jetstream';

events: {
stream: { ...DEFAULT_EVENT_STREAM_CONFIG, max_age: toNanos(14, 'days') },
}