Symptoms
ApproximateNumberOfMessagesVisibleandApproximateAgeOfOldestMessagekeep rising.- The DLQ count grows; orders, emails or jobs are delayed.
1. Read the queue
Q=https://sqs.eu-west-1.amazonaws.com/111122223333/orders
aws sqs get-queue-attributes --queue-url $Q --attribute-names All \
--query "Attributes.{visible:ApproximateNumberOfMessages, inFlight:ApproximateNumberOfMessagesNotVisible, vt:VisibilityTimeout, redrive:RedrivePolicy}"
| Pattern | Meaning |
|---|---|
| Visible rising, in-flight low | Consumers not polling (down, scaled to zero, permissions) |
| In-flight high, visible rising, DLQ growing | Consumers receive but fail — bug, dependency down, poison messages |
| In-flight high, duplicates processed | Visibility timeout shorter than processing time |
| DLQ growing, main queue normal | A subset of messages always fails (poison) |
2. Look at a DLQ message (without consuming it for good)
DLQ=https://sqs.eu-west-1.amazonaws.com/111122223333/orders-dlq
aws sqs receive-message --queue-url $DLQ --max-number-of-messages 5 --visibility-timeout 30 \
--attribute-names All --message-attribute-names All
Messages become visible again after 30 seconds. Correlate their IDs with consumer logs to find the exception. Common causes: schema change by the producer, a record that references a deleted entity, payload too large for a downstream API.
3. Fix the consumer
Lambda consumers
- Visibility timeout on the queue should be at least 6× the function timeout (AWS guidance) so retries don't overlap.
- Use partial batch responses (
ReportBatchItemFailures) so one bad message doesn't fail the whole batch and get good ones retried.
aws lambda update-event-source-mapping --uuid <uuid> --function-response-types ReportBatchItemFailures
aws sqs set-queue-attributes --queue-url $Q --attributes VisibilityTimeout=360
- If a downstream dependency is down, reduce pressure: lower the mapping's
MaximumConcurrencyrather than letting everything fail into the DLQ.
Container/EC2 consumers
- Check the worker count, crash loops and IAM permissions (
sqs:ReceiveMessage,sqs:DeleteMessage, KMSDecryptfor encrypted queues).
4. Redrive the DLQ
After the fix is deployed:
aws sqs start-message-move-task --source-arn arn:aws:sqs:eu-west-1:111122223333:orders-dlq \
--max-number-of-messages-per-second 50
aws sqs list-message-move-tasks --source-arn arn:aws:sqs:eu-west-1:111122223333:orders-dlq
Without a destination, messages go back to their original source queue. A rate limit protects downstream systems.
Warning
Redriving replays work. Make sure consumers are idempotent (dedupe on a business key or message ID) before you redrive orders, payments or emails.
5. Poison messages that can never succeed
Move them aside to an archive (S3) with their attributes, then delete from the DLQ. Raise a bug with the producer team.
Prevent it next time
- Alarms on
ApproximateAgeOfOldestMessage(main queue) and on any message in the DLQ. maxReceiveCountof 3–5 in the redrive policy; DLQ retention longer than the main queue.- Idempotent consumers and schema validation at the producer.