---
# === IDENTITY ===
id: software/debugging/aws-lambda-timeout-coldstart/2026
canonical_question: "How do I fix AWS Lambda timeouts and cold start issues?"
aliases:
  - "Lambda task timed out"
  - "AWS Lambda cold start"
  - "Lambda timeout troubleshooting"
  - "Lambda cold start optimization"
  - "Lambda provisioned concurrency"
  - "Lambda SnapStart"
  - "Lambda VPC timeout"
  - "Lambda slow invocation"
  - "Lambda ETIMEDOUT"
  - "Lambda init duration"
entity_type: software_reference
domain: software > debugging > aws_lambda_timeout_coldstart
region: global
jurisdiction: global
temporal_scope: 2020-2026

# === VERIFICATION ===
last_verified: 2026-05-17
confidence: 0.93
freshness: evolving
version: 1.1
first_published: 2026-02-20

# === TEMPORAL VALIDITY ===
temporal_validity:
  status: evolving
  last_breaking_change: "Lambda Durable Functions released late 2025 — breaks the 15-minute timeout ceiling via checkpoint/replay (up to 1 year)"
  next_review: 2026-11-13
  change_sensitivity: high

# === AGENT HINTS ===
inputs_needed:
  - key: "runtime"
    question: "Which Lambda runtime are you using?"
    type: choice
    options: ["Node.js", "Python", "Java", "Go", ".NET", "Rust/custom"]
  - key: "vpc_attached"
    question: "Is your Lambda function attached to a VPC?"
    type: choice
    options: ["yes", "no"]
  - key: "issue_type"
    question: "Are you experiencing timeouts, cold starts, or both?"
    type: choice
    options: ["timeout", "cold_start", "both"]

# === DISTRIBUTION ===
canonical_source: "https://knowledgelib.io/software/debugging/aws-lambda-timeout-coldstart/2026"
suggested_citation: "Source: knowledgelib.io — AI Knowledge Library (verified 2026-05-17)"

# === CONSTRAINTS ===
constraints:
  - "AWS Lambda only — does not apply to Azure Functions, GCP Cloud Functions, or Cloudflare Workers (different runtime models, different tuning)"
  - "Standard Lambda timeout is capped at 900 seconds (15 min); workloads exceeding this require Lambda Durable Functions (late 2025+, up to 1 year via checkpoint/replay), Step Functions, ECS, or Fargate"
  - "SnapStart is limited to Java 11/17/21, Python 3.12+, and .NET 8+ — not available for Node.js, Go, Ruby, or Rust runtimes as of May 2026"
  - "Provisioned concurrency eliminates cold starts but costs ~$0.015/GB-hour even when idle — do not enable without cost analysis"
  - "VPC cold start guidance assumes Hyperplane ENI (2019+); pre-2019 accounts may see legacy ~10s VPC attach penalty"
  - "Amazon Linux 2 runtimes reach end of life on June 30, 2026 — migrate to AL2023-based runtimes (Node.js 20+, Python 3.12+, Java 21) before then or face deprecation warnings and eventual loss of security patches"

# === SKIP CONDITIONS ===
skip_this_unit_if:
  - condition: "Using Azure Functions or GCP Cloud Functions"
    use_instead: "Platform-specific cold start and timeout tuning guides for Azure Functions or GCP Cloud Functions"
  - condition: "Using Cloudflare Workers, Deno Deploy, or other V8 isolate-based platforms"
    use_instead: "V8 isolate platforms have no traditional cold start; consult platform-specific performance docs"
  - condition: "Lambda error is IAM/permissions (AccessDeniedException, not authorized)"
    use_instead: "AWS IAM troubleshooting guide — timeout symptoms with permission root cause are unrelated to this unit"
  - condition: "Application logic bug causing infinite loop or runaway recursion unrelated to Lambda infrastructure"
    use_instead: "General debugging guide for the application runtime — the issue is in code logic, not Lambda configuration"

