The “what message broker should we use?” question has the same answer ratio as “what database?”: “depends on what you’re building, here are the three you should know.” This post is the practical decision guide for 2026.
TL;DR by use case
| Use case | First choice | Why |
|---|---|---|
| Event streaming, log of facts, replay-able history | Kafka | Durable log model fits |
| Microservices RPC / pub-sub, low latency | NATS | Sub-ms; tiny ops cost |
| Task queues, complex routing, classic work distribution | RabbitMQ | AMQP routing, mature |
| IoT / edge fan-in | NATS | Lightweight, edge-aware |
| Analytics pipeline | Kafka | Connect ecosystem, replay |
| Background jobs (Celery-style) | RabbitMQ | Simple semantics, retries |
| AI agent event bus | NATS JetStream | Streams + small footprint |
You can build almost anything with any of them. The question is which gives you the path of least resistance.
The core mental model
The differences are mostly about data model:
- Kafka — distributed append-only log, partitioned, replicated. Consumers track their own position.
- NATS — pub/sub messaging system. JetStream adds streams + persistence. Subjects are wildcard-routed.
- RabbitMQ — AMQP broker. Producers send to exchanges, exchanges route to queues, consumers drain queues.
Different shapes, different strengths.
Throughput and latency
Cherry-picked numbers from many benchmarks; treat as orders of magnitude.
| Sustained throughput | p99 latency | Persistent | |
|---|---|---|---|
| Kafka | 1M+ msg/sec/cluster | 5–20 ms | Always |
| NATS Core | 5M+ msg/sec | <1 ms | No |
| NATS JetStream | 500k–1M msg/sec | 1–5 ms | Yes |
| RabbitMQ | 100k–500k msg/sec | 1–5 ms | Configurable |
For most application workloads, all three are fast enough. Pick on semantics, not throughput.
Kafka — when it’s right
What Kafka is good at
- Append-only log. Every message is a fact, ordered within a partition, retained for a configurable time.
- Replayable. Consumers track offsets; you can rewind to reprocess.
- Many independent consumers. One topic feeds analytics, search indexing, audit, billing, all at once.
- Stream processing. Kafka Streams, Flink, ksqlDB all integrate natively.
What Kafka is bad at
- Per-message acks. Kafka tracks consumer position, not per-message status. “I processed message X but not Y” doesn’t fit.
- Complex routing. No fanout-with-filter. Use multiple topics or Kafka Streams.
- Operational simplicity. Even with KRaft (no ZooKeeper), running Kafka in production is real work.
When to pick Kafka
- You need a system of record for events.
- Your data flow looks like a fan-out from sources to many consumers.
- You’ll do stream processing at some point.
- You can afford the operational overhead (or you’re using a managed service: Confluent, AWS MSK, Redpanda).
Modern alternatives in the Kafka shape
- Redpanda — Kafka API, single C++ binary, lower latency, easier ops. A genuine drop-in for many use cases.
- WarpStream — S3-backed Kafka API. Lower throughput but cheaper at rest.
If you want Kafka semantics without ZooKeeper drama, Redpanda is what I reach for in 2026.
NATS — when it’s right
What NATS is good at
- Sub-millisecond latency. Tiny binary, efficient protocol.
- Subject-based routing with wildcards (
orders.*,orders.>,orders.us.>). - Tiny operational footprint. Single binary, embeds in your app if you want.
- Edge-aware. Leaf nodes, geo-distributed clusters, bridges.
- Request-reply built-in (rare in messaging systems).
NATS Core vs JetStream
- Core NATS — fire-and-forget, at-most-once. Fast, simple, ephemeral.
- JetStream — persistent streams, at-least-once. The Kafka-shaped layer on top of NATS.
Most production deploys use both: Core for hot RPC-shaped traffic, JetStream where durability matters.
When to pick NATS
- Microservices need a fast pub/sub or request-reply substrate.
- Low latency is the priority (sub-ms matters).
- You want simple ops — one binary, embed-able, geo-distributable.
- AI agent buses that need typed publish/subscribe with durability fit JetStream very well.
What NATS is not for
- Massive long-retention event lakes. JetStream can do it, but Kafka’s tooling around storage tiering and ecosystem is broader.
- Complex AMQP-style routing (header-based, exchange-to-exchange). NATS subject hierarchies are powerful but different.
RabbitMQ — when it’s right
What RabbitMQ is good at
- Mature. Decades of production runtime; postmortems exist for every weird failure mode.
- AMQP routing — direct, topic, fanout, headers exchanges.
- Per-message ack/nack. Each message has a delivery tag; failure handling is granular.
- Plugins: STOMP, MQTT, federation, shovel.
- Streams (since 3.9) — Kafka-like log mode.
What RabbitMQ is bad at
- Sustained throughput lags Kafka and NATS.
- Long retention — designed as transient queues; storage is bounded by RAM by default.
- Replay across many consumers — possible but not its strength.
When to pick RabbitMQ
- Task queues / work distribution — Celery, BullMQ-style backends.
- Complex routing rules that need exchange-level logic.
- Your team already knows AMQP — the cost of using something else outweighs the benefit.
- You need per-message ack semantics for delivery guarantees.
A decision tree
- Are you building an event lake / system-of-record / stream processing pipeline? → Kafka (or Redpanda).
- Is your latency budget sub-millisecond, or do you need request-reply? → NATS.
- Do you need AMQP-style routing and per-message acks? → RabbitMQ.
- Are you in AWS and just need a job queue? → SQS (operationally simpler than any of the above).
- Are you on Kubernetes building event-driven microservices? → NATS JetStream is my default.
Specific scenarios I’ve seen
“Background tasks for a Django app”
→ RabbitMQ + Celery if you’re already on that stack. Redis Streams if you want to keep one fewer dependency. NATS if you have other NATS users in your org.
“Order events to billing, search, and analytics”
→ Kafka. The fan-out + retention model fits exactly.
“Real-time chat / pub/sub / ephemeral notifications”
→ NATS. Or Redis Pub/Sub for the very simple case.
“AI agent communication on a multi-agent platform”
→ NATS JetStream. Subject hierarchies map well to agents/topics; durability ensures replay; latency is friendly to agent loops.
“Event sourcing with strict ordering”
→ Kafka with key-partitioned topics. Order-within-partition is the strongest ordering guarantee that scales.
Operational realities
Kafka
- Multiple machines required for proper replication.
- JVM tuning matters (less so with KRaft).
- Broker rebalances on cluster scaling can be impactful.
- Tooling: Kafka Connect, Schema Registry, Streams, ksqlDB — rich.
Managed: Confluent Cloud, AWS MSK, Aiven. Use a managed service unless you have a strong reason not to.
NATS
- Single binary, written in Go.
- Cluster setup is genuinely simple.
- JetStream storage lives on disk; backed up trivially.
- Tooling: lighter than Kafka, sufficient for most.
Managed: Synadia Cloud. Self-host is feasible — many teams do.
RabbitMQ
- Erlang-based, mature.
- Clustering has historical complexity; modern Quorum Queues simplify it.
- Persistence and HA require thought (acks, mirroring, quorum queues).
- Tooling: management plugin, plenty of language clients.
Managed: CloudAMQP, AWS MQ.
What I’d build today
For a brand-new product backend in 2026:
- NATS JetStream for inter-service async communication.
- Postgres LISTEN/NOTIFY for trivial pub-sub (when one DB row update fires a notification).
- Redpanda if I expect a high-throughput event log future.
- SQS if I’m on AWS and the workload is simple job queues.
I’d avoid RabbitMQ for greenfield in 2026 unless the team already knows it. NATS+JetStream covers RabbitMQ’s space with simpler ops.
Read this next
- Distributed Systems Fundamentals — the model behind why brokers matter.
- Idempotency, Retries, and Exactly-Once Illusions — the patterns every broker user needs.
- Celery Background Tasks Explained — Python task queue specifics.
If you want a small NATS JetStream + Postgres outbox example you can clone, it’s at rajpoot.dev .
Building something AI-, backend-, or data-heavy and want a second pair of eyes? I do consulting and freelance work — see my projects and ways to reach me at rajpoot.dev .