Why is queue visibility timeout is recommended to be six times function timeout plus batch window?
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
When using AWS Lambda with SQS as an event source, AWS recommends setting the queue's visibility timeout to at least six times the function timeout plus the MaximumBatchingWindowInSeconds. This formula (6 * functionTimeout + batchWindow) prevents messages from being processed multiple times when Lambda retries failed invocations. Setting it too low causes duplicate processing; setting it too high delays legitimate retries after real failures.
How Visibility Timeout Works
When SQS delivers a message to a consumer, it hides that message from other consumers for the duration of the visibility timeout. If the consumer does not delete the message before the timeout expires, SQS makes the message visible again for redelivery.
Without an adequate visibility timeout, the message reappears while the original consumer is still processing it, causing duplicate execution.
Why Six Times the Function Timeout
Lambda's SQS integration has built-in retry logic. When a Lambda function fails (throws an error or times out), Lambda retries the entire batch of messages. The retry behavior includes:
- Initial attempt: Lambda invokes the function with the batch
- Up to 5 retries: On failure, Lambda retries with exponential backoff
- Total attempts: Up to 6 invocations (1 original + 5 retries)
Each retry can take up to the full function timeout duration. In the worst case:
If the visibility timeout is shorter than this total, the message becomes visible again while Lambda is still retrying, causing another Lambda invocation to pick up the same message.
The Batch Window Factor
The MaximumBatchingWindowInSeconds adds additional delay before Lambda starts processing. SQS waits up to this duration to collect messages into a batch before invoking the function:
The batch window consumes part of the visibility timeout before processing even begins, which is why it is added to the formula.
Configuring the Settings
AWS CDK
AWS SAM Template
Terraform
What Happens with Incorrect Settings
| Visibility Timeout | Behavior |
| Too low (less than 6x + batch) | Messages reappear during retries, causing duplicate processing |
| Correct (6x + batch) | Messages stay hidden through all retry attempts |
| Too high (much more than 6x) | Failed messages take a long time to become available for reprocessing |
Common Pitfalls
- Setting visibility timeout equal to function timeout: This only covers one attempt. Lambda retries up to 5 additional times, so the message reappears during retry 2 and gets processed by another invocation concurrently.
- Forgetting the batch window: The batch window delays invocation but the visibility timeout clock is already ticking. Without adding the batch window to the formula, the effective processing time is shorter than expected.
- Using default SQS visibility timeout (30 seconds): The SQS default of 30 seconds is almost never sufficient for Lambda integrations. Always calculate and set it explicitly based on your function timeout and batch window.
- Not making the function idempotent: Even with correct visibility timeout settings, network issues or Lambda service errors can cause occasional duplicate deliveries. Design your function to handle the same message more than once safely.
- Ignoring dead-letter queue configuration: If a message fails all 6 attempts, it needs somewhere to go. Configure a dead-letter queue with
maxReceiveCountto prevent poison messages from being retried indefinitely.
Summary
- The formula is
visibilityTimeout = 6 * functionTimeout + batchWindow - The factor of 6 accounts for 1 original invocation + 5 automatic retries by Lambda
- The batch window is added because it consumes visibility timeout before processing starts
- Setting visibility timeout too low causes duplicate message processing
- Always configure a dead-letter queue for messages that exhaust all retry attempts
- Design Lambda functions to be idempotent regardless of timeout settings