# === RELATED UNITS ===
related_kos:
  related_to:
    - id: "software/debugging/postgresql-slow-queries/2026"
      label: "PostgreSQL Slow Query Diagnosis"
    - id: "software/debugging/nodejs-econnrefused/2026"
      label: "Node.js ECONNREFUSED — symptom often surfaces from Lambda-to-downstream networking"
    - id: "software/debugging/postgresql-connection-pool/2026"
      label: "PostgreSQL Connection Pool Exhaustion — common cause of Lambda timeouts at high concurrency"
  often_confused_with:
    - id: "software/debugging/ssl-tls-certificate-errors/2026"
      label: "SSL/TLS certificate errors — can masquerade as Lambda timeout when handshake silently stalls without explicit error"

# === SOURCES ===
sources:
  - id: src1
    title: "Configure Lambda function timeout — AWS Lambda Documentation"
    author: Amazon Web Services
    url: https://docs.aws.amazon.com/lambda/latest/dg/configuration-timeout.html
    type: official_docs
    published: 2026-03-15
    reliability: authoritative
  - id: src2
    title: "Troubleshoot execution issues in Lambda — AWS Lambda Documentation"
    author: Amazon Web Services
    url: https://docs.aws.amazon.com/lambda/latest/dg/troubleshooting-execution.html
    type: official_docs
    published: 2025-01-01
    reliability: authoritative
  - id: src3
    title: "Understanding the Lambda execution environment lifecycle — AWS Lambda Documentation"
    author: Amazon Web Services
    url: https://docs.aws.amazon.com/lambda/latest/dg/lambda-runtime-environment.html
    type: official_docs
    published: 2025-01-01
    reliability: authoritative
  - id: src4
    title: "Improving startup performance with Lambda SnapStart — AWS Lambda Documentation"
    author: Amazon Web Services
    url: https://docs.aws.amazon.com/lambda/latest/dg/snapstart.html
    type: official_docs
    published: 2025-01-01
    reliability: authoritative
  - id: src5
    title: "Troubleshoot networking issues in Lambda — AWS Lambda Documentation"
    author: Amazon Web Services
    url: https://docs.aws.amazon.com/lambda/latest/dg/troubleshooting-networking.html
    type: official_docs
    published: 2025-01-01
    reliability: authoritative
  - id: src6
    title: "Understanding and Remediating Cold Starts: An AWS Lambda Perspective"
    author: Amazon Web Services
    url: https://aws.amazon.com/blogs/compute/understanding-and-remediating-cold-starts-an-aws-lambda-perspective/
    type: technical_blog
    published: 2024-06-01
    reliability: high
  - id: src7
    title: "What Causes AWS Lambda Cold Starts & 7 Ways to Solve Them"
    author: Lumigo
    url: https://lumigo.io/blog/this-is-all-you-need-to-know-about-lambda-cold-starts/
    type: technical_blog
    published: 2024-08-01
    reliability: high
  - id: src8
    title: "Operating Lambda: Performance optimization — Part 1"
    author: Amazon Web Services
    url: https://aws.amazon.com/blogs/compute/operating-lambda-performance-optimization-part-1/
    type: technical_blog
    published: 2024-03-01
    reliability: high
  - id: src9
    title: "AWS Lambda Durable Functions: stateful workflows up to 1 year"
    author: AWS / CodeStax (community deep-dive)
    url: https://codestax.medium.com/the-15-minute-wall-just-came-down-a-guide-to-aws-lambda-durable-functions-6151d3b6dd0b
    type: technical_blog
    published: 2026-01-15
    reliability: high
---

# How Do I Fix AWS Lambda Timeouts and Cold Start Issues?

## How do I fix AWS Lambda timeouts and cold start issues?

## TL;DR

