Quick answer
For advanced users: if your Lambda function times out because it's in a VPC, the fastest fix is to attach the function to a VPC that uses a Hyperplane ENI (which AWS does automatically for most setups now) and then enable provisioned concurrency to keep ENIs warm. If that's not enough, move the function out of the VPC and access the private resources via a VPC endpoint or a proxy.
Why this happens
When you attach a Lambda function to a VPC, AWS has to create an Elastic Network Interface (ENI) in your subnets before the function can run. That's not a fast operation—it can take 5 to 15 seconds, sometimes longer. During that time, your function is stuck in the "pending" state, and if your lambda timeout is set to 3 seconds (the default), it times out immediately. Even if you set the timeout to 30 seconds, every cold start after a period of inactivity will still eat up those seconds.
The classic scenario: you have a Lambda function that queries an RDS database in a private subnet. It works fine when you test it, but after a few minutes of no traffic, the next invocation times out. That's the cold start ENI dance.
The real problem isn't the VPC itself—it's the ENI creation. AWS has improved this with Hyperplane ENIs (which are shared, so warm-up is faster), but you still pay the penalty on the first call after a scale-down.
Step-by-step fix
- Check your current timeout and VPC config.
Go to the Lambda console, open your function, and look at the "General configuration" tab. Note the timeout setting. Then check the "VPC" section—are you attached to a VPC? If yes, which subnets and security groups? - Raise the timeout temporarily (optional but helpful for testing).
Set the timeout to 30 seconds so you can see how long the cold start actually takes. After the fix, you can lower it back. Expected outcome: after saving, the function will run again, but you'll see a long duration on the first invocation. - Check if you're using Hyperplane ENIs.
If your function uses a VPC with at least 2 subnets (AWS recommends at least 2 AZs), Lambda uses Hyperplane. That's good. If you're on an older setup with a single subnet, you might be on classic ENIs—still slower. The fix is to move to at least 2 subnets in different AZs. How to check: In the VPC config section, see how many subnets are listed. If it's one, edit and add another. - Enable provisioned concurrency.
This is the big one. In the Lambda console, go to "Versions" and publish a version of your function (if you haven't already). Then go to "Provisioned concurrency" and set a count (e.g., 1 or 2). This tells AWS to initialize the function in advance, so the ENI is already attached when a request comes in. Expected outcome: after you enable it, the function will have a "Provisioned" status, and cold starts will be near zero for the first few invocations. - Test again.
Invoke the function a few times, wait a few minutes, and invoke again. The duration should stay low (under 1 second) instead of jumping to 10+ seconds. - If still timing out, check your security group rules.
A common hidden cause: your security group blocks outbound traffic to the internet (if you're using a NAT gateway) or to the RDS database. A timeout isn't always ENI latency—sometimes it's a network path issue. Use VPC flow logs to see if packets are being dropped. But for ENI latency, the above steps fix it.
Alternative fixes if the main one doesn't work
- Move the Lambda out of the VPC. If you don't need to access resources that are only in the VPC (like RDS or Elasticache), just remove the VPC config. That eliminates ENI setup entirely. You'll get cold starts of 200–500ms, which is nothing. If you do need RDS, use a VPC endpoint or a proxy like RDS Proxy to keep the Lambda out of the VPC but still talk to the database.
- Use a Lambda layer or a custom runtime. Some people find that using a custom runtime (like provided.al2) reduces cold start time because the environment is lighter. It won't fix ENI latency, but it shaves off a few hundred ms. Not the root cause, but every bit helps.
- Use a scheduled warm-up. A CloudWatch Event rule that invokes your function every 3–5 minutes keeps the ENI warm. It's a hack, and you'll pay for those invocations, but it works if you can't use provisioned concurrency (e.g., for cost reasons).
- Switch to container images. If you package your Lambda as a container, you still get the same ENI behavior. So this doesn't fix the problem—skip it.
Prevention tip
Set up provisioned concurrency on the versions that handle production traffic. Don't enable it on every version—that gets expensive. The sweet spot is 1 or 2 for a low-traffic app. For a high-traffic app, you might need more, but start small and monitor. Also, make sure your subnets have enough IP addresses—if they run out, Lambda can't create ENIs, and you'll get a different error (ENILimitReached or similar). Keep a subnet mask of /24 or larger for each AZ used.
Finally, if you're building new functions, design them to be VPC-free when possible. Use RDS Proxy for databases, and use VPC endpoints for services like S3 or DynamoDB. That way, you avoid the ENI problem entirely. It's more work upfront, but saves you headaches later.