Engineering Notes
Home/Distributed Systems/Message Brokers/RabbitMQ vs Kafka
Distributed Systems · Message Brokers

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.

🕸️ Distributed Systems● Intermediate⏱ 5 min read▶ 2 interactive🛠️ 1 exercise🎤 5 interview Q&As

🎯 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

📚 Before you start

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.
text
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 expires

2Side by Side

DimensionRabbitMQKafka
Core modelqueues; message consumed = gonepartitioned log; messages retained
Deliverybroker pushes (with prefetch limit)consumer pulls batches
Routingrich: direct / topic / fanout / headers exchangesby topic + partition key only
Replay old messagesno (once acked, deleted)yes — reset the offset
Orderingper queue (breaks with competing consumers + requeue)per partition
Scaling consumersadd consumers to a queue (competing consumers)up to #partitions consumers per group
Multiple independent readersone queue per reader (fanout copies the message)many consumer groups read the same log
Per-message featuresTTL, priority, per-message ack/nack, DLXnone per message; batch-oriented
Throughputtens of thousands/s per queuemillions/s per cluster (sequential I/O, batching)
Latencyvery low (sub-ms) at moderate loadlow ms; tuned for throughput (batching/linger)
Typical usetask queues, RPC, complex routing, work distributionevent 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.created to the EU billing queue and *.*.created to audit, without producers knowing consumers.
  • Request/reply (RPC over messaging) with reply_to and 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 = orderId keeps 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).
💡 Example: PetPal runs both
  • RabbitMQ: thumbnail.resize and email.send jobs. Each is done once by one worker, with per-message retries, DLX and priorities for password-reset emails.
  • Kafka: orders and clicks streams. 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 at earliest.

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.

RabbitMQ routes each message through an exchange into queues and deletes it when acked, while Kafka appends to partitioned logs that retain messages and lets each consumer group track its own offset
RabbitMQ routes each message through an exchange into queues and deletes it when acked, while Kafka appends to partitioned logs that retain messages and lets each consumer group track its own offset

⚠️ Common Pitfalls

  1. Using Kafka as a job queue — no per-message ack/retry/DLQ; one slow message blocks its whole partition.
  2. Using RabbitMQ for replayable event history — acked messages are gone; you can't rebuild a read model from it.
  3. Too few Kafka partitions — consumer parallelism is capped by partition count, and increasing it later reshuffles key → partition mapping.
  4. Long RabbitMQ queues as a buffer for days of data — memory pressure, paging, flow control.
  5. 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, prioritiesRabbitMQ
flexible routing by patternRabbitMQ
replay, many independent consumers, event sourcingKafka
millions of events/s with per-key orderingKafka
bothit'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

Questions interviewers ask about this topic. Answer out loud first, then open a card to compare.

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.

Follow-ups interviewers ask
  • 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.

Follow-ups interviewers ask
  • 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.

Follow-ups interviewers ask
  • 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.

Follow-ups interviewers ask
  • 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.

Follow-ups interviewers ask
  • 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.

1. You need to rebuild a read model from last month's events. Which fits?
Acked RabbitMQ messages are gone.
2. Background jobs with priorities and per-message retries?
Per-message features are RabbitMQ's strength.
3. Why is Kafka's throughput so high?
Progress is one integer per partition.
4. 'Topic' means the same thing in both systems.
A classic false friend.