Signal Forge ADR-008: Dead Letter Queue for poison message handling
Status: Accepted
Decision: The RabbitMQ notifications queue is declared with x-dead-letter-exchange pointing
to orders.dlq (fanout exchange). Messages that exceed x-max-retries or are explicitly NACKed
without requeue are routed to a notifications.dlq queue.
Rationale:
- Without a DLQ, a consistently failing message causes an infinite retry loop that starves processing of other messages and spikes CPU.
- The dead-letter pattern is built into RabbitMQ — no additional application code is needed in the
NACK path. The same notification-svc consumer that carries the
SpanLink from the RabbitMQ producer
NACKs with
requeue=False; the broker handles routing. - DLQ messages can be inspected via the RabbitMQ Management UI and reprocessed manually or via a separate consumer once the underlying bug is fixed.
Alternative considered: Manual retry counter in Redis with re-publish — rejected as unnecessary complexity when RabbitMQ provides this natively.