Why Lambda hits that 3-second wall when talking to RDS
You've got a Lambda function that connects to an RDS database. Locally, it works. In the cloud, it dies with Task timed out after 3.00 seconds. The 3.00 seconds is just the default timeout — the real problem is that your Lambda can't reach the database at all. What's actually happening is the function is stuck waiting for a TCP connection that never completes. Most of the time, it's a VPC networking misconfiguration. Let's walk through it, easiest fix first.
30-second fix: Check if your Lambda is even in the right VPC
If your RDS instance is in a VPC (and it almost always is), your Lambda must be in the same VPC, or in a peered VPC with proper routing. If your Lambda isn't attached to any VPC, it runs in the default AWS-managed VPC and can't reach private RDS endpoints. The fix: attach the Lambda to the same VPC and subnets as your RDS instance.
- Open the Lambda console.
- Go to Configuration > VPC.
- Select the VPC that contains your RDS instance.
- Choose at least two subnets in different Availability Zones (for high availability).
- Attach a security group that allows outbound traffic to your RDS security group.
If your Lambda was already in the correct VPC, skip to the next section.
5-minute fix: Security groups and subnet routing
Two common culprits here: security groups and route tables.
Security group rules
Your Lambda's security group must allow outbound traffic on the database port (e.g., 3306 for MySQL, 5432 for PostgreSQL) to the RDS security group. And the RDS security group must allow inbound traffic from the Lambda's security group on that same port. Don't rely on CIDR blocks — use security group references. It's more secure and survives IP changes.
Check both:
- Lambda SG outbound: allow TCP to RDS SG on port 3306/5432.
- RDS SG inbound: allow TCP from Lambda SG on port 3306/5432.
If you changed rules, wait 30 seconds and test again.
Subnet route tables
If your Lambda is in a private subnet (which it should be), that subnet's route table must have a route to the RDS instance. If RDS is in the same VPC, the local route (10.0.0.0/16 or whatever your CIDR is) handles it. But if RDS is in a peered VPC or on-premises via VPN/Direct Connect, you need explicit routes. Also, if your Lambda needs internet access (e.g., to call an external API), private subnets need a NAT Gateway. Without NAT, outbound internet fails silently, and your function times out.
Check your subnet's route table:
aws ec2 describe-route-tables --filters "Name=association.subnet-id,Values=subnet-12345678"
Look for a route to 0.0.0.0/0 pointing to a NAT Gateway (for internet) or a route to your RDS CIDR pointing to a peering connection or transit gateway.
15-minute deep dive: Lambda ENIs, DNS, and RDS Proxy
Still timing out? Time to dig deeper.
Lambda ENI cold start
When you attach a Lambda to a VPC, AWS creates an Elastic Network Interface (ENI) in your subnet. On the first invocation after a deployment or long idle period, this ENI creation adds latency — sometimes several seconds. If your Lambda timeout is 3 seconds, the ENI setup alone can eat that. Increase your Lambda timeout to at least 10 seconds, then test. If it works, the issue was cold start ENI creation. You can also provision concurrency to keep ENIs warm.
DNS resolution
Lambda in a VPC uses the VPC's DNS settings. If you disabled DNS hostnames or DNS resolution in your VPC, RDS endpoint resolution fails. Check your VPC settings: both DNS resolution and DNS hostnames should be enabled. Also, if you're using a custom DHCP option set, make sure it points to AmazonProvidedDNS or a working DNS server.
RDS Proxy
If your Lambda makes many short-lived connections, you might be exhausting RDS connection limits. That can cause timeouts. RDS Proxy pools and shares database connections, reducing overhead. It's not a quick fix, but it's the right long-term solution for serverless workloads. Set it up, point your Lambda to the proxy endpoint, and you'll likely see timeouts disappear.
VPC Flow Logs
Enable VPC Flow Logs on the Lambda's ENI and the RDS ENI. Look for REJECT entries. That tells you exactly which traffic is being blocked and where.
aws ec2 create-flow-logs --resource-type NetworkInterface --resource-ids eni-1234567890abcdef0 --traffic-type ALL --log-destination-type cloud-watch-logs --log-group-name MyFlowLogs
Check the logs after a failed invocation. If you see rejects on port 3306 from your Lambda's IP to RDS, it's a security group or NACL issue.
What most people miss
The 3-second timeout is often just the default. If your Lambda is doing real work, 3 seconds is too short anyway. Bump it to 30 seconds or more while you debug. That gives you room to see the actual error. Also, don't put your Lambda in a public subnet and expect it to reach RDS privately — it won't, unless you've set up routing and security groups correctly. And remember: if your Lambda needs both VPC access and internet access, it must be in a private subnet with a NAT Gateway. There's no way around that.
Quick checklist
- Lambda in same VPC as RDS? (Yes/No)
- Lambda subnets have route to RDS? (Check route tables)
- Security groups allow traffic on DB port? (Inbound/Outbound)
- Lambda timeout > 3 seconds? (Set to 10+ for testing)
- VPC DNS resolution enabled? (Yes/No)
- NAT Gateway for internet access? (If needed)
Work through these in order. You'll find the culprit. Nine times out of ten, it's a security group or a missing route. The other time, it's the ENI cold start or DNS.