- **Bottom line**: Lambda timeouts stem from 4 root causes in order of likelihood: insufficient memory/CPU (Lambda allocates CPU proportionally to memory), downstream service latency, VPC networking misconfiguration, and deployment package bloat causing slow INIT. Cold starts affect <1% of invocations but add 100ms-5s latency depending on runtime and package size. Fix timeouts by increasing memory to 1769 MB (1 full vCPU), adding connection timeouts to downstream calls, and configuring NAT gateway for VPC functions. Fix cold starts with SnapStart (Java/Python/.NET), provisioned concurrency, or smaller packages.
- **Key tool/command**: `aws lambda update-function-configuration --function-name my-func --memory-size 1769 --timeout 30`
- **Watch out for**: Setting timeout close to average duration causes intermittent failures. The default 3-second timeout is almost always too low for production functions.
- **Works with**: All Lambda runtimes (Node.js, Python, Java, Go, .NET, Rust). SnapStart requires Java 11+, Python 3.12+, or .NET 8+. Provisioned concurrency works with all runtimes.

## Constraints

- Standard Lambda timeout is 900 seconds (15 minutes). For longer workloads, either use **Lambda Durable Functions** (released late 2025; up to 1 year via checkpoint/replay across containers) or fall back to Step Functions, ECS, or Fargate. [src1, src9]
- INIT phase has a hard 10-second timeout (extended to 15 min with provisioned concurrency or SnapStart). If initialization takes >10s, the function fails before your handler ever runs. [src3]
- SnapStart only works on **published function versions and aliases** -- not $LATEST. It cannot be combined with provisioned concurrency, Amazon EFS, or ephemeral storage >512 MB. [src4]
- Lambda functions in a VPC have **no internet access by default**. They require a NAT gateway in a public subnet for outbound internet traffic. Without this, any HTTP call to an external service will timeout silently. [src5]
- Memory ranges from 128 MB to 10,240 MB. CPU is allocated proportionally: 1769 MB = 1 full vCPU, 3538 MB = 2 vCPUs, 5307 MB = 3 vCPUs. Below 1769 MB, your function runs on a fractional CPU. [src1, src3]
- Lambda supports max 20 concurrent TCP connections for DNS resolution. Exceeding this causes `UNKNOWNHOSTEXCEPTION` regardless of timeout settings. [src5]

## Quick Reference

| # | Cause | Likelihood | Signature | Fix |
|---|---|---|---|---|
| 1 | Insufficient memory/CPU | ~30% of cases | `Duration` near timeout; `Max Memory Used` near `Memory Size` in REPORT log | Increase memory to 1769 MB (1 vCPU). CPU scales with memory. [src1, src3] |
| 2 | Downstream service timeout | ~25% of cases | `Task timed out after X.XX seconds`; no error log before timeout | Add explicit connection/read timeouts (e.g., 5s) to HTTP clients, SDK calls. [src2] |
| 3 | VPC without NAT gateway | ~20% of cases | `ETIMEDOUT` or `Task timed out` on any external HTTP call | Add NAT gateway to public subnet; route private subnet traffic through it. [src5] |
| 4 | Cold start during INIT | ~10% of cases | `Init Duration: NNNNms` in REPORT log; first invocation slow | Use SnapStart, provisioned concurrency, or reduce package size. [src3, src4, src6] |
| 5 | Large deployment package | ~5% of cases | High `Init Duration` (>1s); large ZIP artifact | Tree-shake dependencies, use Lambda Layers for shared code. [src6, src7] |
| 6 | Recursive/infinite loop | ~5% of cases | Function always times out at exact timeout limit | Check S3 trigger writing back to same bucket, SQS re-queue loops. [src2] |
| 7 | Payload too large | ~3% of cases | Timeout with large event payloads (up to 6 MB sync, 256 KB async) | Batch smaller; use S3 pre-signed URLs for large data. [src2] |
| 8 | Default 3s timeout | ~2% of cases | `Task timed out after 3.00 seconds` on any non-trivial function | Set timeout to 30-60s for API backends, 300s for data processing. [src1] |
| 9 | Network ACL blocking ephemeral ports | Rare | Intermittent `ETIMEDOUT` in VPC functions | Allow TCP/UDP ports 1024-65535 in subnet Network ACLs. [src5] |
| 10 | DNS resolution limit exceeded | Rare | `UNKNOWNHOSTEXCEPTION` under high concurrency | Reduce concurrent DNS lookups; Lambda supports max 20 TCP DNS connections. [src5] |

