How it works
The explanation, with examples you can run.
The life of a message
SendMessage: stored redundantly (up to 1 MiB; larger payloads go to S3 with a pointer). Kept for 4 days by default, up to 14.ReceiveMessage: returned to one consumer with a fresh receipt handle, hidden for the visibility timeout, receive count incremented. Use long polling (WaitTimeSecondsup to 20) to avoid paying for empty responses.DeleteMessagewith the latest receipt handle: gone. Otherwise it reappears when the timeout expires.- With a redrive policy, once the receive count exceeds
maxReceiveCount, SQS moves the message to a dead-letter queue (DLQ) instead.
Try it
A simulated clock with one message, a 30-second visibility timeout and maxReceiveCount 3. Consumer A is slower than the timeout, B and C crash.
Press Run to see what your code prints, in order.
Runs in this browser, in an isolated frame with no access to this page. console.log, info, warn and error are shown; code runs as a classic script, so use an async function for await.
t= 0s A receives order-42 (receive 1), hidden until t=30t=30s B receives order-42 (receive 2), hidden until t=60t=40s B crashes without deleting itt=45s A finishes late; its receipt handle is stale, and another consumer already has the messaget=60s C receives order-42 (receive 3), hidden until t=90t=65s C crashes without deleting itt=90s order-42 was received 3 times: moved to the DLQA did the work, but too late: the side effects happened, and the message was handed out again. Change visibilityTimeout to 60 and A deletes it cleanly.
Standard or FIFO
Standard queues support a nearly unlimited request rate, deliver at least once, and make a best effort at ordering. FIFO queues (names end in .fifo) deliver in order within each message group ID, and deduplicate messages with the same deduplication ID within 5 minutes. Without high-throughput mode they handle 300 API calls per second per action (3,000 messages with batches of 10); high-throughput mode raises that a lot, depending on the Region. A failing message blocks the rest of its group until it succeeds or reaches the DLQ.
Settings that prevent incidents
- Visibility timeout above worst-case processing time; for a Lambda trigger, AWS recommends at least six times the function's timeout.
- Always a DLQ, with an alarm on its depth (and on
ApproximateAgeOfOldestMessagein the main queue). - Idempotent consumers, keyed on a business ID, because duplicates will happen on standard queues.
- Batch sends, receives and deletes (up to 10 messages) to cut cost and API calls.
Check yourself
3 questions. Get them all right to finish this topic.
0 of 3 right so far. Get all three to finish this topic.