Backend6 min read
RabbitMQ Patterns for Reliable Background Processing
RabbitMQ's flexibility means there are several ways to build a queue, and only some of them survive a worker crashing mid-message.
Tanjil Ahmed
Lead Software Engineer · Notionhive
RabbitMQ gives you enough low-level control to build a queue several different ways, and the difference between those ways shows up exactly once — the first time a worker crashes mid-message, and either the message is safely redelivered or it's gone forever.
- Manual acknowledgment, not auto-ack — a worker crash before ack means RabbitMQ redelivers the message instead of silently dropping it.
- Dead-letter exchanges for messages that fail repeatedly, so a poison message doesn't loop forever or block the queue.
- Idempotent consumers, always — 'at least once' delivery is the realistic guarantee, and duplicate processing will eventually happen.
- Prefetch count tuned to worker capacity — an unbounded prefetch lets one slow worker hoard messages other idle workers could process.
The incidents I've debugged in queue-based systems were never about RabbitMQ being unreliable — they were about a consumer written assuming exactly-once delivery, which message queues don't actually offer without deliberate idempotency on the consumer's side.
RabbitMQ promises at-least-once delivery. If your consumer isn't idempotent, that promise becomes your bug.