## Decision Tree

> Full script: [decision-tree.txt](scripts/decision-tree.txt) (31 lines)

```
START — Lambda function timing out or slow
├── Check REPORT log in CloudWatch
│   ├── "Init Duration" present and > 1000ms?
│   │   ├── YES → COLD START ISSUE
│   │   │   ├── Runtime is Java/Python/.NET? → Enable SnapStart [src4]
# ... (see full script)
```

## Step-by-Step Guide

### 1. Check CloudWatch REPORT logs for diagnosis

Every Lambda invocation produces a REPORT line with key metrics. This is your starting point. [src2, src3]

```bash
# Find recent timeouts using CloudWatch Logs Insights
# Go to CloudWatch > Logs Insights, select your Lambda log group, and run:
fields @timestamp, @message
| filter @message like /Task timed out/
| sort @timestamp desc
| limit 20

# Check Init Duration (cold starts) and memory usage:
fields @timestamp, @duration, @maxMemoryUsed, @memorySize, @initDuration
| filter ispresent(@initDuration)
| stats avg(@initDuration) as avgColdStart, max(@initDuration) as maxColdStart,
        count(*) as coldStartCount
| sort coldStartCount desc
```

**Verify**: Check the `REPORT` line in CloudWatch Logs -- it shows `Duration`, `Billed Duration`, `Memory Size`, `Max Memory Used`, and `Init Duration` (if cold start).

### 2. Increase memory to get more CPU

Lambda allocates CPU proportionally to memory. Below 1769 MB, you get a fractional CPU. This is the single most impactful tuning knob. [src1, src3]

```bash
# Set memory to 1769 MB (1 full vCPU) and timeout to 30 seconds
aws lambda update-function-configuration \
  --function-name my-function \
  --memory-size 1769 \
  --timeout 30

# Use AWS Lambda Power Tuning to find optimal memory/cost balance:
# https://github.com/alexcasalboni/aws-lambda-power-tuning
```

**Verify**: `aws lambda get-function-configuration --function-name my-function --query '{Memory: MemorySize, Timeout: Timeout}'`

### 3. Add explicit timeouts to downstream calls

Never rely on the Lambda timeout as your only safety net. Set client-side timeouts on every external call. [src2]

```python
# Python — set explicit timeouts on HTTP calls and AWS SDK
import boto3
from botocore.config import Config
import urllib3

# AWS SDK: set connect and read timeouts
boto_config = Config(
    connect_timeout=5,    # 5 seconds to establish connection
    read_timeout=10,      # 10 seconds to read response
    retries={'max_attempts': 2}
)
dynamodb = boto3.client('dynamodb', config=boto_config)

# HTTP calls: always set timeout
http = urllib3.PoolManager()
response = http.request('GET', 'https://api.example.com/data',
                        timeout=urllib3.Timeout(connect=5.0, read=10.0))
```

```javascript
// Node.js — set explicit timeouts
const { DynamoDBClient } = require('@aws-sdk/client-dynamodb');

// AWS SDK v3: set timeouts
const client = new DynamoDBClient({
  requestHandler: {
    connectionTimeout: 5000,  // 5s connection timeout
    socketTimeout: 10000      // 10s socket timeout
  },
  maxAttempts: 2
});

// fetch/HTTP: always set AbortController timeout
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), 10000);
const response = await fetch('https://api.example.com/data', {
  signal: controller.signal
});
clearTimeout(timeoutId);
```

