Visibility Timeout

Topics

When a consuming component in your system receives and processes a message from the queue, the message remains in the queue. Why doesn't Amazon SQS automatically delete it?

Because your system is distributed, there's no guarantee that the component will actually receive the message (it's possible the connection could break or the component could fail before receiving the message). Therefore, Amazon SQS does not delete the message, and instead, your consuming component must delete the message from the queue after receiving and processing it.

Immediately after the component receives the message, the message is still in the queue. However, you don't want other components in the system receiving and processing the message again. Therefore, Amazon SQS blocks them with a visibility timeout, which is a period of time during which Amazon SQS prevents other consuming components from receiving and processing that message. The following figure and discussion illustrate the concept.

Visibility Timeout

General Recommendations for Visibility Timeout

The visibility timeout clock starts ticking once Amazon SQS returns the message. During that time, the component processes and deletes the message. But what happens if the component fails before deleting the message? If your system doesn't call DeleteMessage for that message before the visibility timeout expires, the message again becomes visible to the ReceiveMessage calls placed by the components in your system and it will be received again. If a message should only be received once, your system should delete it within the duration of the visibility timeout.

Each queue starts with a default setting of 30 seconds for the visibility timeout. You can change that setting for the entire queue. Typically, you'll set the visibility timeout to the average time it takes to process and delete a message from the queue. When receiving messages, you can also set a special visibility timeout for the returned messages without changing the overall queue timeout.

We recommend that if you have a system that produces messages that require varying amounts of time to process and delete, you create multiple queues, each with a different visibility timeout setting. Your system can then send all messages to a single queue that forwards each message to another queue with the appropriate visibility timeout based on the expected processing and deletion time for that message.

Extending a Message's Visibility Timeout

When you receive a message from the queue, you might find the visibility timeout for the queue is insufficient to fully process and delete that message. Amazon SQS allows you to extend the visibility timeout for that particular message. When you extend the visibility timeout, Amazon SQS overwrites the original timeout value and the new value begins at the time you changed it.

For example, let's say the timeout for the queue is 30 seconds, and you receive a message. Once you're 20 seconds into the timeout for that message (i.e., you have 10 seconds left), you extend it by 60 seconds by calling ChangeMessageVisibility with VisibilityTimeoutset to 60 seconds. You have then changed the remaining visibility timeout from 10 seconds to 60 seconds.

The extension you request is not stored in memory for that message. If for some reason you don't delete the message and the message is received again, the visibility timeout for the message the next time it's received is the overall value for the queue and not the extended value you previously set.

Terminating a Message's Visibility Timeout

When you receive a message from the queue, you might find that you actually don't want to process and delete that message. Amazon SQS allows you to terminate the visibility timeout for a specific message, which immediately makes the message visible to other components in the system to process. To do this, you call ChangeMessageVisibility with VisibilityTimeout=0 seconds.

API Actions Related to Visibility Timeout

The following table lists the API actions to use to manipulate the visibility timeout.

To do this... Use this action

Set the visibility timeout for a queue

???

Get the visibility timeout for a queue

???

Set the visibility timeout for the received messages without affecting the queue's visibility timeout

??? and set the VisibilityTimeout parameter to the value you want

Extending or terminating a message's visibility timeout

???