← Insights

RabbitMQ is not a queue. It is a routing engine with queues attached.

Most production failures come from treating RabbitMQ as a black box, and discovering its failure modes under load.

Exchange types

  • Direct: exact match. order.placed goes to the orders queue.
  • Topic: pattern match. sensor.# goes to all sensor events.
  • Fanout: broadcast to all bound queues.
  • Headers: match on attributes such as format and region.

Three primitives most teams get wrong

Connection layer. One TCP connection per service, with multiple channels per connection. A 60 second heartbeat detects zombie connections. Automatic topology recovery lets consumers resubscribe without intervention.

Load distribution. By default a consumer is flooded with messages while others sit idle. Set basic_qos(prefetch=1) so each consumer processes, acks, then receives the next. Distribution evens out.

Durability. Mirrored queues use synchronous replication and can diverge under load. Quorum queues use Raft consensus and confirm when a majority acks, so they are partition-safe. Use quorum for anything you cannot afford to lose.

Retry without application code

A dead letter exchange routes failed messages to a retry queue with a 60 second TTL, back to the main queue when the TTL expires, and to a parking lot after N failures. The consumer nacks. The broker handles retry, backoff and isolation, with zero application coupling.

  • Publisher confirms. Without them it is fire and forget. With confirms the broker acks on a durable write.
  • Mandatory flag. Returns unroutable messages to the producer. Without it they disappear silently, with no error and no trace.

RabbitMQ rewards architects who understand its primitives. The failure modes are predictable, if you know where to look.

Seen this differently?

Questions, corrections and counterexamples are welcome.

Related

Keep reading