**Verify**: Test with a deliberately slow endpoint; function should throw a timeout error from the HTTP client before the Lambda timeout fires.

### 4. Fix VPC internet access (if VPC-attached)

VPC-attached Lambda functions have no internet access by default. All outbound traffic goes through the VPC. [src5]

```yaml
# AWS SAM template — Lambda in VPC with NAT gateway
# Ensure: private subnet routes 0.0.0.0/0 to NAT gateway in public subnet
Resources:
  MyFunction:
    Type: AWS::Serverless::Function
    Properties:
      Handler: index.handler
      Runtime: nodejs20.x
      MemorySize: 1769
      Timeout: 30
      VpcConfig:
        SecurityGroupIds:
          - !Ref LambdaSecurityGroup
        SubnetIds:
          - !Ref PrivateSubnet1
          - !Ref PrivateSubnet2
      Policies:
        - VPCAccessPolicy: {}

# For AWS-only services without internet: use VPC Endpoints
  DynamoDBEndpoint:
    Type: AWS::EC2::VPCEndpoint
    Properties:
      ServiceName: !Sub com.amazonaws.${AWS::Region}.dynamodb
      VpcId: !Ref VPC
      RouteTableIds:
        - !Ref PrivateRouteTable
```

**Verify**: `aws lambda invoke --function-name my-function --payload '{}' response.json && cat response.json` -- should return without timeout.

### 5. Enable SnapStart for Java, Python, or .NET cold starts

SnapStart takes a Firecracker microVM snapshot after INIT, reducing cold starts from seconds to sub-second. [src4]

```bash
# Enable SnapStart on a Lambda function (must publish a version)
aws lambda update-function-configuration \
  --function-name my-function \
  --snap-start ApplyOn=PublishedVersions

# Wait for update, then publish a version
aws lambda publish-version --function-name my-function

# Create alias pointing to the SnapStart-enabled version
aws lambda create-alias \
  --function-name my-function \
  --name live \
  --function-version 1
```

**Verify**: Invoke the alias and check CloudWatch for `Restore Duration` instead of `Init Duration` -- restore should be <200ms vs >1s init.

### 6. Configure provisioned concurrency for zero cold starts

Provisioned concurrency keeps execution environments pre-warmed. Most reliable but most expensive approach. [src3, src6]

```bash
# Set 10 provisioned concurrent executions on a published version
aws lambda put-provisioned-concurrency-config \
  --function-name my-function \
  --qualifier live \
  --provisioned-concurrent-executions 10

# Check provisioning status
aws lambda get-provisioned-concurrency-config \
  --function-name my-function \
  --qualifier live
```

**Verify**: `Status` should be `READY`. Invoke the alias -- CloudWatch REPORT should show no `Init Duration`.

## Code Examples

### Python: Lambda handler with cold start optimization

> Full script: [python-lambda-handler-with-cold-start-optimization.py](scripts/python-lambda-handler-with-cold-start-optimization.py) (27 lines)

```python
# Input:  API Gateway event
# Output: JSON response with downstream data
import json
import os
import boto3
# ... (see full script)
```

### Node.js: Optimized handler with lazy imports

> Full script: [node-js-optimized-handler-with-lazy-imports.js](scripts/node-js-optimized-handler-with-lazy-imports.js) (28 lines)

```javascript
// Input:  API Gateway event
// Output: JSON response
// INIT phase: import only what you need (not the entire AWS SDK)
const { DynamoDBClient, GetItemCommand } = require('@aws-sdk/client-dynamodb');
const { unmarshall } = require('@aws-sdk/util-dynamodb');
# ... (see full script)
```

### Java: SnapStart-optimized handler

> Full script: [java-snapstart-optimized-handler.java](scripts/java-snapstart-optimized-handler.java) (46 lines)

```java
// Input:  API Gateway proxy request
// Output: API Gateway proxy response
// Requires: Java 11+ runtime with SnapStart enabled
import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler;
# ... (see full script)
```

