Introduction
PostgreSQL and MySQL have a maximum number of concurrent connections defined by the max_connections parameter. When this limit is reached, new connection attempts are rejected. In RDS, the default max_connections is based on instance class, and hitting this limit means your application can't connect to the database.
Symptoms
For PostgreSQL:
FATAL: remaining connection slots are reserved for non-replication superuser connectionsOr:
FATAL: sorry, too many clients alreadyFor MySQL:
ERROR 1040 (HY000): Too many connectionsApplication logs:
org.postgresql.util.PSQLException: FATAL: sorry, too many clients already
java.sql.SQLTransientConnectionException: HikariPool - Connection is not availableCommon Causes
- 1.Connection leaks - Application doesn't close connections properly
- 2.Insufficient pooling - Each request opens a new connection
- 3.Long-running transactions - Connections held for extended periods
- 4.Instance class limits - Default max_connections too low for workload
- 5.Zombie connections - Aborted connections not cleaned up
- 6.Connection storms - Sudden spike in concurrent requests
- 7.Connection timeout misconfiguration - Connections held while waiting
Step-by-Step Fix
- 1.Check logs for specific error messages
- 2.Verify configuration settings
- 3.Test network connectivity
- 4.Review recent changes
- 5.Apply corrective action
- 6.Verify the fix
Step 1: Check Current Connection Count
For PostgreSQL:
SELECT count(*) FROM pg_stat_activity;
SELECT max_conn, used, res_for_super, max_conn - used - res_for_super
FROM pg_settings max_conn, (SELECT count(*) used FROM pg_stat_activity) s,
(SELECT setting::int res_for_super FROM pg_settings WHERE name='superuser_reserved_connections') r;For MySQL:
SHOW STATUS LIKE 'Threads_connected';
SHOW VARIABLES LIKE 'max_connections';
SHOW PROCESSLIST;Step 2: Identify What's Using Connections
PostgreSQL - Find top connection sources:
SELECT client_addr, usename, application_name, state, count(*)
FROM pg_stat_activity
GROUP BY client_addr, usename, application_name, state
ORDER BY count(*) DESC;Find long-idle connections:
SELECT pid, usename, application_name, client_addr, state,
now() - state_change AS idle_duration
FROM pg_stat_activity
WHERE state = 'idle'
ORDER BY idle_duration DESC;MySQL - Find connection sources:
SELECT USER, HOST, DB, COMMAND, TIME, STATE, INFO
FROM INFORMATION_SCHEMA.PROCESSLIST
ORDER BY TIME DESC;Step 3: Kill Idle or Problem Connections
PostgreSQL:
```sql -- Terminate specific connection SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE pid = 12345;
-- Terminate all idle connections older than 10 minutes SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE state = 'idle' AND query_start < now() - interval '10 minutes'; ```
MySQL:
```sql -- Kill specific connection KILL CONNECTION 12345;
-- Find and kill long-running queries SELECT CONCAT('KILL ', id, ';') FROM INFORMATION_SCHEMA.PROCESSLIST WHERE TIME > 300 AND COMMAND != 'Sleep'; ```
Step 4: Check for Connection Leaks
Application-level causes:
```python # BAD: Connection leak def get_user(user_id): conn = get_db_connection() cursor = conn.cursor() cursor.execute("SELECT * FROM users WHERE id = %s", (user_id,)) return cursor.fetchone() # conn.close() is never called!
# GOOD: Using context manager def get_user(user_id): with get_db_connection() as conn: with conn.cursor() as cursor: cursor.execute("SELECT * FROM users WHERE id = %s", (user_id,)) return cursor.fetchone() ```
Enable connection tracking in your application to find leaks:
```python import traceback import weakref
connections = weakref.WeakSet()
def get_db_connection(): conn = create_connection() connections.add(conn) print(f"Connection created. Stack:\n{''.join(traceback.format_stack())}") return conn ```
Step 5: Implement Connection Pooling
Use a connection pooler like PgBouncer or ProxySQL:
For RDS, enable RDS Proxy:
aws rds create-db-proxy \
--db-proxy-name my-proxy \
--engine-family POSTGRESQL \
--auth AuthScheme=SECRETS,SecretArn=arn:aws:secretsmanager:region:account:secret:my-secret \
--role-arn arn:aws:iam::account:role/rds-proxy-role \
--vpc-subnet-ids subnet-1 subnet-2 \
--vpc-security-group-ids sg-1Or use application-level pooling (HikariCP, pgx pool):
# application.yml for HikariCP
spring:
datasource:
hikari:
maximum-pool-size: 20
minimum-idle: 5
idle-timeout: 300000
connection-timeout: 30000
max-lifetime: 1200000Step 6: Increase max_connections (If Needed)
Check current limit:
aws rds describe-db-instances --db-instance-identifier my-db \
--query 'DBInstances[*].[DBInstanceClass,AllocatedStorage]'Default max_connections by instance class (PostgreSQL):
| Instance Class | max_connections |
|---|---|
| db.t3.micro | 87 |
| db.t3.small | 192 |
| db.t3.medium | 412 |
| db.r5.large | 850 |
| db.r5.xlarge | 1700 |
To modify:
aws rds modify-db-parameter-group \
--db-parameter-group-name my-param-group \
--parameters "ParameterName=max_connections,ParameterValue=500,ApplyMethod=pending-reboot"Then reboot the instance:
aws rds reboot-db-instance --db-instance-identifier my-dbWarning: Increasing max_connections without increasing instance size may cause memory exhaustion.
Step 7: Set Up Connection Monitoring
CloudWatch metric for connection count:
aws cloudwatch put-metric-alarm \
--alarm-name "rds-connections-high" \
--metric-name DatabaseConnections \
--namespace AWS/RDS \
--dimensions DBInstanceIdentifier=my-db \
--statistic Average \
--period 300 \
--threshold 400 \
--comparison-operator GreaterThanThreshold \
--evaluation-periods 2 \
--alarm-actions arn:aws:sns:region:account:alertsVerification
```bash # Check connection count aws cloudwatch get-metric-statistics \ --namespace AWS/RDS \ --metric-name DatabaseConnections \ --dimensions DBInstanceIdentifier=my-db \ --start-time $(date -u -d '1 hour ago' +%Y-%m-%dT%H:%M:%S) \ --end-time $(date -u +%Y-%m-%dT%H:%M:%S) \ --period 300 \ --statistics Average,Maximum
# Should show connections well below max_connections ```
Related Issues
- [Fix AWS RDS CPU Utilization High](/articles/fix-aws-rds-cpu-utilization-high)
- [Fix AWS RDS Storage Full](/articles/fix-aws-rds-storage-full)
- [Fix AWS RDS Slow Query Performance](/articles/fix-aws-rds-slow-query-performance)
Related Articles
- [AWS troubleshooting: Fix IAM Permission Denied - Complete Tro](fix-iam-permission-denied)
- [AWS cloud troubleshooting: AWS ACM Certificate Pending Validation Because the](aws-acm-certificate-pending-validation-wrong-route53-zone)
- [AWS cloud troubleshooting: AWS ALB Returns 502 Because the Target Closed the ](aws-alb-502-target-closed-connection-keepalive-timeout-mismatch)
- [AWS cloud troubleshooting: Fix AWS ALB CreateListener TargetGroupNotFound Err](aws-alb-createlistener-targetgroupnotfound)
- [AWS cloud troubleshooting: Fix Aws Alb Lambda 502 Bad Gateway Issue in AWS](aws-alb-lambda-502-bad-gateway)
<script type="application/ld+json"> { "@context": "https://schema.org", "@type": "TechArticle", "headline": "Fix AWS RDS Connection Limit Exceeded Error", "description": "Troubleshoot RDS connection limit errors. Find connection leaks, tune max_connections, implement pooling, and monitor connection metrics.", "url": "https://www.fixwikihub.com/fix-aws-rds-connection-limit-exceeded", "publisher": { "@type": "Organization", "name": "FixWikiHub", "url": "https://www.fixwikihub.com" }, "author": { "@type": "Person", "name": "FixWikiHub Editorial Team" }, "datePublished": "2026-03-31T19:23:06.347Z", "dateModified": "2026-03-31T19:23:06.347Z" } </script>