Task timed out after N seconds
Fix Lambda "Task timed out": read the REPORT line, raise memory and timeout, and check VPC NAT access. Covers cold starts and in-function client timeouts.
Task timed out after 3.01 seconds
Incident Overview
Fix Lambda "Task timed out": read the REPORT line, raise memory and timeout, and check VPC NAT access. Covers cold starts and in-function client timeouts.
medium fix·6 min read
By Vishvesh Patel·DevOps Engineer·Updated 21 September 2026
Task timed out after 3.01 seconds
{"errorMessage":"2026-09-21T09:14:02.123Z abc-123 Task timed out after 30.05 seconds"}
Runtime exited with error: signal: killed Runtime.ExitErrorDo this first3 steps
Run these in order. Each one tells you what its output means before you change anything.
• See where the time actually goes
The REPORT line gives Duration, Billed Duration, Memory Size, Max Memory Used and Init Duration. A large Init Duration means cold starts, and Max Memory Used near the limit means you are CPU starved as well.
• Raise memory, which raises CPU proportionally
Lambda allocates CPU in proportion to memory, so a CPU-bound function at 128MB is running on a fraction of a core. Raising memory often reduces both duration and total cost.
• Check whether the function is in a VPC without a route out
A Lambda in private subnets has no internet access unless there is a NAT gateway or VPC endpoints. Calls to a public API or to an AWS service without an endpoint hang until the timeout.
Lambda enforced the timeout you configured. The function was still running and was killed. The question is where the time went.
aws logs filter-log-events --log-group-name /aws/lambda/api --filter-pattern "REPORT" --max-items 10 --query 'events[].message' --output text
Read the REPORT line
Every invocation logs one:
Four things to read:
REPORT RequestId: abc-123 Duration: 3010.00 ms Billed Duration: 3010 ms Memory Size: 128 MB Max Memory Used: 127 MB Init Duration: 890.12 ms
Memory is CPU
This is the single most misunderstood thing about Lambda. CPU is allocated in proportion to memory. At 128 MB you get a small fraction of a vCPU; you reach roughly one full vCPU at 1,769 MB.
So a CPU-bound function at 128 MB is slow because it is CPU-starved, not because of anything in the code:
Counter-intuitively this often reduces cost. A function that takes 6,000 ms at 128 MB may take 700 ms at 1,024 MB. Billing is memory multiplied by duration, so 8x the memory for less than 1/8th the time is cheaper as well as faster.
AWS Lambda Power Tuning, a published state machine, measures this for your function across memory settings and shows the cost and duration curve. It is worth running once for anything invoked frequently.
aws lambda update-function-configuration --function-name api --memory-size 1024
The VPC trap
A Lambda in a VPC has no internet access. Attaching it to a VPC replaces the default networking, and a private subnet with no NAT gateway means:
This is the most common cause of a function that worked in development and times out after being moved into a VPC. The symptom is a hang rather than a connection error, because the packets go nowhere and nothing answers.
The fix is a NAT gateway for internet access, or VPC endpoints for AWS services. S3 and DynamoDB have free gateway endpoints; the rest are interface endpoints with an hourly cost.
Also ask whether the function needs the VPC at all. It is only required to reach private resources such as an RDS instance. A function that only calls public AWS APIs is better off outside a VPC entirely.
aws lambda get-function-configuration --function-name api --query 'VpcConfig'
Cold starts
A large Init Duration means initialisation, not your handler:
Things that inflate it:
Move work that is not needed for every invocation out of module scope, and import only what you use:
Provisioned concurrency removes cold starts for a fixed cost. SnapStart does the same for Java at no extra charge.
Init Duration: 3890.12 ms
Set the timeout deliberately
The default is 3 seconds and the maximum is 15 minutes. Set it a little above the observed p99, not at the maximum: a generous timeout turns a hung dependency into a function that burns fifteen minutes of billed time per invocation and keeps concurrency occupied.
Behind API Gateway the effective ceiling is API Gateway's own 29 second integration timeout, so a Lambda timeout above that cannot help.
aws lambda update-function-configuration --function-name api --timeout 30
Client timeouts inside the function
Set your SDK and HTTP client timeouts below the Lambda timeout, so a slow dependency produces a handled error with a useful log line rather than an abrupt kill:
A Lambda killed at its timeout gets no chance to log anything, which is why these failures are often invisible.
from botocore.config import Config
cfg = Config(connect_timeout=2, read_timeout=5, retries={"max_attempts": 2})Runtime.ExitError
Different failure: the runtime process was killed, usually out of memory rather than time. Check Max Memory Used against Memory Size in the REPORT line and raise memory.
Runtime exited with error: signal: killed
A checklist
Frequently Asked Questions
Why does increasing Lambda memory make my function faster?
Because Lambda allocates CPU in proportion to memory. At 128 MB you get a small fraction of a vCPU, and you reach roughly one full vCPU at 1,769 MB. A CPU-bound function at low memory is therefore throttled on processor time rather than limited by anything in your code. Raising memory frequently reduces cost as well as duration, because billing multiplies memory by time: eight times the memory for a tenth of the duration is cheaper overall.
Why does my Lambda time out after I attached it to a VPC?
Attaching a Lambda to a VPC removes its default internet access, and a private subnet with no NAT gateway has no route out. Calls to public APIs, and to AWS services that have no VPC endpoint in that subnet, simply hang until the timeout rather than failing fast. Add a NAT gateway, or create VPC endpoints for the services you use. It is also worth checking whether the VPC is needed at all: it is only required to reach private resources such as an RDS instance.
What is Init Duration and how do I reduce it?
Init Duration is the cold start: the time spent loading your code and running everything at module scope before the handler is called. Reduce it by shrinking the deployment package, importing only the specific SDK clients you need rather than whole libraries, and deferring expensive work such as database connections until first use. Provisioned concurrency eliminates cold starts for a fixed cost, and SnapStart does the same for Java runtimes without one.
What timeout value should I use?
Slightly above the observed p99 duration, not the maximum. A 15 minute timeout on a function that normally takes 200 milliseconds means a hung dependency burns fifteen minutes of billed time and holds a concurrency slot for the duration, which can starve the rest of your traffic. Behind API Gateway there is a hard ceiling anyway, since API Gateway's integration timeout is 29 seconds, so a longer Lambda timeout cannot help those invocations.
What is the difference between a timeout and Runtime.ExitError?
A timeout means the invocation was still running when the configured limit was reached, so the problem is duration. Runtime exited with error: signal: killed means the runtime process itself was terminated, which is usually the out-of-memory killer rather than the clock. Compare Max Memory Used against Memory Size in the REPORT line: if they are close, raise the memory allocation. The two are easy to confuse because both end the invocation abruptly with little in the logs.
Reference and practice
Learn the underlying concept
Other AWS errors
Free, comprehensive DevOps tutorials and learning roadmaps. Master Docker, Kubernetes, CI/CD, and more.
Get notified about new tutorials and features.
• Roadmaps
• Interview Prep
• Certifications
• Company
© 2026 DevOpsLesson. All rights reserved.
Need to practice this scenario?
Simulate this error condition and practice recovery commands safely in our in-browser terminal.