Reference · gazar.dev ← From Senior to Staff

Distributed systems · messaging

Kafka vs RabbitMQ cheat sheet.

The two names every backend interview reaches for. They look similar (both move messages between services) but they are fundamentally different tools: Kafka is a durable log you read from, RabbitMQ is a broker that routes and deletes. Get that one distinction and most questions answer themselves. Companion to S6 · Distributed Patterns and S7 · Architectural Styles.

01

Two mental models

Fix these two pictures and the rest is detail. Almost every interview answer is a consequence of "log vs broker."

K

Kafka: a durable, replayable log

Messages are appended to a partition and kept for a retention period. Each consumer group remembers its offset (its bookmark). Reading does not delete. Many independent readers, replay from any point, huge throughput. Think event stream.

R

RabbitMQ: a smart post office

A producer sends to an exchange, which routes to one or more queues by rules. A consumer takes a message, acks it, and it is removed. Rich routing, per-message delivery, low latency. Think work queue and task dispatch.

The trap that fails the question

Treating them as interchangeable "message queues." If you say "I'd use Kafka" for a job-dispatch problem that needs per-message retries and dead-lettering, or "I'd use RabbitMQ" to fan a firehose of events out to five analytics consumers that each replay history, the interviewer learns you do not understand the models. Name the model first, then the tool.

02

Side by side

The comparison interviewers are really probing. Read every row as a consequence of log-vs-broker.

DimensionKafkaRabbitMQ
Modeldistributed append-only logmessage broker with routing
Consumptionpull; consumer tracks offsetpush; broker delivers, consumer acks
After readmessage stays until retention expiresmessage deleted once acked
Replay historyyes, reset the offsetno, once gone it is gone
Orderingguaranteed within a partitionper queue, weakens with redelivery / multiple consumers
Routingsimple: topic + partition by keyrich: direct, topic, fanout, headers
Throughputvery high (millions/s), sequential diskhigh (tens of thousands/s), lower ceiling
Multiple consumers of same datanative: many consumer groupsneeds a fanout exchange + a queue each
Per-message TTL / priority / DLQlimited / manualfirst-class
Scaling unitpartitions (add to parallelise)queues + consumers (competing consumers)
Best atevent streaming, log of facts, analytics, replaytask queues, RPC, complex routing, per-message control
03

Kafka concepts, the ones they ask about

If you can explain partition, consumer group, and offset clearly, you are most of the way there. The rest are follow-ups.

Core objectstopic · partition · offset
topic
a named stream of messages, e.g. orders. Split into partitions.
partition
one ordered, append-only log. The unit of parallelism and ordering. More partitions = more throughput.
offset
a message's position in a partition. Consumers commit the offset they have processed: their bookmark.
key
decides the partition (same key = same partition = ordered together). No key = round-robin.
Consumers & clustergroups · brokers · replicas
consumer group
consumers sharing a group id split the partitions between them. A different group reads the same data independently.
broker
one Kafka server. A cluster is many brokers; partitions are spread across them.
replication
each partition has a leader + follower replicas. ISR = in-sync replicas. Survives broker loss.
retention
keep messages for a time or size window. Log compaction instead keeps the latest value per key forever.

The one-liner they want

"A topic is split into partitions; ordering is guaranteed only within a partition, set by the message key. Consumers in a group share the partitions for scale; a separate group re-reads the same stream independently. Each consumer commits an offset, so it can resume or replay." That single sentence answers half the Kafka questions.

04

RabbitMQ concepts, the ones they ask about

The heart of RabbitMQ is routing: producers never talk to queues directly, they publish to an exchange that decides where it goes.

Routingexchange · binding · key
exchange
the router. Producers publish here, never to a queue directly.
queue
where messages wait for a consumer. Bound to an exchange.
binding
a rule linking an exchange to a queue, often with a routing key pattern.
routing key
a label on the message the exchange matches against bindings.
Exchange types & controldirect · topic · fanout · ack
direct
route on an exact routing-key match.
topic
route on a pattern, e.g. order.*.eu. The flexible workhorse.
fanout
copy to every bound queue (pub/sub broadcast).
ack / nack
consumer confirms done (deletes) or rejects (requeue or dead-letter).
prefetch
how many unacked messages one consumer may hold: the fairness / backpressure knob.
DLX + TTL
dead-letter exchange catches failed / expired messages; TTL expires them. First-class retry tooling.

The one-liner they want

"Producers publish to an exchange with a routing key; bindings decide which queues get it. direct matches exactly, topic matches patterns, fanout broadcasts. Consumers ack to delete, nack to requeue or dead-letter, and prefetch bounds how much one consumer holds for fairness and backpressure."

05

Delivery semantics & ordering

Straight from S6: both are at-least-once by default, so design for duplicates. "Exactly-once" is at-least-once delivery plus an idempotent consumer. Ordering is the other half interviewers probe.

GuaranteeKafkaRabbitMQ
At-least-oncedefault; commit offset after processingdefault; ack after processing
At-most-oncecommit offset before processingauto-ack on delivery
Effectively exactly-onceidempotent producer + transactions, or idempotent consumeridempotent consumer (dedupe on a key)
Orderingstrict within a partitionper queue, but lost once messages requeue or fan to many consumers
Ordering priceorder needs same key, which can create a hot partitionstrict order needs a single consumer, which caps throughput

The exactly-once reframe (the senior answer)

