NATS Core vs JetStream vs KV Store: When to Use Each
One NATS server gives you three very different tools: Core NATS messaging, JetStream streams, and a Key-Value store. They are easy to confuse because they all run on the same subjects and the same binary. But they answer different questions. This guide maps each one to the job it is actually good at.
Core NATS: The Fast Fire-and-Forget Bus
Core NATS is plain pub/sub over subjects, with request/reply built in. Messages live only in memory: they are delivered to currently-connected subscribers and then forgotten. No persistence, no acknowledgements, no replay.
Use Core NATS for:
- Live telemetry: a sensor publishes current state every second; dashboards subscribe and render it. Losing a reading is fine.
- Request/reply: "give me the current value of device 7" / "here it is." This is Core NATS' killer feature and it is built into the protocol.
- Fan-out events: a service publishes "order placed" and ten subscribers react, none of which need to replay it later.
- Service discovery / presence: heartbeat subjects that tell you who is alive right now.
Core NATS is the lowest-latency, lowest-footprint option on the server. It is also the easiest to reason about: if no one is listening, the message does not exist.
JetStream Streams: The Durable Message Store
JetStream adds persistence. A stream captures messages on a subject and stores them on disk; consumers read them with tracked progress, ack-based delivery, and replay from any point. This is the tool for anything that must survive a restart, a disconnect, or a slow consumer.
Use JetStream streams for:
- Event history: every reading, every state change, every command, kept for hours or days.
- Work queues: messages that must be processed exactly once by one of several workers, with redelivery on failure.
- Catch-up / replay: a dashboard that was down for an hour comes back and replays everything it missed.
- Buffering between producers and consumers: producers never block on consumer speed; the stream absorbs the difference.
Streams are the right choice when the sequence of messages matters and you need to replay it.
The KV Store: Latest Value, Not History
NATS KV is built on top of JetStream but presents a completely different interface: GET, PUT, DELETE, plus watches and history per key. It is a distributed key-value store, not a message log. Each key holds one current value (with revision history), and updates overwrite the previous value.
Use KV for:
- Configuration: services watch a config bucket and react to changes instantly, no restart.
- Device state: "last known state of pump 3," "firmware version of gateway 9," "current mode of line A."
- Feature flags / leader election / simple coordination: small pieces of shared state with per-key history.
- Anything where you want the latest value and don't care about the full stream: that is the classic "retained message" use case, done with a real store.
There is also an Object store for larger blobs (files, images, firmware images up to several MB) that JetStream splits into chunks. Same idea as KV, sized for big payloads.
How to Choose
| Question | Answer | Use |
|---|---|---|
| Do subscribers only need it live, right now? | Yes | Core NATS |
| Do you need to replay history or queue work? | Yes | JetStream stream |
| Do you need one current value per key, updated in place? | Yes | KV bucket |
| Do you need to store files / firmware images? | Yes | Object store |
A typical system uses all three on one server: Core NATS for live telemetry and request/reply, a JetStream stream for the audit history of important events, and a KV bucket for device configuration that services watch. They are complementary, not competitors.
Common Mistakes
- Putting everything in JetStream "just in case." You pay disk I/O and ack overhead for data nobody replays. Keep hot live data on Core NATS.
- Using KV for event history. KV overwrites values; it is not a log. If you need the sequence, use a stream.
- Using Core NATS for "must not lose it." If a message disappearing is unacceptable, you need JetStream or KV, full stop.
- Ignoring the Object store and stuffing files into messages. A 4 MB file as a single NATS message hits default max-payload limits. That is what the Object store is for.
The one-line summary: Core NATS = live and fast. JetStream = durable and replayable. KV = current state per key. Pick by whether the data is ephemeral, sequential, or a snapshot.
Seeing All Three in One Tool
Because the three features share subjects and a server, it helps to see them side by side. NATS Explorer includes an embedded server and dedicated browsers for Core NATS pub/sub, JetStream streams and consumers, and KV/Object store buckets, so you can publish to a live subject, mirror it into a stream, and put configuration in a KV bucket from the same window.
Explore NATS Without the CLI
NATS Explorer bundles an embedded NATS server plus browsers for Core NATS, JetStream, KV, and Object stores (on macOS, Windows, and Linux).
Explore NATS Explorer →