SQS delay queues let you defer the delivery of a message for a specified period, enabling you to control when consumers start processing messages.
Let’s see this in action. Imagine you have a system that sends an order confirmation email. You want to send it 5 minutes after the order is placed, giving the user a chance to cancel.
Here’s how you’d configure a standard SQS queue to have a 5-minute delay:
aws sqs create-queue --queue-name order-confirmation-queue --attributes DelaySeconds=300
When a message is sent to this queue, it won’t be visible to consumers for 300 seconds (5 minutes).
aws sqs send-message --queue-url <your-queue-url> --message-body "Order ID: 12345, Customer: Alice"
After 5 minutes, the message becomes available for a consumer to ReceiveMessage and process.
The primary use case is to introduce a "grace period" for actions that might be reversed. For example, a payment processing system could place a message to capture funds into a delayed queue. If the order is cancelled within the delay period, the message is simply deleted without ever being processed. If the delay expires, the message is processed, and the payment is captured.
Another common pattern is for rate-limiting or batching operations. You might send a burst of messages to a queue and then configure a delay so that consumers process them at a more manageable rate, preventing downstream systems from being overwhelmed.
Internally, when you set DelaySeconds on a queue, SQS timestamps the message with a "visibility timeout" that is the current time plus the DelaySeconds value. Until that timestamp passes, the message is considered "invisible" to ReceiveMessage calls. The message is still stored in the queue, but it’s not eligible for retrieval.
You can also set a DelaySeconds value on a per-message basis, overriding the queue’s default delay. This is useful if some messages need a longer or shorter delay than the queue’s standard.
aws sqs send-message --queue-url <your-queue-url> --message-body "Order ID: 67890, Customer: Bob" --delay-seconds 600
This message will be delayed for 10 minutes, even if the queue’s default delay is 5 minutes. The effective delay for a message is the maximum of the message-level DelaySeconds and the queue-level DelaySeconds.
The DelaySeconds attribute on a queue can be set to a value between 0 and 900 seconds (15 minutes). If you need longer delays, you’d typically implement a custom solution, perhaps by sending the message to another queue after the initial delay expires.
When a message is sent to a queue with a DelaySeconds greater than 0, SQS does not immediately make it available for polling. The message is effectively held back until the specified delay has elapsed from the time it was sent. Consumers polling the queue will not see this message until it becomes visible. This mechanism ensures that your consumers only receive messages when you intend for them to be processed.
The next concept to explore is how SQS handles message visibility timeouts, which are distinct from delay queues but interact with message processing.