## Anti-Patterns

### Wrong: Using default 3-second timeout in production

```yaml
# ❌ BAD — 3-second default timeout is almost never enough for production [src1]
Resources:
  MyFunction:
    Type: AWS::Serverless::Function
    Properties:
      Handler: index.handler
      Runtime: nodejs20.x
      # No Timeout specified — defaults to 3 seconds
      # Any cold start + downstream call > 3s = failure
```

### Correct: Set appropriate timeout with margin

```yaml
# ✅ GOOD — explicit timeout based on expected duration + margin [src1]
Resources:
  MyFunction:
    Type: AWS::Serverless::Function
    Properties:
      Handler: index.handler
      Runtime: nodejs20.x
      MemorySize: 1769          # 1 full vCPU
      Timeout: 30               # 30s for API backends (p99 duration + margin)
      # For data processing: 300-900s depending on workload
```

### Wrong: Importing entire AWS SDK

```javascript
// ❌ BAD — imports entire SDK (~60MB), dramatically increases cold start [src7, src8]
const AWS = require('aws-sdk');
const dynamodb = new AWS.DynamoDB();
const s3 = new AWS.S3();
// Init Duration: 800-1500ms due to massive import
```

### Correct: Import only the clients you need

```javascript
// ✅ GOOD — modular imports, minimal cold start impact [src7, src8]
const { DynamoDBClient } = require('@aws-sdk/client-dynamodb');
const { S3Client } = require('@aws-sdk/client-s3');
// Init Duration: 150-300ms — only loads what's needed
```

### Wrong: Creating SDK clients inside the handler

```python
# ❌ BAD — creates a new client on every invocation, wasting warm-start reuse [src3, src8]
def handler(event, context):
    dynamodb = boto3.resource('dynamodb')  # NEW client every invocation
    table = dynamodb.Table('my-table')
    return table.get_item(Key={'id': event['id']})
```

### Correct: Initialize clients outside the handler

```python
# ✅ GOOD — client created once in INIT, reused across warm invocations [src3, src8]
import boto3

dynamodb = boto3.resource('dynamodb')       # Created once during INIT
table = dynamodb.Table('my-table')          # Persists across invocations

def handler(event, context):
    return table.get_item(Key={'id': event['id']})  # Reuses warm connection
```

### Wrong: VPC Lambda without NAT for external calls

```yaml
# ❌ BAD — VPC function with no internet path silently times out on external calls [src5]
Resources:
  MyFunction:
    Type: AWS::Serverless::Function
    Properties:
      Handler: index.handler
      Runtime: python3.12
      VpcConfig:
        SecurityGroupIds: [!Ref SG]
        SubnetIds: [!Ref PrivateSubnet]
      # No NAT gateway configured — ALL external HTTP calls will timeout
      # Error: connect ETIMEDOUT 176.32.98.189:443
```

### Correct: Route VPC traffic through NAT gateway or use VPC endpoints

```yaml
# ✅ GOOD — private subnet routes to NAT gateway for internet; VPC endpoints for AWS services [src5]
Resources:
  NATGateway:
    Type: AWS::EC2::NatGateway
    Properties:
      SubnetId: !Ref PublicSubnet
      AllocationId: !GetAtt EIP.AllocationId

  PrivateRoute:
    Type: AWS::EC2::Route
    Properties:
      RouteTableId: !Ref PrivateRouteTable
      DestinationCidrBlock: 0.0.0.0/0
      NatGatewayId: !Ref NATGateway
```

## Common Pitfalls

