AWS Lambda Timeout Errors: Fix "Task timed out after X seconds"
The default Lambda timeout is 3 seconds — far too short for most real workloads. Here is how to increase it, eliminate cold starts, handle jobs that exceed the 15-minute hard limit, and work around Lambda@Edge constraints.
Step 1 — Find the timeout in CloudWatch Logs
Every Lambda timeout produces a log line like this in CloudWatch:
REPORT RequestId: a1b2c3d4 Duration: 3000.00 ms Billed Duration: 3000 ms ...
2026-07-17T10:23:01.000Z a1b2c3d4 Task timed out after 3.00 seconds The line just before the timeout line in the log stream shows what your function was doing — usually a database query, an HTTP request to an external API, or a large file read from S3. That is your actual bottleneck.
Duration exactly equal to your configured timeout, that confirms a hard timeout — not an unhandled exception.
Step 2 — Increase the timeout
The default is 3 seconds. The maximum is 900 seconds (15 minutes). You can change it in three ways:
AWS CLI
# Increase timeout to 30 seconds
aws lambda update-function-configuration \
--function-name my-function \
--timeout 30
# Verify the change
aws lambda get-function-configuration \
--function-name my-function \
--query 'Timeout' AWS SAM (template.yaml)
MyFunction:
Type: AWS::Serverless::Function
Properties:
Handler: index.handler
Runtime: nodejs20.x
Timeout: 30 # seconds, max 900
MemorySize: 512 # more memory = faster CPU Always set timeouts inside your function code too
Lambda's timeout kills the whole invocation but gives no useful error. Set per-call timeouts on every outbound request so you get actionable errors:
import urllib.request
import urllib.error
def handler(event, context):
# Check remaining time before expensive operations
remaining_ms = context.get_remaining_time_in_millis()
if remaining_ms < 2000:
raise RuntimeError("Not enough time remaining")
# Set explicit socket timeout on outbound HTTP calls
req = urllib.request.urlopen(
"https://api.example.com/data",
timeout=10 # seconds — never leave this None
)
return {"statusCode": 200, "body": req.read().decode()} // Node.js: use AbortSignal for fetch timeouts
export const handler = async (event: unknown, context: AWSLambda.Context) => {
const controller = new AbortController();
const timer = setTimeout(() => controller.abort(), 8_000); // 8 s
try {
const res = await fetch('https://api.example.com/data', {
signal: controller.signal,
});
return { statusCode: 200, body: await res.text() };
} finally {
clearTimeout(timer);
}
}; Step 3 — Fix cold starts
A cold start adds 100 ms–2 s to the very first invocation after a function has been idle. If your timeout is tight, cold starts alone can trigger it. Three strategies:
Provisioned Concurrency (all runtimes)
Keeps N execution environments initialized and ready. Eliminates cold starts for that concurrency level but incurs an hourly cost even when idle.
# Publish a version, then enable Provisioned Concurrency
aws lambda publish-version --function-name my-function
aws lambda put-provisioned-concurrency-config \
--function-name my-function \
--qualifier 1 \
--provisioned-concurrent-executions 5 SnapStart (Java 21, Python 3.12+)
Lambda takes a snapshot of the initialized execution environment after your INIT phase. Subsequent cold starts restore from the snapshot instead of re-initializing — typically 10× faster. No extra cost beyond execution time.
# Enable SnapStart on a Java 21 or Python 3.12+ function
aws lambda update-function-configuration \
--function-name my-java-function \
--snap-start ApplyOn=PublishedVersions Keep-alive ping via EventBridge Scheduler
A free option: trigger your function on a schedule every 5 minutes to prevent the runtime from being reclaimed. Not guaranteed — AWS may still replace execution environments — but reduces cold start frequency significantly for low-traffic functions.
# EventBridge rule: ping every 5 minutes
aws events put-rule \
--name keep-warm-my-function \
--schedule-expression "rate(5 minutes)"
# In your handler, skip real work on warm-up pings:
# if event.get('source') == 'aws.events': return {'statusCode': 200} Step 4 — Jobs longer than 15 minutes
Lambda's hard ceiling is 900 seconds. For longer workloads you need a different architecture:
Step Functions — orchestrate multiple Lambda steps
Each Lambda step can run up to 15 minutes. Step Functions chains them with built-in retry, error handling, and state. Total workflow duration can be up to one year.
// Pseudocode: each state calls a Lambda that finishes in <15 min
{
"Comment": "Long-running data pipeline",
"StartAt": "Extract",
"States": {
"Extract": {
"Type": "Task",
"Resource": "arn:aws:lambda:us-east-1:123:function:extract",
"Next": "Transform"
},
"Transform": {
"Type": "Task",
"Resource": "arn:aws:lambda:us-east-1:123:function:transform",
"Next": "Load"
},
"Load": {
"Type": "Task",
"Resource": "arn:aws:lambda:us-east-1:123:function:load",
"End": true
}
}
} SQS + Lambda fan-out — parallel chunk processing
Split large work into small items, push them to SQS, and let Lambda process each item independently in parallel. 1000 items that each take 10 seconds finish in 10 seconds total, not 10,000 seconds.
import boto3, json
sqs = boto3.client('sqs')
QUEUE_URL = 'https://sqs.us-east-1.amazonaws.com/123/my-queue'
def dispatcher_handler(event, context):
# Split work into chunks, enqueue each
items = get_all_items() # e.g. 50,000 rows
for chunk in chunks(items, 100): # 500 messages
sqs.send_message(
QueueUrl=QUEUE_URL,
MessageBody=json.dumps(chunk)
)
def worker_handler(event, context):
for record in event['Records']:
chunk = json.loads(record['body'])
process(chunk) # each invocation < 15 min Lambda@Edge timeout limits
Lambda@Edge has stricter limits than regular Lambda because it runs at CloudFront edge nodes:
| Event type | Max timeout | Max memory |
|---|---|---|
| viewer-request | 5 seconds | 128 MB |
| viewer-response | 5 seconds | 128 MB |
| origin-request | 30 seconds | 10,240 MB |
| origin-response | 30 seconds | 10,240 MB |
If you need more than 30 seconds at the edge, migrate from Lambda@Edge to CloudFront Functions (sub-1 ms for simple header manipulation) or route to a regional Lambda via CloudFront origin for heavier logic.
Memory, CPU, and timeout relationship
Lambda allocates CPU proportional to memory. A 1,769 MB function gets exactly 1 vCPU. A 512 MB function gets ~0.3 vCPU. CPU-bound functions that time out at 512 MB often complete well within the timeout at 1,024 MB — and can still be cheaper because they run in half the time.
# Quick benchmark: run your function at different memory sizes
aws lambda update-function-configuration \
--function-name my-function \
--memory-size 1024
# Then check REPORT lines in CloudWatch for Duration + Billed Duration
# to find the memory/price sweet spot /tmp is the only writable directory. It has a 512 MB default limit (adjustable up to 10,240 MB via --ephemeral-storage). Do not write to LAMBDA_TASK_ROOT — that directory is read-only.
Know when AWS has an outage
Free email alerts when AWS Lambda or any other service you depend on goes down. No credit card needed.
FAQ
What is the maximum timeout for AWS Lambda?
The maximum is 900 seconds (15 minutes). The default is 3 seconds. You can set any value between 1 and 900 via the AWS Console, CLI, or IaC tools like SAM, CDK, or Terraform.
How do I fix "Task timed out after 3.00 seconds"?
Run aws lambda update-function-configuration --function-name YOUR_FUNCTION --timeout 30 to increase the timeout. Then check CloudWatch Logs to identify whether the root cause is a slow external call, a cold start, or insufficient CPU (try increasing memory).
What is Lambda cold start and how do I fix it?
A cold start is the 100 ms–2 s overhead Lambda adds when provisioning a fresh execution environment. Fix it with Provisioned Concurrency (all runtimes), SnapStart (Java 21 / Python 3.12+), or periodic keep-alive pings via EventBridge Scheduler.
How do I run jobs longer than 15 minutes in AWS Lambda?
Lambda's hard limit is 15 minutes. Use AWS Step Functions to chain multiple Lambda steps, or SQS fan-out to split work into parallel short-lived invocations. For container workloads with no time limit, use AWS Fargate.