Core NATS gives connected subscribers live messages
NATS organizes messages by subjects rather than queues declared in a central schema. Publishers send a payload to a subject, subscribers express interest, and queue groups divide work among members. Request-reply uses an inbox subject for responses. This small set of concepts covers service events, work distribution, commands, and fan-out without making every application depend on a large broker-side routing model.
Core NATS is intentionally ephemeral and at-most-once. The official documentation says a message reaches subscribers connected at publication time and disappears for clients that are offline. That property is useful for live signals where stale work has little value. It is dangerous when an application silently assumes broker retention. Reconnect logic belongs to the client, and an in-flight message may be lost around a dropped connection.
JetStream adds persistence through streams and consumers
JetStream stores messages whose subjects match a stream configuration. A consumer tracks delivery position and acknowledgments, allowing replay and at-least-once delivery. Storage may be memory or disk, with retention and replication selected by the operator. The same layer supplies key-value and object-store abstractions. Those features make NATS capable of durable jobs and state distribution, but they introduce storage semantics that Core NATS users can otherwise ignore.
A durable design has to choose subject boundaries, retention limits, acknowledgment policy, redelivery handling, replicas, and recovery procedures. At-least-once means a handler may see a message again, so side effects need idempotency or deduplication. A 3-node cluster does not remove the need for snapshots and restore tests. JetStream is easier to approach than a separate broker product, yet it remains a storage system once data must survive failures.
What happened when we ran it
Our sandbox installed 24 Go packages in 27 seconds and built commit 1787eee successfully in 52 seconds. The repository occupied 14.1 MB before dependencies and contained 605 files with roughly 454,658 source lines. It has 10 CI workflow files and a tests directory. Our scan did not find a Dockerfile, although NATS distributes an official Docker image as well as binaries and packages.
The test step ran for 344 seconds and exited with code 1. Eight package results passed and 2 failed out of 10. Both visible failures concern OCSP peer revocation. The cases expected a remote TLS bad-certificate error, while the client received a connection closed after the TLS handshake with a broken TCP write. The log supports that narrow description; it does not show a general messaging or JetStream failure.
For ordinary publish-subscribe evaluation, the successful 52-second build is encouraging. A deployment that requires mutual TLS with OCSP checking should treat the two failures as release qualification work. Rerun them using the same certificate chain, operating system, network family, and Go toolchain planned for production, then confirm that revoked clients are rejected in the way monitoring and clients expect.
Authentication and topology outgrow the one-command demo
A local server is easy to start, but a shared instance needs accounts or users, credentials, subject permissions, and TLS. Monitoring endpoints should stay on an administrative network. Limits for payloads, connections, subscriptions, and JetStream storage need values derived from the application. Client libraries also need reconnect, timeout, and slow-consumer behavior that matches each service's tolerance for delay and loss.
NATS can form clusters, connect regions through gateways, and attach edge installations as leaf nodes. Release v2.14.5 added a configurable leaf-node dial timeout above the 1-second default for higher-latency links. Those topologies solve real placement problems, but every link adds credentials, routing policy, upgrade order, and failure modes. Start with the fewest servers that meet availability needs, then add topology only for a measured reason.
A JetStream key-value bug matters to single-replica users
Issue #8505 reports that a key purged with a time-limited marker in a single-replica bucket can reappear after an unclean shutdown and file-store index rebuild. The reporter reproduced it on v2.14.5 and describes retaining purge markers as a workaround. This is a specific JetStream key-value path, not evidence that all stored messages revive. It is still serious for anyone using deletion as a correctness or privacy boundary.
The latest v2.14.5 release also fixed potential JetStream data loss during an idempotent stream-create recovery path. That fix and the open purge report show why persistence upgrades deserve workload tests and backups. Teams storing authoritative state in JetStream should test unclean shutdown, snapshot restore, replica loss, expiry, purge, and consumer replay instead of stopping at a healthy cluster status.
August 2026 activity supports adoption with version discipline
GitHub recorded a push on August 26, 2026, 20,598 stars, and 543 combined issues and pull requests. Release v2.14.5 arrived on August 12 and directs users to a 2.14 upgrade guide because version 2.13 was skipped. The release also moved to Go 1.26.5, updated cryptography and compression dependencies, and fixed a logger deadlock.
NATS has more than 40 client language implementations according to its README, CNCF stewardship, and a published April 2025 security audit. Those are useful maturity signals. The choice still turns on semantics: RabbitMQ fits conventional AMQP queues, Kafka fits retained partitioned logs, and NATS fits subject-based service communication with optional persistence. Pick Core NATS or JetStream explicitly, then test the failure behavior that choice promises.

