Introduction

Lambda cold starts occur when a function hasn't been invoked recently and AWS needs to initialize a new execution environment. This includes downloading your code, starting the runtime, and running initialization code. Cold starts add 100ms to several seconds of latency to the first request.

Symptoms

CloudWatch Logs show initialization time:

```bash $ aws logs filter-log-events --log-group-name /aws/lambda/my-function \ --filter-pattern "INIT_START"

INIT_START Runtime Version: python:3.11 INIT_START Runtime Version: java:21 Duration: 1500.00 ms # Cold start initialization ```

Function latency metrics:

```bash $ aws cloudwatch get-metric-statistics \ --namespace AWS/Lambda --metric-name Duration \ --dimensions Name=FunctionName,Value=my-function \ --statistics Average \ --period 300

# P99 latency shows cold start spikes: # Average: 50ms (warm) # P99: 2500ms (cold start) ```

Client experiences:

bash
Request 1: 2500ms (cold start)
Request 2: 50ms (warm)
Request 3: 50ms (warm)
... (15 minutes idle)
Request 4: 2500ms (cold start again)

Common Causes

  1. 1.No provisioned concurrency - AWS scales to zero when idle
  2. 2.Large deployment package - Slow download and initialization
  3. 3.Heavy initialization code - Complex imports or SDK initialization
  4. 4.Java runtime - JVM initialization adds significant latency
  5. 5.Dependency loading - Many dependencies slow startup
  6. 6.Lambda execution environment reclaimed - After ~15 minutes idle

Step-by-Step Fix

  1. 1.Check logs for specific error messages
  2. 2.Verify configuration settings
  3. 3.Test network connectivity
  4. 4.Review recent changes
  5. 5.Apply corrective action
  6. 6.Verify the fix

Step 1: Analyze Cold Start Frequency

```bash # Check init duration in CloudWatch aws logs filter-log-events \ --log-group-name /aws/lambda/my-function \ --filter-pattern "INIT_START" \ --query 'events[*].message'

# Get invocation count vs init count aws cloudwatch get-metric-statistics \ --namespace AWS/Lambda --metric-name Invocations \ --dimensions Name=FunctionName,Value=my-function \ --statistics Sum --period 86400

# Compare with initialization count aws logs filter-log-events \ --log-group-name /aws/lambda/my-function \ --start-time $(date -d '1 day ago' +%s)000 \ --filter-pattern "INIT_START" | wc -l ```

Step 2: Enable Provisioned Concurrency

```bash # Check current provisioned concurrency aws lambda get-function-concurrency --function-name my-function

# Set provisioned concurrency on alias aws lambda put-provisioned-concurrency-config \ --function-name my-function \ --qualifier prod \ --provisioned-concurrent-executions 5

# Wait for status aws lambda get-provisioned-concurrency-config \ --function-name my-function --qualifier prod \ --query 'Status'

# Should show: READY ```

Note: Provisioned concurrency keeps execution environments initialized and ready.

Step 3: Configure Auto Scaling for Provisioned Concurrency

```bash # Create Application Auto Scaling target aws application-autoscaling register-scalable-target \ --service-namespace lambda \ --resource-id function:my-function:prod \ --scalable-dimension lambda:function:ProvisionedConcurrency \ --min-capacity 1 \ --max-capacity 10

# Add scaling policy based on utilization aws application-autoscaling put-scaling-policy \ --service-namespace lambda \ --resource-id function:my-function:prod \ --scalable-dimension lambda:function:ProvisionedConcurrency \ --policy-name my-scaling-policy \ --policy-type TargetTracking \ --target-tracking-scaling-policy-configuration \ '{"TargetValue": 0.7, "PredefinedMetricSpecification": {"PredefinedMetricType": "LambdaProvisionedConcurrencyUtilization"}}' ```

Step 4: Use Lambda SnapStart (Java Functions)

```bash # Enable SnapStart for Java functions aws lambda update-function-configuration \ --function-name my-java-function \ --snap-start '{"ApplyOn": "PublishedVersions"}'

# SnapStart caches initialized state: # - JVM initialization # - Class loading # - Static initialization # - Function handler initialization

# Verify SnapStart is enabled aws lambda get-function-configuration \ --function-name my-java-function \ --query 'SnapStart' ```

SnapStart reduces Java cold starts from 2-6 seconds to sub-100ms.

Step 5: Optimize Deployment Package Size

```bash # Check function code size aws lambda get-function --function-name my-function \ --query 'Configuration.CodeSize'

# Large packages (>50MB) take longer to download # Reduce size by: # - Removing unnecessary dependencies # - Using Lambda layers for shared dependencies # - Minifying code where applicable

# Create Lambda layer for large dependencies aws lambda publish-layer-version \ --layer-name my-deps-layer \ --description "Shared dependencies" \ --zip-file fileb://layer.zip

# Update function to use layer aws lambda update-function-configuration \ --function-name my-function \ --layers arn:aws:lambda:region:account:layer:my-deps-layer:1 ```

