RabbitMQ vs Kafka
A smart broker with deleting queues, or a dumb broker with a retained log? Compare RabbitMQ and Kafka dimension by dimension, see why their performance profiles differ, and use the decision helper to pick one for a real workload.
🎯 What you'll learn
- The one-line difference: queue model vs log model
- Routing, delivery, replay, ordering and scaling compared
- When each one fits better, and false friends ('topic', 'consumer group')
- Why per-message state limits throughput
02-rabbitmq/ and 03-kafka/ covered each broker on its own terms. This topic puts them side by side, because "which broker?" is a design decision that shapes everything downstream: how consumers scale, whether messages can be replayed, and what ordering you get.
1The One-Line Difference
- RabbitMQ is a smart broker with a queue model: the broker routes each message (exchanges + bindings) into queues, tracks per-message delivery and acknowledgement, and deletes a message once it's acked. Consumers are relatively simple.
- Kafka is a distributed append-only log: producers append to partitions, the broker keeps everything for a retention period, and consumers track their own position (offset). The broker is relatively simple; consumers do more.
RabbitMQ: producer → exchange ──binding──► queue ──push──► consumer → ack → message deleted
Kafka: producer → topic/partition (append) ◄──pull at offset N── consumer (commits offset)
messages stay until retention expires2Side by Side
| Dimension | RabbitMQ | Kafka |
|---|---|---|
| Core model | queues; message consumed = gone | partitioned log; messages retained |
| Delivery | broker pushes (with prefetch limit) | consumer pulls batches |
| Routing | rich: direct / topic / fanout / headers exchanges | by topic + partition key only |
| Replay old messages | no (once acked, deleted) | yes — reset the offset |
| Ordering | per queue (breaks with competing consumers + requeue) | per partition |
| Scaling consumers | add consumers to a queue (competing consumers) | up to #partitions consumers per group |
| Multiple independent readers | one queue per reader (fanout copies the message) | many consumer groups read the same log |
| Per-message features | TTL, priority, per-message ack/nack, DLX | none per message; batch-oriented |
| Throughput | tens of thousands/s per queue | millions/s per cluster (sequential I/O, batching) |
| Latency | very low (sub-ms) at moderate load | low ms; tuned for throughput (batching/linger) |
| Typical use | task queues, RPC, complex routing, work distribution | event streaming, event sourcing, CDC, analytics pipelines, logs |
3When RabbitMQ Fits Better
- Work queues / background jobs: each task done once by one worker, per-message ack, retries, DLX (
10-dead_letter_queues/), priorities. - Complex routing: route
order.eu.createdto the EU billing queue and*.*.createdto audit, without producers knowing consumers. - Request/reply (RPC over messaging) with
reply_toand correlation IDs. - Low volume, many short-lived queues (per-user, per-session).
4When Kafka Fits Better
- Event streams many teams consume independently: analytics, search indexing, fraud detection each run their own consumer group at their own pace, on the same events.
- Replay: rebuild a read model, backfill a new service, or reprocess after a bug fix by rewinding offsets.
- Very high throughput with ordering per entity (key =
orderIdkeeps one order's events in order). - Event sourcing / CDC: the log is the source of truth or the change history (log compaction keeps the latest value per key).
- RabbitMQ:
thumbnail.resizeandemail.sendjobs. Each is done once by one worker, with per-message retries, DLX and priorities for password-reset emails. - Kafka:
ordersandclicksstreams. Billing, search indexing, fraud and the data lake each run their own consumer group; a new recommendation service backfilled six months of clicks by starting atearliest.
5Things That Look Similar but Aren't
- "Topic": in RabbitMQ a topic exchange is a routing rule; in Kafka a topic is a durable, partitioned log.
- "Consumer group": RabbitMQ has no such concept — competing consumers simply share a queue. Kafka's groups give each group its own full copy of the stream (
07-consumer_groups_partitions_offsets/). - Ordering: both offer ordering only within a unit (a queue / a partition), and both lose it if you parallelize carelessly (
08-acknowledgements_and_message_ordering/). - Streams: RabbitMQ 3.9+ has Streams (an append-only, replayable log type) and Kafka has share groups in newer versions (queue-like consumption) — the two products are converging at the edges, but their defaults and strengths still differ.
Under the HoodWhy Their Performance Profiles Differ▾
RabbitMQ keeps per-message state: which consumer has it, whether it's acked, redelivery flags. Each ack is a broker-side operation, and a queue is (by default) a single Erlang process, so one queue's throughput is bounded by one core; you scale by having more queues. Messages that aren't consumed quickly are paged from memory to disk, which slows the broker when queues grow long — RabbitMQ is happiest when queues stay short.
Kafka keeps almost no per-message state. A partition is a set of segment files that are only ever appended to; consumer progress is a single integer per partition per group. Producers batch and compress many records into one request; brokers write them with sequential I/O and serve reads from the OS page cache using sendfile (zero-copy from disk cache to socket). Long backlogs are normal and cheap — a lagging consumer is just reading an older offset. The price is coarser semantics: no per-message ack, no per-message routing or priority, and parallelism capped by partition count.
⚠️ Common Pitfalls
- Using Kafka as a job queue — no per-message ack/retry/DLQ; one slow message blocks its whole partition.
- Using RabbitMQ for replayable event history — acked messages are gone; you can't rebuild a read model from it.
- Too few Kafka partitions — consumer parallelism is capped by partition count, and increasing it later reshuffles key → partition mapping.
- Long RabbitMQ queues as a buffer for days of data — memory pressure, paging, flow control.
- Choosing on hype rather than on the consumption model — ask: does each message need to be processed once by one worker (queue), or read by many independent consumers over time (log)?
📋 Quick Reference
| If you need… | Choose |
|---|---|
| task distribution, per-message retry/DLQ, priorities | RabbitMQ |
| flexible routing by pattern | RabbitMQ |
| replay, many independent consumers, event sourcing | Kafka |
| millions of events/s with per-key ordering | Kafka |
| both | it's common to run both, each for what it's good at |
🧠 Key takeaways
- RabbitMQ: smart broker, routing via exchanges, per-message ack, deleted on ack, push with prefetch.
- Kafka: partitioned retained log, consumers pull and track offsets, replay, consumer groups.
- RabbitMQ shines for jobs, routing, RPC; Kafka for streams, many readers, replay, huge throughput.
- Decide by the consumption model, not hype. Many companies run both.
🎤 Interview Q&A
Q1What's the fundamental difference between RabbitMQ and Kafka?core▾
RabbitMQ is a message broker: smart routing, messages are removed once acknowledged, push-based delivery to consumers. Kafka is a distributed log: dumb routing, messages are retained and consumers pull and track offsets, enabling replay and many independent readers.
- Which is 'smart broker, dumb consumer'? RabbitMQ; Kafka is the opposite.
Q2When would you pick each?core▾
RabbitMQ: task/work queues, complex routing, per-message ack/retry, priorities, RPC, moderate throughput. Kafka: high-throughput event streaming, event sourcing, analytics pipelines, multiple consumers reading the same data, replay, stream processing.
- Could you use both? Yes; many companies use Kafka for event streams and RabbitMQ or SQS for job queues.
Q3How do they compare on ordering?core▾
Kafka guarantees order per partition, and a consumer group processes each partition sequentially. RabbitMQ preserves queue order, but competing consumers and requeues can reorder processing. In both, keying and single-consumer processing per key preserve order.
- How do you scale Kafka while keeping order per key? Partition by that key.
Q4How do they handle consumer failures and retries?senior▾
RabbitMQ redelivers unacked messages and supports per-message nack, DLX and TTL-based delay. Kafka has no per-message ack: a failing message blocks its partition unless you skip it to a retry/DLQ topic and commit the offset.
- What's the Kafka retry-topic pattern? Failed records go to retry topics with increasing delays, then a DLQ topic.
Q5How do they scale?core▾
Kafka scales horizontally by partitions across brokers, handling millions of messages per second. RabbitMQ scales with more queues/nodes but a single queue is bound to one node, so throughput per queue is limited; sharding plugins or streams help.
- What limits Kafka consumer parallelism? The number of partitions.
🛠️ Practice exercises
Each exercise is a file in this topic folder. Code exercises are self-checking: run them and make the checks pass.
✅ Check yourself
Answer the questions — feedback is instant.