Delivery Delays with Amazon SQS – Concepts, Use cases, Mechanisms

Spread the love

One of my earlier blogs, Amazon SQS – Long Polling versus Short Polling, introduced Amazon SQS as a cloud based, highly available, reliable, scalable, distributed, fully managed messaging service and provided a detailed explanation of the all important topic of strategies around writing efficient message consumers for Amazon SQS. Let us try and understand another important aspect with respect to world of enterprise messaging – Delivery Delays – in the context of Amazon SQS through this blog.

Delivery Delay – Overview

As the name suggests, Delivery Delay as a concept lets you specify a specified amount of delay to be introduced while delivering messages to its consumers. The delay is typically specified as part of sending the messages and is implemented by the messaging broker/provider transparently without the sender or the consumer having to do anything about it (apart from the sender specifying the delay). In fact, it is more transparent to the the consumer since in most cases, the consumer does not even realize that the message has been delayed by the broker, unless the consumer specifically checks message headers, or some mechanism, if at all supported by the broker, to derive that information.

A key point to note is that the delay is introduced by the broker while delivering the message, and neither is the sender blocked, nor is the message sending action delayed from a senders perspective. In other words, the message gets queued up in the broker/provider but is available for consumption (to any consumer) only after the specified delay.

Delivery Delay – Use Cases

Messaging is typically used to decouple systems, integrate applications/systems built using heterogeneous languages/platforms, scaling applications, as a plumbing layer between microservices and many more. Likewise, there are many real world use cases for Delayed Messages as well. Let us try to have a quick look at some real world examples.

  • In a lot of cases, Delivery Delays help overcome race conditions in distributed applications and subsystems. For example, consider a case where an application subsystem is inserting a row into a database, and sending a message about availability of this new data to various other subsystems, which in turn process this message and subsequently make updates to the same row. As you may observe, the likelihood of the initial insert getting committed after the updates get processed by the other subsystems obviously exists, and in such cases, the updates would typically fail.
  • Similarly, there could be end user use cases where you would like things to happen at a (small) delay so that the actions prior to that are completed, for example, sending a notification for an eCommerce purchase.
  • Another potential use of Delivery Delay could be to send a series of messages with increasing amounts of delay, which would obviously lead to these messages getting processed in the order as governed by the increasing delay period.

Delivery Delay as a concept has been around for a while, but was formally introduced in JMS through the JMS 2.0 specification which came out in 2013. Since it was not part of JMS 1.x, prior to it being introduced in JMS 2.0, it was supported by some message brokers/providers outside of the specification using custom header properties.

Often times, if the messaging provider/broker did not support Delivery Delays as a capability, this was either done programmatically in application code or done using constructs provided by application integration frameworks like Spring Integration, Apache Camel if such frameworks are being leveraged by the application.

Delivery Delay and Amazon SQS

Broadly speaking, there are two mechanisms supported by Amazon SQS to implement Delivery Delays, one at a queue level and the other at a message level. There are specifics around each one of them, specifically with respect to the type of queue. Let us try and understand the mechanisms as well as their behavior with respect to each queue type supported by Amazon SQS. Likewise, we will also take a quick look at the actual implementation options in terms of the API.

Option 1 – Delay Queues

Using this option, a queue can be optionally configured as a Delay Queue, thus implying all messages sent to that queue being delayed unless specifically overridden otherwise at a message level. (using Message Timers as explained below in the next section). The configuration property is named “DelaySeconds” and is specified in terms of seconds, with valid values being 0 to 900. Thus, the delivery of messages to consumers can be delayed by a maximum of 15 minutes. The default value is 0.

Key points to note:

  • A queue can be configured as Delay Queue during creation
  • An existing queue can be configured as Delay Queue as well, however what happens to existing messages in the queue depend on the type of queue.
    • Standard Queues – In case of standard queues, the existing messages do not get impacted, thus they are delivered as they would have been delivered earlier without any delay configuration, while new messages would get delayed by the time period specified in the configuration change. Thus, the change is not applied retroactively.
    • FIFO Queues – In case of FIFO queues, the configuration change is applied to existing messages as well, along with the new messages, making the configuration retroactive. Why so? Think about it, if this is not done, the ordering of messages could get distorted from a consuming application standpoint. In fact, I was pleasantly surprised to find out that the delay is applied to in-flight messages (messages that are already being read by some consumer but not yet deleted) as well – obviously this happens only if the current consumer reading the message just releases the message without deleting it.
  • The retroactive behavior mentioned above is observed in the reverse case as well. So if a standard queue, which is configured as a Delay Queue, is changed so that it is no longer a Delay Queue, the existing messages do not get impacted. Likewise, in case of FIFO queues put through a similar situation, the existing messages get impacted and existing messages (which were delayed and still under the original delay period) are made available immediately.
  • Value is specified in seconds, valid values are from 0 to 900.
  • The delay information is not available to consumers in the message.

Implementation Details

The implementation details would depend on how you create your queues (or configure your existing queues). You can use any of the valid mechanisms supported by Amazon, including Amazon Console, CloudFormation, CLI or the SDK’s.

Let us look at an example of using the Java API through the Java SDK for configuring an existing queue as a Delay Queue.

Option 2 – Message Timers

This mechanism allows us to specify a delay for each message in the sendMessage request. Again, the delay is specified in terms of seconds, with valid values being 0 to 900. The default value is 0. The value specified as part of this option overrides any queue level Delay Queue settings that may exist (for that particular message).

Key points to note:

  • Message Timers (or message level delaying) is not supported for FIFO queues, which is understandable since different delay values for different messages can lead to distortion of the FIFO behavior with respect to consumers.
  • If a message with a Delay Seconds value is sent to a queue, and the queue itself is configured with Delay Queue option, the value specified in the send message request takes precedence over the queue level settings of the Delay Queue. In fact, Amazon SQS also differentiates between setting the message level Delay Seconds value as 0 versus not setting it at all as part of the send request. So, here is how it works in various scenarios:
    • With DelaySeconds=non-zero value in the message, the value supplied in the message takes precedence and overrides the queue level setting, thus delaying the delivery of message by the period specified while sending the message
    • With DelaySeconds=0 in the message, the value supplied in the message overrides the queue level setting, thus there is no delivery delay for this message.
    • With DelaySeconds not specified (or specified as null) in the message, the queue level settings (if any) take effect.
  • Setting the delay time period is also supported using the Batch send API options. And even with batch, it can be set at each message level, thus, enabling message senders to set different delay time periods for different messages sent as part of one batch send call.
  • Value is specified in seconds, valid values range from 0 to 900.
  • Again, the delay information is not available to consumers in the message., not even as message attributes.

Implementation Details

As explained earlier, this option is also available to be set in various ways, including the Amazon console, CloudFormation, CLI and the SDK’s. Let us take a look at an example of setting it using the Java SDK option.


As you may note, the maximum value allowed for the delay is 900 seconds, which is 15 minutes. Although this would be sufficient for a lot of use cases, there are use cases where this delay period is required to be a larger value. Although considering the scale at which Amazon SQS is typically used, supporting a very high value for this delay could be problematic as well.


As part of this blog, we introduced the concept of Delivery Delays and looked at a bit of history with respect to this feature in the context of JMS. We then looked at the options available in Amazon SQS to implement delayed messaging. Along with understanding the two mechanisms provided by Amazon SQS to support delayed messages, we also looked at some of the constraints and corner cases around using these mechanisms. Hope you enjoyed reading this blog, and would provide your valuable suggestions, comments and/or feedback.

Happy learning, Happy sharing!!!



Spread the love

Leave a Reply

Your email address will not be published. Required fields are marked *