Skip to main content

Stream and consumer policies

Much of what you configured in this chapter came down to policies. A policy is a config field that takes one value from a short, fixed list, and each policy answers one question about how the stream or the consumer behaves. You met most of them one page at a time as the ORDERS walkthrough grew; this page lines up all nine in one place.

Two things are true of every policy. Each has a default, and the defaults are safe to start with: ORDERS ran for most of the chapter without you touching them. And five of the nine are fixed the moment the stream or consumer exists. The server refuses the update, and the only way to change your mind is to recreate the object. The table near the end shows which ones.

Stream policies

Five policies shape a stream.

Retention decides when a message leaves the stream. limits keeps messages until a cap removes them. interest and workqueue remove messages once consumers have acked them. ORDERS stayed on limits, and the FULFILLMENT work queue ran on workqueue. Choosing among the three is covered on Retention policies.

Discard decides what happens when a stream at its limit receives one more message. old deletes the oldest messages to make room; new refuses the publish. ORDERS kept the default, old; Shaping the stream covers when new is worth the rejected publishes.

Storage decides where messages live. file writes them to disk and they survive a server restart. memory keeps them only in RAM: faster, and gone on restart. The choice applies to the whole stream, replicas included. How storage and replicas together decide what survives a failure is covered on Surviving node loss.

Compression is one this chapter didn't need. Setting it to s2 (from the default none) makes a file-storage stream compress message blocks on disk, spending CPU to cut disk usage. Repetitive payloads such as JSON compress well; already-compressed payloads such as images don't. Set it at creation with --compression s2 on nats stream add. Editing it later is allowed, but the new setting waits until the stream's store restarts, on a server restart or a leader change, and blocks already on disk stay as they are.

Persist mode decides when the server acknowledges a publish relative to writing it out. By default, the message is flushed to storage first and the PubAck follows. On async, the server acknowledges first and flushes in the background. That buys a higher ingest rate in exchange for a window in which a crash can lose messages the server already acked, so it fits data that arrives in volume and tolerates a lost tail, such as metrics — not an order log. async is only accepted on a file-storage stream with a single replica, and an async stream refuses the atomic batch publishing from Advanced publishing.

Every stream field, with each policy's values described inline, is in Reference → Stream Configuration.

Consumer policies

Four policies shape a consumer.

Deliver policy decides where a consumer starts reading, once, at creation. billing was created with all, which is also the default: start at the stream's first message. last starts at the newest message and continues live. new delivers only messages that arrive after the consumer is created. by_start_sequence and by_start_time start at a sequence or a point in time (--deliver 1000, --deliver 1h for an hour back). The remaining value, last_per_subject, starts with the newest message for each subject the consumer matches. That gives a latest-state view per subject, and it's what Key-Value watches are built on. Don't confuse it with the --last-per-subject flag of Reading messages directly. The two are different features that share a name: one is a consumer's start position, the other a one-shot read.

Ack policy decides what the server needs before it considers a delivered message handled. shipping used explicit; the others are none, all, and flow_control, covered in Ack responses and redelivery.

Replay policy decides the pace of delivery. Every consumer in this chapter ran on the default, instant, which Reading back the stream introduced: messages arrive as fast as the reader takes them. The other value, original, spaces deliveries to match the gaps between the original timestamps. A long quiet stretch in the stream is replayed as a long quiet wait.

Priority policy decides which of a consumer's clients gets served. The default, none, applies no steering: pulls are served as they come. overflow, pinned_client, and prioritized each steer differently, and they're covered on Priority groups.

The consumer fields, including the start-position options the deliver policy uses, are in Reference → Consumer Configuration.

What you can change later

Five of the nine policies are fixed at creation. The server enforces this on update, so settle these before you create anything you'll keep:

Stream policyOn a live stream
Retentionlimitsinterest allowed, though the switch re-applies to messages already stored; to or from workqueue refused
DiscardCan change
StorageFixed at creation
CompressionCan change; takes effect after a server or leader restart
Persist modeFixed at creation
Consumer policyOn a live consumer
Deliver policyFixed at creation
Ack policyFixed at creation
Replay policyFixed at creation
Priority policyCan change; nats consumer edit has no flag for it, so pass a config file with --config

Pitfalls

Changing a fixed policy means recreating the object. The server is explicit about it: editing a stream's storage type fails with stream configuration update can not change storage type, and updating a consumer's start position fails with deliver policy can not be updated. Recreating a stream means moving the data too. A mirror can copy the messages across, but a mirror is read-only, and turning it into a publishable replacement takes steps of its own. Recreating a consumer loses the saved position: the new consumer starts wherever its deliver policy says, not where the old one stopped. Do settle the fixed policies before creating anything durable. Don't count on nats stream edit or nats consumer edit to fix them later.

Expecting new to skip the backlog on every restart. A deliver policy applies once, when the consumer is created. A durable created with new starts with the messages that arrive after that moment, and it keeps a saved position like any other durable. When your client restarts and attaches to it, it resumes from that position, backlog included. Do use new to define where a consumer's history begins. Don't use it hoping each reconnect jumps to live traffic.

Two features answer to "last per subject". The deliver policy value gives a consumer a standing latest-per-subject view; the Direct Get flag fetches the same shape once, with no consumer. Do check which feature a flag or value belongs to before copying it. Don't assume the phrase means the same thing in both places.

Where you are

ORDERS and its consumers are unchanged. You now have:

  • the nine policies mapped, most to the page where you used them
  • compression and persist mode placed, the two ORDERS never set
  • the five policies that are fixed at creation, and what the server says when you try to change one

What's next

That's the full policy map. Where to go next recaps the model you built and points to the chapters that take it further.

See also