Step 6: Move Initialization Outside Handler

Python example:

```python # BAD: Initialization inside handler def handler(event, context): import boto3 # Slow import on cold start import pandas # Very slow import

s3 = boto3.client('s3') # SDK initialization # ... rest of handler

# GOOD: Initialization outside handler import boto3 import pandas

s3 = boto3.client('s3') # Runs once at cold start, reused for warm starts

def handler(event, context): # Handler starts faster, uses pre-initialized clients # ... rest of handler ```

Java example:

```java // BAD: Initialization inside handler public class Handler implements RequestHandler<String, String> { @Override public String handleRequest(String input, Context context) { S3Client s3 = S3Client.create(); // Created every invocation // ... } }

// GOOD: Initialization outside handler public class Handler implements RequestHandler<String, String> { private final S3Client s3 = S3Client.create(); // Created once

@Override public String handleRequest(String input, Context context) { // s3 already initialized // ... } } ```

Step 7: Minimize Dependency Load Time

```bash # For Python, use specific imports instead of module-level imports # Avoid: import boto3 (loads all services) # Use: from boto3 import client (loads only what needed)

# Check dependency count pip list | wc -l

# Remove unused dependencies pip-autoremove

# For Node.js, check bundle size npm list --depth=0

# Use bundlers like esbuild to tree-shake esbuild handler.js --bundle --minify --platform=node --target=nodejs18.x ```

Step 8: Keep Functions Warm

```bash # Use CloudWatch Events to ping function periodically aws events put-rule \ --name keep-lambda-warm \ --schedule-expression "rate(5 minutes)"

# Add Lambda as target aws events put-targets \ --rule keep-lambda-warm \ --targets '{"Id": "1", "Arn": "arn:aws:lambda:region:account:function:my-function"}'

# Note: This is a workaround, provisioned concurrency is preferred ```

Step 9: Monitor Cold Start Metrics

```bash # Create CloudWatch alarm for cold starts aws cloudwatch put-metric-alarm \ --alarm-name lambda-cold-start-frequency \ --namespace AWS/Lambda \ --metric-name InitDuration \ --dimensions Name=FunctionName,Value=my-function \ --statistic Average \ --period 60 \ --threshold 1000 \ --comparison-operator GreaterThanThreshold \ --evaluation-periods 1

Step 10: Compare Runtime Cold Start Times

Average cold start times by runtime:

RuntimeTypical Cold Start
Python100-300ms
Node.js100-200ms
Go50-100ms
Java (without SnapStart)2000-6000ms
Java (with SnapStart)50-200ms
.NET500-1500ms

Consider switching to faster runtime if cold starts are critical.

Verification

```bash # After enabling provisioned concurrency aws lambda invoke --function-name my-function:prod output.json

# Check duration in response cat output.json | jq '.duration'

# CloudWatch should show reduced P99 latency aws cloudwatch get-metric-statistics \ --namespace AWS/Lambda --metric-name Duration \ --dimensions Name=FunctionName,Value=my-function \ --statistics p99 \ --period 300 ```

  • [Fix AWS Lambda Function Timeout](/articles/fix-aws-lambda-function-timeout)
  • [Fix AWS Lambda Memory Limit Exceeded](/articles/fix-aws-lambda-memory-limit-exceeded)
  • [Fix AWS Lambda SnapStart Initialization Failed](/articles/fix-aws-lambda-snapstart-initialization-failed)
  • [AWS troubleshooting: Fix IAM Permission Denied - Complete Tro](fix-iam-permission-denied)
  • [AWS cloud troubleshooting: AWS ACM Certificate Pending Validation Because the](aws-acm-certificate-pending-validation-wrong-route53-zone)
  • [AWS cloud troubleshooting: AWS ALB Returns 502 Because the Target Closed the ](aws-alb-502-target-closed-connection-keepalive-timeout-mismatch)
  • [AWS cloud troubleshooting: Fix AWS ALB CreateListener TargetGroupNotFound Err](aws-alb-createlistener-targetgroupnotfound)
  • [AWS cloud troubleshooting: Fix Aws Alb Lambda 502 Bad Gateway Issue in AWS](aws-alb-lambda-502-bad-gateway)

<script type="application/ld+json"> { "@context": "https://schema.org", "@type": "TechArticle", "headline": "Fix AWS Lambda Cold Start Latency", "description": "Reduce Lambda cold start delays. Enable provisioned concurrency, optimize initialization, and implement SnapStart for Java functions.", "url": "https://www.fixwikihub.com/fix-aws-lambda-cold-start-latency", "publisher": { "@type": "Organization", "name": "FixWikiHub", "url": "https://www.fixwikihub.com" }, "author": { "@type": "Person", "name": "FixWikiHub Editorial Team" }, "datePublished": "2026-04-01T16:52:19.808Z", "dateModified": "2026-04-01T16:52:19.808Z" } </script>