Queues & Background Processing in Depth · Background Job Processing

Retries and Dead-Letter Queues

Retry transient failures, park permanent ones.

Classify failures: transient (timeouts, 503, deadlocks) → retry with exponential backoff and jitter; permanent (validation errors, missing data, bugs) → don't retry endlessly. After max attempts, move the message to a dead-letter queue (DLQ) with error details, alert, and provide tooling to inspect, fix and redrive (replay) messages. DLQs are an operational queue, not a trash can.

DLQ mechanisms

Broker DLQ mechanism
SQS Redrive policy (maxReceiveCount) → DLQ; redrive back to source
RabbitMQ Dead-letter exchange (x-dead-letter-exchange) on reject/expiry
Kafka Application-level DLT topic (e.g., Spring DeadLetterPublishingRecoverer)
BullMQ / Celery Failed job state / custom DLQ queue
{
  "deadLetterTargetArn": "arn:aws:sqs:eu-west-1:123456789012:orders-dlq",
  "maxReceiveCount": "5"
}

Common pitfalls

  • Infinite retries of permanent failures.
  • DLQs without alerts or owners.
  • Redriving before fixing the cause.

Key points

  • Transient vs permanent
  • Max attempts → DLQ
  • Alert, inspect, redrive

Further reading: SQS: Dead-letter queues

Practice questions

Why shouldn't validation errors be retried?

Answer

They will fail the same way every time, wasting resources and delaying other messages; send them to the DLQ immediately.

What's needed to safely redrive DLQ messages?

Answer

A fix for the underlying cause, idempotent handlers (messages may have been partially processed), and controlled-rate replay with monitoring.

Open in the app to mark lessons complete, take notes and track your progress.