RDS max_connections reached — apps rejected
Apps error with 'too many connections' from the DB client
Focused incident mode — strips away everything but this runbook.
Symptoms
- Apps error with 'too many connections' from the DB client
- RDS CloudWatch DatabaseConnections saturates at the limit
- Connection poolers report exhausted pools
max_connections is memory-bound on RDS: raising it past the instance's memory kills idle connections and starves the buffer cache. Prefer a connection pooler (RDS Proxy) over a raw bump.
Evidence to grab
Collect these artifacts before you change anything — they prove (or rule out) each cause.
Current connection count
aws cloudwatch get-metric-statistics --namespace AWS/RDS --metric-name DatabaseConnections --dimensions Name=DBInstanceIdentifier,Value=<DB-ID> --start-time <ISO> --end-time <ISO> --period 60 --statistics MaximumConfigured max_connections
aws rds describe-db-parameters --db-parameter-group-name <PG-NAME> --query 'Parameters[?ParameterName==`max_connections`]'
Diagnostic flow
Run the steps in order, marking each claim confirmed or refuted. The evidence you gather feeds the ranked causes below.
Guided decision tree is ready.
Steps with commands, expected output, and pass/fail branches.
Ranked root causes
Evidence checklist
- DatabaseConnections climbs monotonically between restarts
- SHOW PROCESSLIST/pg_stat_activity shows many idle sessions
Confirm before fixing
aws ssm start-session --target <BASTION-INSTANCE-ID>Check idle sessions; e.g. mysql: SHOW PROCESSLIST; postgres: SELECT state,count(*) FROM pg_stat_activity GROUP BY state
Fix
aws ssm start-session --target <BASTION-INSTANCE-ID>Kill idle sessions (KILL <id> / pg_terminate_backend) after confirming the app change
Resolution runbook
Apply from top to bottom after the cause is confirmed. Review every command before running it — risk tags are shown on each.
aws rds describe-db-parameters --db-parameter-group-name <PG-NAME> --query 'Parameters[?ParameterName==`max_connections`]'Know the limit
aws cloudwatch get-metric-statistics --namespace AWS/RDS --metric-name DatabaseConnections --dimensions Name=DBInstanceIdentifier,Value=<DB-ID> --start-time $(date -u -d '-30 minutes' +%Y-%m-%dT%H:%M:%SZ) --end-time $(date -u +%Y-%m-%dT%H:%M:%SZ) --period 60 --statistics MaximumKnow the demand
aws rds modify-db-parameter-group --db-parameter-group-name <PG-NAME> --parameters ParameterName=max_connections,ParameterValue=<NEW-VALUE>,ApplyMethod=pending-rebootRaise the ceiling
aws rds reboot-db-instance --db-instance-identifier <DB-ID>Apply the parameter change (planned window if possible)
Prevention
- Put every app behind RDS Proxy or an in-app pool with sane max idle.
- Alert on DatabaseConnections > 80% of max_connections.
- Step DB size up with fleet growth so max_connections tracks demand automatically.
Related runbooks
Same stack, same failure family — worth a skim.
Commands marked READ CHANGE DESTRUCTIVE — never run DESTRUCTIVE commands against production data you cannot restore. Copy → verify → execute.