- **Default 3-second timeout**: The Lambda console defaults to 3 seconds. This is fine for simple operations but fails for any function that calls external services, uses VPC networking, or processes non-trivial data. Set to at least 10-30 seconds for API backends and 120-900 seconds for data processing. [src1]
- **Memory = CPU misconception**: Developers increase timeout when the real problem is CPU starvation. At 128 MB, your function gets a fraction of a CPU core. Increasing memory to 1769 MB gives 1 full vCPU and often makes functions 10x faster at the same cost (shorter duration). [src1, src3]
- **VPC internet access**: Functions attached to a VPC lose internet access unless you configure a NAT gateway. The error is a silent timeout (`ETIMEDOUT`), not a clear networking error. This is the #1 gotcha for VPC Lambda beginners. [src5]
- **SnapStart uniqueness trap**: SnapStart restores from a snapshot, meaning initialization code that generates unique values (UUIDs, random seeds, encryption keys) will produce the same values across all restored environments. Generate unique content in the handler, not in initialization. [src4]
- **Recursive invocation loops**: An S3 trigger that writes to the same bucket, or a DynamoDB stream handler that writes to the same table, creates an infinite loop that only stops at timeout. Always write to a different resource or use object key prefixes to filter. [src2]
- **Provisioned concurrency + SnapStart conflict**: These two features cannot be used together on the same function version. Choose one. SnapStart is free (Java only); provisioned concurrency costs ~$15-30/month per 10 environments at 512 MB. [src4]
- **API Gateway 29-second limit**: Even if your Lambda timeout is 900 seconds, API Gateway has a hard 29-second integration timeout. For long-running tasks behind API Gateway, use async invocation or Step Functions. [src1, src2]
- **Cold start after code deploy**: Every code deployment invalidates all warm execution environments, causing a burst of cold starts. Deploy during low-traffic periods or use traffic shifting with aliases to mitigate. [src3, src6]

## Diagnostic Commands

> Full script: [diagnostic-commands.sh](scripts/diagnostic-commands.sh) (43 lines)

```bash
# === Check current function configuration ===
aws lambda get-function-configuration --function-name my-function \
  --query '{Memory: MemorySize, Timeout: Timeout, Runtime: Runtime, VPC: VpcConfig.SubnetIds, SnapStart: SnapStart}'
# === Find recent timeouts in CloudWatch Logs Insights ===
# (Run in CloudWatch console, select your Lambda log group)
# ... (see full script)
```

## Version History & Compatibility

| Feature | Available Since | Notes |
|---|---|---|
| Lambda timeout (max 15 min) | 2018 (increased from 5 min) | All runtimes [src1] |
| VPC Hyperplane ENI (fast VPC attach) | 2019 | Eliminated ~10s VPC cold start penalty [src5] |
| Provisioned concurrency | Dec 2019 | All runtimes; eliminates cold starts [src3] |
| SnapStart for Java | Nov 2022 | Java 11+ Corretto; free [src4] |
| SnapStart for Python | Dec 2024 | Python 3.12+; caching/restore charges apply [src4] |
| SnapStart for .NET | Dec 2024 | .NET 8+; requires Amazon.Lambda.Annotations v1.6.0+ [src4] |
| Lambda Managed Instances | 2025 preview | Multi-concurrent execution on EC2-class instances |
| ARM64/Graviton support | 2021 | 20% faster cold starts vs x86; lower cost [src6] |
| INIT phase logging (INIT_REPORT) | Nov 2023 | Explicit Init/Restore phase error reporting [src3] |
| Lambda Durable Functions | Late 2025 (GA) | Stateful workflows up to **1 year** via checkpoint/replay; hibernation pauses billing while awaiting external signals (~20-30% cost reduction for human-in-the-loop) [src9] |
| Amazon Linux 2 runtime EOL | June 30, 2026 | Migrate to Amazon Linux 2023-based runtimes (Node.js 20+, Python 3.12+, Java 21); AL2-based Java 8/11/17 deprecate without migration |

## Decision Logic

### If `Init Duration` is present and >1000ms in REPORT log
--> Cold start is the bottleneck. If runtime is Java/Python 3.12+/.NET 8+, enable SnapStart (free for Java, charged for Python/.NET). [src3, src4]

