Database Deadlocks, Connection Pool Exhaustion, and Prepared Statements on RDS
Quick summary: Too many "too many connections" pages are fixed by raising max_connections—which trades one outage for OOM on the writer. This guide traces deadlocks, pool sizing, RDS Proxy, and prepared statement caching on Aurora.
Key Takeaways
- This guide traces deadlocks, pool sizing, RDS Proxy, and prepared statement caching on Aurora
- June 2026: Aurora PostgreSQL scales with instance class—not with your microservice count
- A fleet of 80 ECS tasks × pool size 20 = 1,600 client slots fighting a ~5,000 ceiling on , before autovacuum and admin connections consume headroom
- Field note — Logistics SaaS (~$18k/mo Aurora): p99 API 5
- 2 s during deploy; showed 4,800 connections, mostly from a leaked ORM session
Table of Contents
June 2026: Aurora PostgreSQL max_connections scales with instance class—not with your microservice count. A fleet of 80 ECS tasks × pool size 20 = 1,600 client slots fighting a ~5,000 ceiling on db.r6g.xlarge, before autovacuum and admin connections consume headroom.
Field note — Logistics SaaS (~$18k/mo Aurora): p99 API 5.2 s during deploy;
pg_stat_activityshowed 4,800 connections, mostlyidle in transactionfrom a leaked ORM session. RDS Proxy + pool cap 15/task dropped connections to 620; p99 220 ms. Use RDS max connection calculator.
Deadlock detection
PostgreSQL logs deadlock detected with cycle details. Fix lock order (always lock parent row before child), shorten transactions, avoid user prompts inside transactions.
Connection pool exhaustion
| Cause | Signal | Fix |
|---|---|---|
| Pool > DB max | FATAL: too many connections | RDS Proxy; reduce per-task pool |
| Idle in transaction | idle in transaction in pg_stat_activity | Timeouts; code review |
| Thundering herd deploy | Spike on rollout | Staggered deploy; Proxy borrow timeout |
| Lambda per invoke connect | Connection storm | Proxy + Data API for light queries |
Prepared statements
Use for hot queries; watch RDS Proxy pinning—session-level prepared statements may not multiplex identically to transaction pooling.
AWS services map
| Control | Service |
|---|---|
| Multiplexing | RDS Proxy |
| Connection math | Performance Insights + max_connections |
| Break-glass scale | Aurora Serverless v2 ACU bump (not a pool substitute) |
When this advice breaks
- Aurora Limitless — shard-aware pooling differs; consult shard router docs.
- Single long-running ETL — dedicated connection, not app pool.
What to do this week
- Graph
DatabaseConnectionsvsmax_connectionson writer. - Deploy RDS Proxy if >20 clients connect independently.
- Set
idle_in_transaction_session_timeout(e.g. 60s) in parameter group. - Enable Performance Insights wait events
Lock:deadlockandClient:ClientRead.
What this guide doesn’t cover
Read replica lag and failover—see canonical RDS vs Aurora guides.
AWS Cloud Architect & AI Expert
AWS-certified cloud architect and AI expert with deep expertise in cloud migrations, cost optimization, and generative AI on AWS.