NATS Messaging in Python — Core Concepts

NATS is a lightweight messaging system designed for cloud-native applications. It handles millions of messages per second with single-digit millisecond latency while using minimal resources. For Python developers building microservices, NATS offers a simpler alternative to Kafka or RabbitMQ when you need real-time communication between services.

Subject-based messaging

Every message in NATS goes to a subject — a string like orders.created or sensors.floor3.temperature. Subjects use dot-separated tokens that enable hierarchical organization.

Two wildcard types let subscribers match broadly:

  • * matches a single token: sensors.*.temperature matches sensors.floor3.temperature but not sensors.floor3.wing2.temperature.
  • > matches one or more tokens at the tail: sensors.> matches everything under sensors.

This design makes adding new event types trivial. Publishers emit events to specific subjects; subscribers choose their granularity.

Core messaging patterns

Publish-Subscribe

The default pattern. One publisher, many subscribers. Every subscriber gets every message. Good for broadcasting events like configuration changes or price ticks.

Queue Groups

Subscribers that share a queue group name receive messages in a load-balanced fashion — only one member of the group gets each message. This is how you scale workers without changing the publisher.

await nc.subscribe("tasks.process", queue="workers", cb=handle)

Three instances of this code will each get roughly one-third of the messages.

Request-Reply

A synchronous-style interaction over an asynchronous transport. The requester publishes a message with a unique reply subject. The responder sends its answer to that subject.

response = await nc.request("api.users.lookup", b'{"id": 42}', timeout=2.0)

Under the hood, NATS creates an ephemeral inbox subscription. This pattern replaces HTTP calls between internal services with lower overhead.

JetStream for persistence

Core NATS is fire-and-forget. JetStream adds persistence, replay, and exactly-once semantics.

Key concepts:

  • Streams capture messages matching certain subjects and store them on disk.
  • Consumers read from streams with configurable delivery policies: deliver all, deliver from a sequence number, or deliver only new messages.
  • Acknowledgements let consumers confirm processing. Unacknowledged messages get redelivered.

JetStream turns NATS into a durable event store suitable for order processing, audit logs, and any workflow where losing a message is not acceptable.

Using nats-py

The official Python client is async-first:

import nats

async def main():
    nc = await nats.connect("nats://localhost:4222")
    
    # Subscribe
    sub = await nc.subscribe("events.>")
    
    # Publish
    await nc.publish("events.user.signup", b'{"user": "alice"}')
    
    msg = await sub.next_msg(timeout=5.0)
    print(msg.data)
    
    await nc.drain()

drain() is important — it flushes pending messages and unsubscribes cleanly before disconnecting.

Common misconception

“NATS is only for fire-and-forget, so I cannot use it for important messages.” With JetStream enabled, NATS supports persistent streams, consumer acknowledgements, and exactly-once delivery. It covers both ephemeral and durable messaging in one system.

When to choose NATS

NATS fits well when you want operational simplicity. The server is a single binary with minimal configuration. Clustering is built in. Compared to Kafka, you trade the deep ecosystem of stream processing (ksqlDB, Kafka Streams) for faster setup and lower operational overhead. Compared to RabbitMQ, you get better throughput and simpler clustering at the cost of fewer routing primitives.

One thing to remember: NATS combines the simplicity of pub/sub with optional JetStream persistence, giving Python services a single messaging layer that scales from fire-and-forget events to durable workflows.

pythonnatsmicroservices

See Also

  • Python Adaptive Learning Systems How Python builds learning apps that adjust to each student like a personal tutor who knows exactly what you need next.
  • Python Airflow Learn Airflow as a timetable manager that makes sure data tasks run in the right order every day.
  • Python Altair Learn Altair through the idea of drawing charts by describing rules, not by hand-placing every visual element.
  • Python Automated Grading How Python grades homework and exams automatically, from simple answer keys to understanding written essays.
  • Python Batch Vs Stream Processing Batch processing is like doing laundry once a week; stream processing is like a self-cleaning shirt that cleans itself constantly.