Understanding AWS SQS ChangeMessageVisibility

Peiti Li
3 min readSep 16, 2021

The VisibilityTimeout in SQS is a straightforward concept according to the official doc. It is a time frame that the message can be hidden so that no others can consume it except the first consumer who calls the ReceiveMessageAPI. And the maximum value of VisibilityTimeout is 43200 seconds or 12 hours.

However the API ChangeMesssageVisibility is tricky because the doc on AWS is too vague.

For example, you have a message with a visibility timeout of 5 minutes. After 3 minutes, you call ChangeMessageVisibility with a timeout of 10 minutes. You can continue to call ChangeMessageVisibility to extend the visibility timeout to the maximum allowed time. If you try to extend the visibility timeout beyond the maximum, your request is rejected.

It is very confusing because you cannot tell what does that mean. If you poke around for some lauguage specific docs such as Java, or Go, things “seems” become clearer. There is a parameter called VisibilityTimeout in the request of ChangeMessageVisibilityAPI, and, according to the doc it means

The new value for the message’s visibility timeout (in seconds). Values range: 0 to 43200. Maximum: 12 hours.

OK, now you may feel you understand how it works. As long as you still have the message handle, you can call this API to change its VisibilityTimeout to any new value as long as the value is between 0 and 43200. However that’s not the case.

Take a look at the following Go code snippet

What do you think the output of this program? You may think, well, the message is retrieved with VisibilityTimeout 30 seconds, then the program sleeps for 10 seconds(you can think of it as the program is doing some business logic that takes 10 seconds), then it tries to change the message’s visibility timeout to a new value 43191 seconds (< 12 hours) because the program maybe doesn’t want other consumer to consume it for 43191seconds, fair.

However the program actually ends up in L43 and prints out an error that says

operation error SQS: ChangeMessageVisibility, https response error StatusCode: 400, RequestID: d6a5bb0e-ef0a-5874–80fa-e2b231a17d11, api error InvalidParameterValue: Value 43191 for parameter VisibilityTimeout is invalid. Reason: Total VisibilityTimeout for the message is beyond the limit [43200 seconds]

What?! 43191 is between 0 and 43200, why it cannot be set?

OK, that’s because after you retrieved the message at L27, time has lapsed for 10 seconds(L35), and SQS rejects it because

10 + 43191 > 43200

So the parameter VisibilityTimeout of the request of ChangeMessageVisibility API actually means from the time the ChangeMessageVisibility request is made, how much more time the message is invisible to others. And the total timeout cannot exceed 43200. (Not the parameter cannot exceed 43200!)

I cannot find the implementation of that API, however I found this resource probably reflects what the implementation is. I think AWS should really fix the doc of this API.

--

--