RabbitMQ is a smart broker / dumb consumer AMQP message broker. Producers publish to an exchange; the exchange routes copies to queues by binding rules; consumers pull from queues and ack. Where Kafka is a dumb log with smart consumers, RabbitMQ puts the routing intelligence in the broker. Senior interviews probe exchange types, ack/prefetch, durability, and the quorum-queue HA story.
1. AMQP model
| Concept | What |
|---|---|
| Producer | Publishes a message to an exchange (never directly to a queue). |
| Exchange | Receives messages and routes them to queues by type + bindings. |
| Queue | Buffers messages until a consumer acks them. The unit of consumption. |
| Binding | A rule linking an exchange to a queue (with a routing/binding key or header match). |
| Routing key | A string the producer sets; exchanges use it to decide routing. |
| Connection / Channel | One TCP connection; multiplex many lightweight channels over it (one per thread). |
| Vhost | Virtual host — namespace/isolation for exchanges, queues, permissions. |
2. Exchange types
| Type | Routing |
|---|---|
| direct | Routing key must equal the binding key. Point-to-point / by category. |
| topic | Pattern match on dotted keys: * = one word, # = zero+ words. logs.*.error. |
| fanout | Broadcast to all bound queues, ignore key. Pub/sub. |
| headers | Match on message headers instead of routing key (x-match any/all). |
default ("") | Implicit direct exchange; routing key = queue name. (How "publish to a queue" works.) |
A message published to an exchange with no matching binding is dropped (or returned with the
mandatory flag / routed to an alternate exchange).
3. Acknowledgements & prefetch
- Manual ack (recommended): consumer
basic.acks after processing → at-least-once. Crash before ack = redelivery.basic.nack/rejectwithrequeueor to a DLX. - Auto-ack: message considered delivered the instant it's sent → at-most-once (lose on crash). Fast, unsafe.
- Prefetch (
basic.qos(prefetch_count)): max unacked messages a consumer holds at once. The single most important throughput/fairness knob. - Publisher confirms: broker acks the producer once a message is safely handled (persisted/routed) — the producer-side reliability mechanism (analogous to Kafka acks).
prefetch is the throughput knob
Unlimited prefetch dumps the whole queue into one greedy consumer (no fair spread, huge memory).
Prefetch 1 starves throughput on round-trips. Tune to a batch (e.g. 10–100) sized to processing
time for balanced, fair dispatch.
4. Durability & persistence
Three independent things must all hold for a message to survive a broker restart:
- Durable queue (survives restart).
- Persistent message (
delivery_mode=2— written to disk). - Publisher confirms so the producer knows it was accepted.
durable queue ≠ persistent message
A durable queue with non-persistent messages still loses the messages on restart. You need
durable queue and persistent messages and confirms. Persistence costs latency
(fsync) — it's a deliberate durability/throughput trade.
5. Queue types
| Type | Use |
|---|---|
| Classic | Default single-node queue. Mirroring (HA classic) is deprecated. |
| Quorum | Raft-replicated, HA, data-safety-first. The modern default for important queues. Replicated across nodes; survives node loss. |
| Stream | Append-only, replayable log (Kafka-like) for high-throughput fan-out + replay. |
6. DLX, TTL & limits
- Dead Letter Exchange (DLX): messages that are rejected/nacked (no requeue), expire (TTL), or overflow a max-length queue get republished to a DLX → a dead-letter queue.
- TTL: per-message or per-queue expiry. Combined with a DLX → delayed/retry queues (let a message TTL out of a "wait" queue back to the work queue).
- Max length / max bytes: cap a queue; overflow goes to DLX or drops the head.
- Priority queues:
x-max-priorityfor higher-priority messages first.
dead-letter loops
If a DLQ dead-letters back to the source (or a TTL bounces a message in a cycle), messages loop
forever. Make the DLQ terminal; cap retries by counting the
x-death header and
parking after N attempts.7. Flow control & alarms
- When memory crosses
vm_memory_high_watermark(default ~40% RAM) or disk drops belowdisk_free_limit, RabbitMQ raises an alarm and blocks publishers until it recovers. - "RabbitMQ hung / publishers frozen with no error" is almost always an alarm — check
rabbitmqctl statusfirst. - Lazy queues / quorum queues page to disk to bound memory under deep backlogs.
8. Clustering & HA
- Nodes form a cluster (shared metadata via Mnesia/Khepri). Queues live on specific nodes unless replicated.
- Quorum queues replicate via Raft across nodes — the modern HA mechanism (classic mirrored queues are deprecated).
- Clients connect through a load balancer; on K8s use the peer-discovery plugin + a headless service + StatefulSet + PVCs.
- Federation / Shovel link brokers across DCs/regions.
9. CLI & ops
rabbitmqctl list_queues name messages messages_ready messages_unacknowledged consumers
rabbitmqctl list_consumers ; rabbitmqctl list_channels name prefetch_count messages_unacknowledged
rabbitmqctl list_connections name state # 'blocked' = hit an alarm
rabbitmqctl status # alarms, memory breakdown, disk
rabbitmq-diagnostics observer / memory_breakdown
rabbitmqctl list_exchanges ; list_bindings
rabbitmqctl set_policy ha "^" '{"queue-mode":"lazy"}' --apply-to queues
rabbitmqctl purge_queue NAME
10. RabbitMQ vs Kafka
| RabbitMQ | Kafka | |
|---|---|---|
| Model | Smart broker, exchanges→queues, push | Dumb log, partitions, pull |
| Routing | Rich (direct/topic/fanout/headers) | By partition/key only |
| Consumption | Per-message ack, requeue, priority, competing consumers | Offset-based, replay, ordered per partition |
| Retention | Until acked (streams = replayable) | Long, replayable by design |
| Best for | Task queues, RPC, complex routing | High-throughput event streaming, replay |
11. Senior interview Q&A
- Exchange types?direct (key equals binding), topic (pattern with */#), fanout (broadcast), headers (match headers). Default exchange routes by queue name.
- How do you guarantee a message survives a restart?Durable queue + persistent message (delivery_mode=2) + publisher confirms — all three. A durable queue alone doesn't persist messages.
- What does prefetch do?Caps unacked messages per consumer (basic.qos). Tune it for fair dispatch + throughput; unlimited = one greedy consumer, 1 = round-trip starvation.
- Manual vs auto ack?Manual = ack after processing (at-least-once, redelivery on crash). Auto = delivered on send (at-most-once, loss on crash). Use manual + idempotent handlers.
- What's a DLX and a use?Dead Letter Exchange — rejected/expired/overflow messages route there. Combined with TTL it builds retry/delay queues. Keep DLQs terminal to avoid loops.
- Classic vs quorum vs stream queues?Classic = single-node default (mirroring deprecated). Quorum = Raft-replicated HA (modern default). Stream = replayable append-only log.
- Why are publishers suddenly blocked?A memory/disk alarm (flow control) — vm_memory_high_watermark or disk_free_limit crossed. Drain queues / free disk; check rabbitmqctl status.
- Connection vs channel?One TCP connection multiplexes many channels (one per thread). Reuse connections — opening one per message exhausts FDs and CPU.
- How do you do HA now?Quorum queues (Raft replication). Classic mirrored queues are deprecated. On K8s: peer-discovery + headless service + StatefulSet + PVCs.
- How do competing consumers work?Multiple consumers on one queue — the broker round-robins (prefetch-bounded) messages among them. Add consumers to scale a queue.
- Publisher confirms vs transactions?Confirms = async broker ack per message (fast, recommended). AMQP transactions are synchronous and much slower — avoid.
- RabbitMQ vs Kafka — when which?RabbitMQ for task queues, complex routing, per-message ack/priority/RPC. Kafka for durable, replayable, high-throughput streaming with ordered partitions.