AWS SQS Visibility Timeout Calculator

Size a visibility timeout, and check the four settings around it that decide whether a failure is caught or repeated forever.

Paste below, or drop a file anywhere on this panel

Or drop a file anywhere on this panel. Nothing is uploaded: the analysis runs in this tab.

The answer appears here

Paste on the left and press Calculate. Nothing leaves this tab.

Examples

Real input you can load into the tool above. Each one shows a different thing going wrong, because that is what the tool is for.

Visibility under the function timeout

Every message delivered twice, with no error anywhere

function timeout: 60
visibility timeout: 30
maxReceiveCount: 5
wait time: 20

A dead letter queue with matching retention

Deletes what it catches, because the clock started on the source queue

function timeout: 30
visibility timeout: 180
maxReceiveCount: 5
wait time: 20
retention: 345600
dlq retention: 345600

A FIFO queue

One poison message stops its whole message group

fifo
function timeout: 30
visibility timeout: 180
maxReceiveCount: 5
wait time: 20

Common mistakes

These are the ones that fail silently. The config is accepted, nothing raises an error, and the consequence arrives later.

  1. Setting the visibility timeout equal to the function timeout

    It leaves no margin, so a slow invocation releases the message while it is still being handled and a second consumer starts on it.

    Instead:Use six times the function timeout, which is what AWS recommends for a Lambda event source mapping.

  2. Giving the dead letter queue the same retention as the source queue

    A message carries its original enqueue timestamp, so anything that failed for the full period is deleted on arrival.

    Instead:Set the dead letter queue to fourteen days, always.

  3. Leaving ReceiveMessageWaitTimeSeconds at zero

    Short polling samples a subset of servers, so a receive can come back empty while the queue is not, and every empty receive is billed.

    Instead:Set it to 20. It lowers both the cost and the latency.

A visibility timeout shorter than the consumer delivers every message twice

The message becomes visible again while the first consumer is still working on it, so a second one picks it up. Nothing errors and nothing is throttled: the only symptom is duplicated side effects that look like an application bug.

AWS recommends six times the function timeout

The margin is for the retries Lambda performs inside a single visibility window before the message is released, and for the time between the message becoming available and the function starting.

A message keeps its original enqueue time in a dead letter queue

So retention is measured from when it first arrived on the source queue, not from when it was moved. A message that failed for the source queue's whole retention is deleted from the dead letter queue the moment it lands, and the queue that exists to catch failures is empty.

Which is why a dead letter queue should always be set to fourteen days

The maximum, regardless of what the source is set to. It is the one setting here with no downside.

Without a redrive policy a failure repeats until retention runs out

Four days by default, at one attempt per visibility timeout, each billed and each invoking the consumer. A single poison message can keep a function busy for days.

A batch fails whole unless you opt out

One bad message in a batch of ten retries all ten, so messages that already succeeded are processed again. ReportBatchItemFailures fixes it, but only if the handler actually returns the failed identifiers rather than just having the flag set.

On a FIFO queue a poison message blocks its whole group

Ordering is the guarantee, so nothing behind a failing message in the same group is delivered. A message group keyed on a customer id therefore stops that customer entirely until the message clears.