---
cuppy_hub: aws
cuppy_path: patterns/lambda-to-rds.md
cuppy_section: docs
cuppy_doc: A444-3Z9F
cuppy_doc_uuid: 625cc847-b3f8-42ba-a7a8-1074c8a6d858
cuppy_permalink: https://cuppy.io/aws/d/A444-3Z9F
cuppy_version: 4
cuppy_updated: 2026-10-23T16:16:52.575Z
cuppy_canonical: https://cuppy.io/aws/docs/patterns/lambda-to-rds
cuppy_mcp: https://cuppy.io/mcp
cuppy_body_sha256: ea92a22b47f8ea799c91dc60d30ab46a54aaedb6b362876e23099764255568b6
# cuppy_body_sha256 is over the document body ALONE, excluding both generated blocks.
---


# Lambda to RDS or Aurora

**Attach the function to the database's VPC, let the database's (or proxy's) security group admit the function's security group, and put RDS Proxy between them.** Each concurrent Lambda environment holds its own connection, and Lambda can add up to 1,000 environments every 10 seconds per function, so bursts exhaust `max_connections` unless something pools them.

## What crosses the handoff

| Side | Provides / expects |
|---|---|
| **Lambda** | VPC config in the database's VPC (private subnets), the ENI permissions on its execution role, a security group allowing outbound traffic on the engine port. The DB client is created **outside the handler**, so warm invocations reuse the connection |
| **RDS Proxy** | In the same VPC, never public. Its security group admits the Lambda security group. It connects to the DB with Secrets Manager secrets or IAM auth, and can require IAM auth from clients |
| **Database** | Its security group admits the **proxy's** security group (or Lambda's if there is no proxy). Not publicly accessible |

## Known-good

1. Lambda → private subnets of the DB VPC, `lambda-sg` (egress to 5432/3306).
2. RDS Proxy → `proxy-sg`, inbound engine port from `lambda-sg`. Target: the DB instance or cluster. Auth to the DB from a Secrets Manager secret.
3. DB → `db-sg`, inbound from `proxy-sg` only.
4. Clients use IAM auth to the proxy. The execution role allows `rds-db:connect` on `arn:aws:rds-db:<region>:<account>:dbuser:<prx-id>/<db-user>`, using the proxy's resource ID. Generate the token with `@aws-sdk/rds-signer` against the **proxy endpoint** (`guides/rds/connect-securely.md`).
5. The handler opens the connection lazily, once per environment, reuses it, and reconnects on error.
6. If the function also calls AWS APIs or the internet: NAT or VPC endpoints, because a VPC-attached function has no internet access (`patterns/lambda-in-vpc.md`). Use a Secrets Manager endpoint if you read secrets at start-up.

## Known-bad

| Configuration | Symptom |
|---|---|
| Function not in the VPC, database private | Connection timeouts (`Task timed out after …`) |
| Database security group admits a CIDR, not the Lambda/proxy security group | Works in one subnet, times out from others |
| No proxy, bursty traffic | Errors about too many connections; `incompatible-parameters` if `max_connections` is raised too far |
| Connection opened inside the handler and never closed | Connection count climbs with concurrency, then refusals |
| IAM token generated against a custom DNS name or a cluster's reader alias in Route 53 | Authentication fails: use the RDS or proxy endpoint |
| `rds-db:connect` resource uses the instance ID while connecting through the proxy | Denied: use the proxy's `prx-…` ID |
| Large prepared statements or session settings through the proxy | Pinning: the proxy stops pooling those clients |
| Secret rotated, function caches the old password forever | Auth failures until cold start. Refresh on auth error |
| Function timeout shorter than the DB query plus connection set-up | Timeouts that look like network issues: log timings |

## Which side is wrong?

- **Timeout before any database error** → network: VPC attachment, security groups, subnets (`guides/vpc/diagnose-connection-timeout.md`).
- **Authentication error** → credentials: the token's endpoint and age, `rds-db:connect` resource ID, the DB user's grants (`reference/rds/errors.md`).
- **Works at low traffic, fails in bursts** → connections: add or size RDS Proxy, and reuse connections.


---
<!-- cuppy -->
You are reading one file. The same content is free over MCP at https://cuppy.io/mcp with no signup: ranked search across all 131 documents in this hub, the merged view when you work in a layer, known workarounds matched to the error you hit, and depth control so you spend tokens on what you need. Start with the `_hello` tool. How to connect: https://cuppy.io/aws/ Something wrong in this document? Report it with the `session feedback` tool on the same endpoint.
<!-- /cuppy -->
