Free — no signup required

Dead Letter Queues (DLQ): The Graveyard

3 min read

The "Poison Pill" Problem

Imagine a message arrives in your queue with a malformed JSON body — a syntax error introduced by a bug in the producer. Your consumer application tries to parse it, throws an exception, and crashes without calling DeleteMessage. The Visibility Timeout expires, the message reappears, and the cycle repeats indefinitely.

This is called a poison pill message. It:
- Burns compute resources (Lambda invocations cost money).
- Blocks processing of legitimate messages behind it (in FIFO queues).
- Generates a flood of error logs and alarms.
- Can exhaust your consumer's retry budget, causing it to stop processing entirely.

The DLQ Solution

A Dead Letter Queue (DLQ) is a standard SQS queue that you designate as a holding area for messages that have repeatedly failed processing. You configure a Redrive Policy on your source queue:

"If a message has been received (and not deleted) N times — called the maxReceiveCount — move it to the DLQ automatically."

A maxReceiveCount of 3–5 is typical. After 5 failed attempts, SQS moves the message to the DLQ and stops retrying. Your main queue is unblocked.

What to Do with DLQ Messages

The DLQ is not a trash can — it's a quarantine. Standard practice:

  1. Alarm on DLQ depth: Set a CloudWatch alarm that fires when ApproximateNumberOfMessagesVisible in the DLQ exceeds 0. Any message in the DLQ is a bug that needs investigation.
  2. Inspect the message: Read the raw message body to understand why it failed.
  3. Fix the bug: Patch the producer (if the message is malformed) or the consumer (if it can't handle a valid edge case).
  4. Redrive: Use SQS's Dead-Letter Queue Redrive feature to replay DLQ messages back to the source queue after the fix is deployed.

DLQ for SNS

SNS also supports DLQs, but at the subscription level, not the topic level. If SNS cannot deliver a message to a subscribed SQS queue (e.g., the queue was deleted), it can send the undelivered message to a DLQ attached to that subscription. This catches delivery failures that happen between SNS and SQS, not just processing failures inside the consumer.

Interview Tip

Interviewers sometimes ask: "How do you handle a poison pill message in SQS?" A weak answer is "use a DLQ." A strong answer explains the full lifecycle: configure maxReceiveCount on the redrive policy, alarm on DLQ depth with CloudWatch, inspect and fix the root cause, then use the SQS Redrive feature to replay messages. Also mention that for FIFO queues, a poison pill is especially dangerous because it blocks all messages in the same Message Group ID — making DLQ configuration even more critical there.

This is one of 18 chapters

Get every chapter — Kubernetes, Terraform, SRE, distributed systems, and more — with fast daily review built in.

See pricing