A common community question is whether JetStream atomic batch publish guarantees only atomicity, or whether it also guarantees ordering and prevents other messages from appearing in the middle of the batch.
Short answer: for a successfully committed atomic publish batch, JetStream preserves the order of messages inside the batch and appends the batch to the stream as a contiguous sequence. Other messages are not interleaved between messages in that committed batch.
For a committed atomic batch:
For example, suppose a publisher builds a batch containing three messages:
1batch: A1, A2, A3While that batch is being built, other publishers may write messages such as:
1B1, B2, B3, ... B14When the atomic batch is committed successfully, JetStream does not place the result into the stream like this:
1A1, B1, B2, A2, B3, A3Instead, the batch is appended as a contiguous sequence:
1..., A1, A2, A3The exact position of the batch relative to other concurrent commits is determined by the server’s commit ordering, but those concurrent writes do not split the batch itself.
Atomic batch publish is a relatively recent JetStream capability, so a few prerequisites are worth confirming before you rely on it:
Because the feature is newer, treat the official documentation and release notes for your specific NATS Server and client versions as the source of truth.
This ordering behavior is part of the design of atomic batched publishes, not an accidental side effect. The design is described in the NATS architecture and design repository, in the Atomic Batched Publishes section of ADR-50.
Preserving in-batch order and contiguous placement is fundamental to the feature, so changing that behavior would be treated as a regression, and the behavior is exercised by NATS Server tests. Even so, when adopting a newer feature it is good practice to confirm behavior against the documentation and release notes for the versions you actually run.
There is no universal performance answer for atomic batch publish. The practical guidance is to benchmark with your own workload and stream configuration.
In general terms:
If performance matters, test the actual shape of your workload rather than assuming atomic batch publish will be faster or slower. Measure at least:
Atomic batch publish can be useful when you split one logical payload into multiple JetStream messages and want those chunks committed together, in order, without unrelated messages appearing between them in the stream.
It also changes the publish and acknowledgement pattern in a way that matters for chunking: success is confirmed once, when the batch is committed, rather than requiring a separately confirmed round trip for every chunk before the next one is sent. Whether that helps or hurts throughput for your payload and chunk sizes is exactly the kind of thing to benchmark.
That said, chunking should still be designed defensively. Consider including metadata such as:
Do not rely only on adjacency if your consumers use subject filters, process subsets of subjects, or have application-level retry behavior. The atomic batch gives you stream placement guarantees, but your application should still be able to identify and validate the chunks that belong together.
Use JetStream atomic batch publish when a group of messages must be committed as an ordered, contiguous unit. This is especially helpful for multi-message logical records, chunked payloads, or workflows where interleaving would complicate downstream processing.
Confirm the prerequisites first: a supported NATS Server and client, and a stream configured to allow atomic batch publishing. Treat performance as workload-specific — the ordering guarantees are strong, but the best publish strategy depends on your stream replication settings, message sizes, batch sizes, and concurrency model.
Want help from the NATS experts? Meet with our architects to get help tailored to your use case and environment.



News and content from across the community