Do not promise exactly-once on the wire, it does not exist. Take at-least-once + an idempotent consumer: carry an idempotency key, check "seen this key?" before acting. Kafka adds idempotent producers and transactions for its own end-to-end path, but a dedupe-on-key consumer is the portable answer that works for both. This is the same move as the outbox and idempotency from S6.

06

Which do I pick?

Answer by the workload, not by taste. Start from "is this a stream of facts to read many ways, or tasks to dispatch once?"

flowchart LR
  Q{"stream of EVENTS or queue of TASKS?"}
  Q -->|"log of facts, many consumers read or replay"| K1["KAFKA
analytics, event sourcing, audit, CDC, metrics, tell everyone"] Q -->|"high throughput, ordered per key, long retention"| K2["KAFKA"] Q -->|"dispatch work once, then forget"| R1["RABBITMQ
background jobs, emails, image resize, RPC, request-reply"] Q -->|"rich routing: topic, fanout, headers"| R2["RABBITMQ"] Q -->|"per-message retries, priority, TTL, dead-letter"| R3["RABBITMQ"] Q -->|"both shapes in one system"| B["USE BOTH
Kafka for the event backbone, Rabbit for task dispatch"] classDef accent fill:#DCEBFE,stroke:#4A90D9,color:#09244B classDef bad fill:#FEE4E2,stroke:#C8102E,color:#09244B classDef good fill:#D6F5E3,stroke:#1B7F46,color:#09244B class K1,K2 accent class R1,R2,R3 bad class B good
07

Common patterns

The shapes that come up, and which tool fits each naturally.

Competing consumers (work queue)

N workers share a load, each message handled once. RabbitMQ one queue, many consumers, prefetch for fairness. Kafka one consumer group, partitions split across workers (parallelism capped by partition count).

Pub/sub (fan-out)

One event, many independent reactors. Kafka a consumer group per subscriber, all read the same log. RabbitMQ a fanout exchange to one queue per subscriber.

Event streaming / sourcing

The log of events is the source of truth; rebuild state by replay. Kafka is the natural home; retention + replay + compaction are built for it. RabbitMQ cannot replay.

Request / reply (RPC)

Send a task, get a result back on a reply queue with a correlation id. RabbitMQ is built for this. Doable in Kafka but awkward.

The hybrid that real systems use

It is rarely either/or. A common shape: Kafka as the event backbone (every domain event from S8 lands here, many consumers, replayable), and RabbitMQ or SQS for task dispatch (send this one email, resize this one image, with retries and a dead-letter queue). Saying "I'd use both, here's the split" is a strong senior answer.

08

Interview questions, with crisp answers

The ones that actually come up, and the one or two sentences that land them.

Q · Kafka vs RabbitMQ in one line?

Kafka is a durable log you read by offset and can replay; RabbitMQ is a broker that routes and deletes on ack. Streams of facts to Kafka, tasks to dispatch to RabbitMQ.

Q · How does Kafka scale and keep order?

A topic splits into partitions; consumers in a group share them. Order holds only within a partition, set by the message key. More partitions, more parallelism, but order is per key, not global.

Q · How do many services read the same Kafka events?

Each gives itself a different consumer group. Reads do not consume the data, so every group reads the full stream independently and at its own pace.

Q · How does RabbitMQ decide where a message goes?

Producers publish to an exchange with a routing key; bindings route to queues. direct exact-match, topic pattern, fanout broadcast.

Q · Do they guarantee exactly-once?

No. Both are at-least-once, so plan for duplicates. Get effectively-once with an idempotent consumer that dedupes on a key. Kafka also offers idempotent producers + transactions for its own path.

Q · A message keeps failing. What happens?

RabbitMQ nack it to a dead-letter exchange after N tries. Kafka has no per-message DLQ; you write failures to a separate "dead-letter topic" yourself and keep the offset moving.

Q · How do you handle backpressure?

RabbitMQ set prefetch so a consumer holds only N unacked messages. Kafka the consumer pulls at its own pace, lag (offset behind the log end) is the signal to add consumers or partitions.

Q · When would you use both?

Kafka as the event backbone (replayable domain events, many consumers), RabbitMQ or SQS for task dispatch (one-off jobs with retries and DLQ). Different shapes, different tools.

09

Traps & the repeatable move

The mistakes that cost the point, and the habit that catches all of them.

The traps

  • "They're both message queues." The log-vs-broker difference is the whole interview.
  • Expecting global ordering in Kafka. Order is per partition only; one partition means no parallelism.
  • One giant partition key. A hot key (e.g. one big tenant) overloads a single partition.
  • No idempotent consumer. At-least-once + a non-idempotent handler = double charges.
  • Reaching for Kafka to get a DLQ / retries. That is RabbitMQ's home turf.
  • Using RabbitMQ as long-term storage. It is a queue, not a database; messages leave on ack.

The repeatable answer

1. name the shape: stream of facts, or tasks to dispatch?
2. pick the tool: log (Kafka) vs broker (RabbitMQ).
3. state the guarantee: at-least-once, so idempotent consumer.
4. name the ordering / routing need and its cost.

Say the shape before the tool. "This is a replayable stream read by several consumers, so Kafka, partitioned by tenant_id, at-least-once with a dedupe key" is a staff answer. "I'd use Kafka" is a coin flip.

Companion to S6 · Distributed Patterns and S7 · Architectural Styles. Further reading: Kafka docs · RabbitMQ tutorials · Kafka exactly-once / transactions · RabbitMQ dead-letter exchanges.