Recipe

SQS queue + DLQ design

A production-ready pattern for AWS SQS with dead-letter queues, exponential backoff, and idempotent consumers.

Architecture

Primary Queue (maxReceiveCount=3)
  ├── DLQ (retention=14d)
  ├── Consumer (visibility=30s)
  └── Alarm on DLQ depth > 0

Queue policy

redrivePolicy:
  deadLetterTargetArn: !GetAtt DLQ.Arn
  maxReceiveCount: 3

visibilityTimeout: 30
messageRetentionPeriod: 345600
receiveMessageWaitTimeSeconds: 20

Consumer loop

while true:
  msgs = sqs.receive(max=10, wait=20)
  for msg in msgs:
    try:
      handle(msg)
      sqs.delete(msg.receiptHandle)
    except RetryableError:
      pass  # visibility timeout expires, retry
    except FatalError:
      sqs.delete(msg.receiptHandle)  # poison pill

Idempotency key

Deduplicate by storing a hash of the message body + message ID in a TTL-indexed DynamoDB table. Check before processing; write after success. TTL = 2× visibility timeout.

Alarms

  • DLQ visible messages > 0 for 5 minutes
  • Primary queue age-of-oldest-message > 60s
  • Consumer heartbeat missing for 2 intervals