### If runtime is Node.js/Go/Ruby/Rust and cold starts are unacceptable
--> SnapStart is not available as of May 2026. Either provisioned concurrency, ARM64 Graviton (15-20% faster cold start), or trim the deployment package. [src4, src6, src7]

### If `Max Memory Used` is close to `Memory Size` in REPORT log
--> Increase memory to at least 1769 MB (1 full vCPU). CPU scales with memory; this is the single highest-leverage tuning knob. [src1, src3]

### If function is VPC-attached and external HTTPS calls hang
--> Add a NAT gateway in a public subnet and route the private subnet's 0.0.0.0/0 through it. For AWS-only calls (DynamoDB, S3), use VPC endpoints instead to avoid NAT cost. [src5]

### If workload exceeds 15 minutes
--> Use Lambda Durable Functions (late 2025+) for stateful workflows up to 1 year, **OR** Step Functions for orchestration, **OR** ECS/Fargate for long-running compute. Do not try to chain regular Lambda invocations manually. [src1, src9]

### If `Task timed out at 3.00 seconds` appears
--> Default timeout is too low. Set 30s for API backends, 300-900s for data processing. Always set client-side timeouts on downstream calls before the Lambda timeout fires. [src1, src2]

### If timeouts are intermittent and only under load
--> Check DNS resolution limits (max 20 concurrent TCP connections for DNS) and connection pool exhaustion on downstream databases. Lower per-invocation parallelism or pool connections via RDS Proxy. [src5]

## When to Use / When Not to Use

| Use When | Don't Use When | Use Instead |
|---|---|---|
| Timeout <15 min and stateless workload | Processing >15 min (single invocation) | Lambda Durable Functions (stateful, ≤1 year), Step Functions, or ECS/Fargate |
| Cold start <2s is acceptable (most use cases) | Hard real-time requirement (<10ms) | EC2, ECS, or containers on always-on compute |
| Traffic is spiky or unpredictable | Steady high-throughput (>1000 req/s sustained) | ECS/Fargate with ALB (cheaper at scale) |
| SnapStart available for your runtime | Need zero cold starts guaranteed | Provisioned concurrency or containers |
| API Gateway integration timeout <29s | Long-running API response >29s | Async invocation + polling, or WebSocket API |

## Important Caveats

- **Cold starts affect <1% of invocations** in steady-state production workloads but can be 100% of invocations after a deployment or during a traffic spike from zero. Monitor `Init Duration` in CloudWatch metrics, not just averages. [src3, src7]
- **Memory cost trade-off**: Increasing memory from 128 MB to 1769 MB (14x) does not always mean 14x cost. Faster execution means shorter billed duration. Use AWS Lambda Power Tuning to find the cost-optimal memory setting. [src1, src3]
- **SnapStart snapshot uniqueness**: Initialization code runs once, then the snapshot is reused. Any random values, UUIDs, or temporary credentials generated during INIT will be identical across all restored instances. Always generate these in the handler. [src4]
- **Provisioned concurrency costs even when idle**: You pay for provisioned environments whether they are invoked or not (~$0.015/GB-hour). Use Application Auto Scaling to adjust provisioned concurrency based on traffic patterns. [src3]
- **ARM64 (Graviton) gives free performance**: Switching from x86 to arm64 provides up to 20% better price-performance with faster cold starts. Change architecture in function configuration -- no code changes needed for interpreted runtimes (Python, Node.js). [src6]

## Related Units

- [PostgreSQL Slow Query Diagnosis](/software/debugging/postgresql-slow-queries/2026)
- [Node.js ECONNREFUSED](/software/debugging/nodejs-econnrefused/2026)
- [PostgreSQL Connection Pool Exhaustion](/software/debugging/postgresql-connection-pool/2026)
- [SSL/TLS Certificate Errors](/software/debugging/ssl-tls-certificate-errors/2026)