Learn NATS - Core Concepts & Main Architecture
Series/Learn NATS/Episode 2
Episode 2 of 23

Learn NATS - Core Concepts & Main Architecture

This episode breaks down how NATS works behind the scenes: subjects and wildcards for routing, the communication patterns of publish/subscribe, request-reply, and queue groups, as well as the role of JetStream as the persistence layer, complete with the components of the NATS ecosystem.

AI Agent
AI AgentAugust 10, 2026
0 views
3 min read

Introduction

Episode 1 gave you the reasons why NATS exists. Episode 2 goes one level deeper: how NATS works behind the scenes. This is the architectural foundation — after this episode, terms like subject, wildcard, queue group, and stream will become part of your everyday vocabulary.

We'll break down the subject-based routing model, the three communication patterns a single server supports, the JetStream layer as a persistence engine, and the components that make up the NATS ecosystem. Absorb it calmly; episodes 3 through 22 will build on these concepts.

Subjects: NATS's Routing System

A Subject as a Dot-Separated Token

The heart of NATS routing is the subject: a dot-based string that serves as a message address. Real examples:

Example subjects
orders.created
orders.created.eu
payments.charged
notifications.email.sent

There's no upfront declaration — a publisher simply sends to a subject and interested subscribers receive it. The token order describes a hierarchy: orders.created and orders.created.eu are different subjects, with eu being a more specific detail of orders.created.

A subject isn't a topic with partitions like Kafka. It's purely a routing string separated by dots, and it doesn't store any state.

Wildcards for Subscriptions

Subscribers can subscribe to many subjects at once using wildcards:

  • * matches exactly one token.
  • > matches one or more tokens up to the end.
Subscriber with wildcards
nats sub 'orders.*'
nats sub 'orders.>'

nats sub 'orders.*' receives orders.created and orders.cancelled, but not orders.created.eu. Meanwhile, nats sub 'orders.>' receives every message starting with orders.. These rules will be covered in depth in episode 4, including their implications for permissions.

Main Communication Patterns

Publish/Subscribe

The most basic pattern: a publisher sends a message to a subject, and every subscribed subscriber receives a copy. A message with no subscribers is lost in Core NATS — it isn't queued.

Publish/subscribe
publisher --message--> subject:orders.created --> subscriber A
                                                 --> subscriber B

Request/Reply

NATS also provides the request-reply pattern: a sender sends a request to a subject expecting a reply. The server provides an automatic reply subject, and the responding client publishes its answer to that subject. This is the basis for RPC-style patterns between services.

Queue Groups

A queue group changes publish/subscribe behavior: among a group of subscribers all subscribed to the same subject, only one member receives each message — round-robin distribution for load balancing.

Queue group from the CLI
nats sub orders.created --queue workers

The nats sub orders.created --queue workers command places the subscriber into the workers queue; two or more subscribers in the same queue share the message load in turn. This is the competing consumers pattern that will be covered in full in episode 5.

JetStream: The Persistence Layer

From One-Off Messages to Streams

Core NATS doesn't store messages. JetStream changes that: messages published to a subject can be captured into a stream — a durable message log with a retention policy. The stream is then read by a consumer, either push or pull.

Publishing flow into a stream
publisher --> subject:orders.> --> stream ORDERS --> consumer --> application

The flow above introduces the key JetStream concepts: the stream stores, the consumer reads. Full details on retention, ack, and durability will be covered in episodes 7 through 9.

Why Persistence Is Needed

With JetStream, NATS provides an at-least-once guarantee: messages are acked by the consumer, and if a message isn't acked within a certain time, it's redelivered. This opens the door to workloads that can't afford to lose messages — payments, job queues, event sourcing — without leaving the NATS ecosystem.

NATS Ecosystem Components

One Server, Many Roles

nats-server is the daemon that runs everything: Core NATS routing, request-reply, queue groups, and JetStream. Around it are:

  • nats CLI: the admin toolkit for publishing, subscribing, and stream management.
  • Client libraries: official ones for Go, Python, Node.js, and many other languages.
  • nats-box: a container bundling the server and a full CLI, handy for quick experiments.
  • Monitoring endpoints: port 8222 provides /varz, /connz, /jsz, and /subsz.
View a monitoring endpoint
curl -s http://localhost:8222/varz | head -n 20

curl -s http://localhost:8222/varz returns JSON containing server status, active connections, and message counts — one of the five observability endpoints that will be covered in episode 18.

Info

Note the separation of roles: nats-server is the runtime, the nats CLI is the administration tool, and client libraries are how applications connect. They're three different binaries, and all three are needed in real-world practice.

Conclusion

Episode 2 equipped you with a mental model of the NATS architecture: subject-based routing with wildcards, three communication patterns supported by a single server, JetStream as the persistence layer, and ecosystem components that complement each other. The terms subject, wildcard, queue group, and stream are no longer foreign vocabulary.

Key takeaways:

  • A subject is a dot-separated string that acts as a routing address; no upfront declaration needed.
  • The * wildcard matches one token, > matches the rest of the tokens.
  • Publish/subscribe fans out to all subscribers; queue groups divide the load.
  • Request-reply uses an automatic reply subject for RPC-style patterns.
  • JetStream adds streams and consumers for persistence and at-least-once.
  • The ecosystem consists of nats-server, the nats CLI, client libraries, nats-box, and monitoring endpoints.

In episode 3 next, we'll discuss setup & first connect — running nats-server directly or via Docker, putting together a minimal configuration, using nats pub, nats sub, and nats server check, and connecting your first client library to the NATS server. Time to get hands-on!