# Dead-letter queues

> A dead-letter queue (DLQ) stores messages that could not be processed after a defined retry policy, or that cannot succeed without intervention. It keeps failed messages from repeatedly consuming worker capacity while preserving them for investigation and recovery.

Source: https://sysround.com/concepts/dead-letter-queue
Updated: 2026-11-05


## How dead-letter queues works

A worker receives a message from a durable queue and acknowledges it after successful processing. If the worker fails or its visibility lease expires, the message can become available again; in a log-based system, the equivalent is retrying without advancing consumer progress.

Classify failures before choosing an action. A temporary provider timeout may deserve retries with exponential backoff and jitter, while an unsupported schema may go directly to quarantine. Set both an attempt limit and a maximum retry age so failures cannot circulate forever.

When the policy is exhausted, move the message to a DLQ or dead-letter topic. For example, an email job that fails five total processing attempts can leave the normal delivery queue so healthy jobs continue. The exact triggers and guarantees depend on the queue implementation.

Make the handoff durable. Use an atomic broker-supported transfer where available; otherwise, confirm the DLQ write before acknowledging the original message or committing its offset. A crash between those operations can create duplicates, so preserve a stable message ID and make the transfer and later processing duplicate-safe.

Store the original payload or a durable reference, message ID, schema version, attempt count, timestamps, and useful error context. Monitor arrival rate, backlog, and oldest unresolved message age, with an owner responsible for investigating failures.

After fixing the cause, replay selected messages at a controlled rate. Preserve the original business idempotency key, check whether the action is still valid, and track replay attempts separately so the same bad messages do not loop indefinitely.

## Worked example: Quarantining failed notification jobs

Suppose an email queue receives 1,000 jobs per minute. Workers allow five total attempts per job, using exponential backoff with jitter, with a maximum retry age of 30 minutes. A template bug makes 20 jobs fail consistently. After their retry budget is exhausted, workers durably write those jobs to a DLQ before acknowledging the originals. An alert identifies the affected template version. After deploying a fix, an operator replays the 20 jobs at two per second, preserving each notification's idempotency key. Workers skip expired notifications and suppress already-recorded sends. If the provider accepted an earlier send but its response was lost, avoiding another send requires provider-side idempotency or reconciliation; the DLQ alone cannot resolve that uncertainty.

## Trade-offs

- **Worker progress versus completion.** Quarantining a poison message frees worker capacity, but the associated business operation remains incomplete until explicitly resolved.
- **Ordering versus isolation.** Skipping a failed message can let later messages for the same entity run out of order, so strict sequencing may require pausing or quarantining that entity's stream.
- **Durability versus duplicate handling.** Writing to the DLQ before acknowledging the source avoids a loss window but can produce duplicates unless the handoff is atomic.
- **Recovery versus overload.** Large replays compete with fresh traffic and can recreate the original outage unless they have rate limits and reserved capacity.
- **Debugging versus storage and privacy.** Retained payloads help diagnosis but require bounded retention, access controls, and protection of sensitive fields.
- **Isolation versus outage handling.** A DLQ handles individual failures well, but a widespread dependency outage usually also needs backpressure or a circuit breaker to avoid quarantining an entire backlog.

## When to use it in a system design interview

- An asynchronous workflow must keep processing healthy jobs even when some messages repeatedly fail.
- External providers can fail temporarily, but retrying indefinitely would waste capacity or violate delivery deadlines.
- Malformed payloads, schema mismatches, or deterministic worker bugs can create poison messages.
- Failed work must remain inspectable and recoverable rather than being silently discarded.

## How to bring it up in the interview

- Introduce a DLQ as part of the failure policy, not as a standalone box: explain which errors are retried, the retry budget, and when work is quarantined.
- Walk through a crash during the source-to-DLQ handoff; interviewers often probe whether your design can lose a message or create duplicates.
- Explain who owns the backlog, what triggers an alert, and how a fix leads to selective, rate-limited replay.
- Defend replay safety with stable idempotency keys and current-state checks; expect questions about already-completed payments, expired notifications, and deleted resources.
- State whether skipping a failed message breaks ordering, and distinguish a few poison messages from a system-wide dependency failure.

## Common mistakes

- Treating arrival in the DLQ as successful business processing rather than an unresolved failure.
- Acknowledging the source message before the DLQ copy is durable, creating a message-loss window.
- Retrying permanent validation errors indefinitely or rapidly retrying every message during an outage.
- Replaying the entire backlog without idempotency, expiration checks, or limits on recovery traffic.
- Creating a DLQ without alerts, retention rules, access controls, or an owner who resolves its contents.

## Interview questions where it comes up

- [Design a notification system](https://sysround.com/questions/design-notification-system): Provider failures and invalid notification jobs require bounded retries, channel isolation, and safe recovery without duplicate sends.
- [Design a distributed message queue like RabbitMQ](https://sysround.com/questions/design-message-queue): Poison-message handling and lossless dead-letter transfer are central to queue durability and consumer progress.
- [Design a distributed job scheduler](https://sysround.com/questions/design-job-scheduler): Jobs that exhaust their retry policy need durable failure handling and controlled replay without repeating external side effects.
- [Design Google Photos](https://sysround.com/questions/design-google-photos): Failed image-processing jobs need quarantine and recovery while respecting deletions and preventing stale work from republishing removed photos.

## FAQ

### What is a dead letter queue?

A dead-letter queue is a separate destination for messages that cannot be processed under the normal delivery policy. Common reasons include exhausted retries, invalid payloads, or expiration, depending on the broker and configuration. It preserves failed work for investigation rather than letting it repeatedly disrupt normal processing.

### What is the difference between a retry queue and a dead-letter queue?

A retry queue holds messages scheduled for another automatic attempt, often after a delay. A DLQ holds messages that have left normal processing and usually need investigation or an explicit recovery decision. Repeatedly retrying everything in a DLQ without a new policy turns it into an uncontrolled retry loop.

### How do you safely replay messages from a dead-letter queue?

Fix or classify the failure first, then select messages that are still valid to process. Replay them at a bounded rate with the original business idempotency keys, while checking current state and expiration. Track replay results and avoid resetting retry history in a way that creates endless failure cycles.

## Related concepts

- [Message queues](https://sysround.com/concepts/message-queues)
- [Retries, backoff and jitter](https://sysround.com/concepts/retries-backoff)
- [Idempotency and idempotency keys](https://sysround.com/concepts/idempotency)
- [Message ordering](https://sysround.com/concepts/message-ordering)


---
SysRound (https://sysround.com) is an AI practice tool for system design interviews: a voice or typed AI interviewer, a shared whiteboard, then feedback on every skill and a model answer. Its feedback is AI-generated and can be wrong.
