AWS Lambda 15-minute timeout cap still hits max execution time
Lambda's hard 15-minute limit is real. Even if you set timeout to 30 minutes, it won't run past 900 seconds. Here's why and how to fix it.
First cause: you're looking at the wrong timeout setting
I see this all the time. Someone sets the Lambda timeout to 30 minutes, redeploys, and the function still dies at 15 minutes. The culprit here is almost always the API Gateway timeout or the ALB timeout — not Lambda itself.
API Gateway has a hard 29-second timeout for sync invocations. ALB gives you 60 seconds. Neither will let a Lambda run for 15 minutes. If you're calling Lambda via API Gateway, the gateway cuts the connection after 29 seconds. Lambda might still run but the client gets a 504 error.
Fix: Check how you're invoking the function. If it's synchronous (API Gateway, ALB, or direct invoke), those services have their own timeouts. For API Gateway, you can push that to 29 seconds max — that's the limit. For longer runs, switch to async invocation or use Step Functions.
Here's the pattern I use:
# Instead of calling Lambda directly with API Gateway
# Use API Gateway to trigger an SNS topic or SQS queue
# Then have Lambda pull from there asynchronously
# This bypasses the API Gateway timeout entirelyAlso check your Lambda's timeout configuration in the console or CLI. I've seen people set it in the code but not deploy the change. Run this to confirm:
aws lambda get-function-configuration --function-name your-function --query 'Timeout'If it shows 900 or less, your code change didn't apply.
Second cause: async invocation retries eating your time
Another common one — your Lambda runs fine for 10 minutes, but then it fails and retries. Lambda retries async invocations up to 3 times by default. Each retry resets the 15-minute clock. So if the first run takes 14 minutes and fails, the second run takes another 14 minutes, and you're looking at 28 minutes total before the function gives up.
Thing is, the error message shows "Task timed out after 15.00 minutes" because that's per invocation. But the total wall clock time for the whole operation can be much longer. This catches people off guard.
Fix: Set the retry count to 0 in the dead-letter queue configuration, or handle retries in your code. I prefer the code route:
import boto3
def lambda_handler(event, context):
# Check if this is a retry
if 'retryCount' in event:
if event['retryCount'] > 2:
# Send to DLQ and return early
sqs = boto3.client('sqs')
sqs.send_message(QueueUrl='YOUR_DLQ_URL', MessageBody=str(event))
return {'status': 'failed', 'message': 'Retry limit reached'}
# Your main logic here
try:
# Do the work
result = process_data(event)
return result
except TimeoutError:
# Increment retry count and re-raise
event['retryCount'] = event.get('retryCount', 0) + 1
raiseAlso check your Lambda's reserved concurrency. If the function gets throttled, retries pile up and the timeout window looks wrong.
Third cause: VPC configuration adding latency
If your Lambda runs inside a VPC (especially with a NAT gateway), the network overhead can eat into your 15-minute window. I've seen functions that take 10 seconds locally take 2 minutes in a VPC because of DNS resolution issues or routing problems.
NAT gateways add about 5ms per packet, but if you're doing heavy I/O (S3 uploads, database queries), that adds up fast. Also, if your Lambda uses a public endpoint but the VPC doesn't have a NAT gateway, the request just hangs until timeout.
Fix: First, check if you really need a VPC. If your Lambda only talks to AWS services via API, use VPC endpoints instead of a NAT gateway. This cuts latency and cost.
If you must use a VPC, set up a VPC endpoint for S3 and DynamoDB. Here's the configuration:
# Create VPC endpoints for S3 and DynamoDB
aws ec2 create-vpc-endpoint --vpc-id vpc-12345 --service-name com.amazonaws.us-east-1.s3
aws ec2 create-vpc-endpoint --vpc-id vpc-12345 --service-name com.amazonaws.us-east-1.dynamodb
# Then in Lambda, attach only the private subnets, not the public ones
# No NAT needed for internal trafficAlso check that your Lambda's security group allows outbound traffic to the endpoint. I've fixed this by adding a rule for HTTPS (443) to the VPC endpoint's prefix list.
Quick-reference summary table
| Cause | Symptoms | Fix |
|---|---|---|
| Wrong timeout setting | Lambda timeout set to 30 min but fails at 15 min. API Gateway returns 504. | Switch to async invocation or Step Functions. Check Lambda config actually deployed. |
| Async retries eating time | Function runs, fails, retries. Total time exceeds 15 min per invocation. | Set retry count to 0 or handle retries in code. Use DLQ for failures. |
| VPC latency | Function runs slow in VPC. DNS timeouts or NAT gateway bottlenecks. | Use VPC endpoints instead of NAT. Optimize security groups. Check routing. |
Was this solution helpful?