SQS message retention is actually a hard limit, not a tunable parameter you can arbitrarily extend.

Let’s see SQS message retention in action. Imagine you have a queue named my-processing-queue. You send a few messages to it:

aws sqs send-message --queue-url https://sqs.us-east-1.amazonaws.com/123456789012/my-processing-queue --message-body "{\"order_id\": 101, \"item\": \"widget\"}"
aws sqs send-message --queue-url https://sqs.us-east-1.amazonaws.com/123456789012/my-processing-queue --message-body "{\"order_id\": 102, \"item\": \"gadget\"}"
aws sqs send-message --queue-url https://sqs.us-east-1.amazonaws.com/123456789012/my-processing-queue --message-body "{\"order_id\": 103, \"item\": \"thingamajig\"}"

Now, you can check the queue’s attributes to see its current retention period. By default, it’s 4 days:

aws sqs get-queue-attributes --queue-url https://sqs.us-east-1.amazonaws.com/123456789012/my-processing-queue --attribute-names MessageRetentionPeriod

The output might look like this:

{
    "Attributes": {
        "MessageRetentionPeriod": "345600"
    }
}

The value 345600 is the number of seconds, which equals 4 days (4 * 24 * 60 * 60).

SQS retains messages until they are either deleted by a consumer or until the retention period expires, whichever comes first. The maximum retention period for standard and FIFO queues is 14 days. This is a fundamental characteristic of the service, designed to balance durability with cost and performance.

You can change the retention period for an existing queue, but you can’t go beyond that 14-day ceiling. To set it to the maximum of 14 days (1,209,600 seconds) for my-processing-queue:

aws sqs set-queue-attributes --queue-url https://sqs.us-east-1.amazonaws.com/123456789012/my-processing-queue --attributes MessageRetentionPeriod=1209600

After running this, if you check the attributes again, you’ll see:

{
    "Attributes": {
        "MessageRetentionPeriod": "1209600"
    }
}

The problem SQS message retention solves is providing a buffer for asynchronous processing. If your worker processes fail to consume messages, SQS holds onto them for a configurable duration, preventing data loss and allowing for retries. The 14-day maximum ensures that messages aren’t kept indefinitely, which would incur significant storage costs and potentially lead to stale data.

Internally, SQS uses a distributed storage system to hold messages. When a message is sent, it’s written to this storage. A message remains in the queue until its visibility timeout expires (meaning a consumer has received it but not yet deleted it) and the message is then deleted by the consumer, or until the MessageRetentionPeriod has elapsed since the message was sent. Once the retention period is reached, SQS automatically purges the message from its storage, regardless of whether it was processed or not.

The key levers you control are the MessageRetentionPeriod attribute when creating or updating a queue, and the VisibilityTimeout when a consumer receives a message. The MessageRetentionPeriod is a queue-level setting, while VisibilityTimeout is per-message and starts when a message is received. If a consumer doesn’t delete a message within its visibility timeout, the message becomes visible again in the queue for another consumer to pick up. If the message is deleted, it’s gone, irrespective of the retention period.

You might think that if you set a message’s visibility timeout to be longer than the retention period, the message would be retained for the visibility timeout duration. This is incorrect. The MessageRetentionPeriod is the absolute maximum time a message will exist in SQS. If a message is sent and the retention period expires before any consumer can even receive it (e.g., due to a long visibility timeout or no consumers available), the message will be deleted by SQS.

The next concept you’ll likely encounter is managing message visibility and handling dead-letter queues for failed processing.

Want structured learning?

Take the full Sqs course →