# Fix AWS CloudWatch MaxConnectionsExceeded Error

You're seeing "MaxConnectionsExceeded" errors in CloudWatch or your application is failing to connect to your RDS database with "too many connections" errors. The database is rejecting new connections because the maximum limit has been reached.

This error indicates your application is opening more database connections than the instance can handle. Let's diagnose and fix this systematically.

Introduction

You are seeing "MaxConnectionsExceeded" errors in CloudWatch or your application is failing to connect to your RDS database with "too many connections" errors. The database is rejecting new connections because the maximum limit has been reached. This error indicates your application is opening more database connections than the instance can handle.

Symptoms

MaxConnectionsExceeded errors present with: - "MaxConnectionsExceeded" CloudWatch alarms - "too many connections" error messages - Application unable to open database connections - Connection pool exhaustion - Slow application response due to connection waiting - Database connection timeout errors - Connection leak warnings in logs

Diagnosis commands to investigate:

Check current connection count:

bash
aws cloudwatch get-metric-statistics \
  --namespace AWS/RDS \
  --metric-name DatabaseConnections \
  --dimensions DBInstanceIdentifier=my-database \
  --start-time $(date -u -d '1 hour ago' +%Y-%m-%dT%H:%M:%SZ) \
  --end-time $(date -u +%Y-%m-%dT%H:%M:%SZ) \
  --period 300 \
  --statistics Average,Maximum \
  --output table

Check the maximum connections for your instance class:

bash
aws rds describe-db-instances \
  --db-instance-identifier my-database \
  --query 'DBInstances[*].[DBInstanceClass,Engine,EngineVersion]'

Connect to the database and check active connections:

```bash # For PostgreSQL psql -h my-database.xxxxx.us-east-1.rds.amazonaws.com -U admin -d postgres -c " SELECT count(*) as total_connections, (SELECT setting::int FROM pg_settings WHERE name = 'max_connections') as max_connections; "

# For MySQL mysql -h my-database.xxxxx.us-east-1.rds.amazonaws.com -u admin -p -e " SHOW STATUS LIKE 'Threads_connected'; SHOW VARIABLES LIKE 'max_connections'; " ```

View connections by state:

```bash # PostgreSQL psql -h my-database.xxxxx.us-east-1.rds.amazonaws.com -U admin -d postgres -c " SELECT state, count(*) FROM pg_stat_activity GROUP BY state ORDER BY count DESC; "

# MySQL mysql -h my-database.xxxxx.us-east-1.rds.amazonaws.com -u admin -p -e " SHOW PROCESSLIST; " ```

Common Causes

  • Configuration misconfiguration
  • Missing or incorrect credentials
  • Network connectivity issues
  • Version compatibility problems
  • Resource exhaustion or limits
  • Permission or access denied

Step-by-Step Fix

  1. 1.Check logs for specific error messages
  2. 2.Verify configuration settings
  3. 3.Test network connectivity
  4. 4.Review recent changes
  5. 5.Apply corrective action
  6. 6.Verify the fix

Common Causes and Solutions

Cause 1: Connection Leaks in Application

Applications not properly closing connections lead to exhaustion.

Identify connection leaks:

bash
# PostgreSQL - Find long-idle connections
psql -h endpoint -U admin -d postgres -c "
SELECT pid, usename, application_name, client_addr,
       now() - pg_stat_activity.query_start AS duration,
       query, state
FROM pg_stat_activity
WHERE (now() - pg_stat_activity.query_start) > interval '5 minutes'
ORDER BY duration DESC;
"

Fix in your application code:

```python # WRONG - Connection leak def get_user(user_id): conn = psycopg2.connect(DATABASE_URL) cur = conn.cursor() cur.execute("SELECT * FROM users WHERE id = %s", (user_id,)) return cur.fetchone() # Connection never closed!

# CORRECT - Proper connection management def get_user(user_id): conn = psycopg2.connect(DATABASE_URL) try: cur = conn.cursor() cur.execute("SELECT * FROM users WHERE id = %s", (user_id,)) return cur.fetchone() finally: conn.close()

# BETTER - Use context manager def get_user(user_id): with psycopg2.connect(DATABASE_URL) as conn: with conn.cursor() as cur: cur.execute("SELECT * FROM users WHERE id = %s", (user_id,)) return cur.fetchone() ```

Cause 2: No Connection Pooling

Creating a new connection for every query is inefficient.

Implement connection pooling:

```python # Using psycopg2.pool from psycopg2 import pool

connection_pool = pool.ThreadedConnectionPool( minconn=5, maxconn=20, dsn=DATABASE_URL )

def get_connection(): return connection_pool.getconn()

def release_connection(conn): connection_pool.putconn(conn) ```

Use PgBouncer for PostgreSQL:

```bash # Install PgBouncer sudo apt-get install pgbouncer

# Configure /etc/pgbouncer/pgbouncer.ini [databases] mydb = host=my-database.xxxxx.us-east-1.rds.amazonaws.com port=5432 dbname=mydb

[pgbouncer] listen_addr = 0.0.0.0 listen_port = 6432 auth_type = md5 auth_file = /etc/pgbouncer/userlist.txt pool_mode = transaction max_client_conn = 1000 default_pool_size = 25 ```

Use RDS Proxy:

```bash aws rds create-db-proxy \ --db-proxy-name my-proxy \ --engine-family POSTGRESQL \ --auth AuthScheme=SECRETS,SecretArn=arn:aws:secretsmanager:us-east-1:123456789012:secret:my-secret \ --role-arn arn:aws:iam::123456789012:role/rds-proxy-role \ --vpc-subnet-ids subnet-1 subnet-2 subnet-3 \ --vpc-security-group-ids sg-12345678

aws rds register-db-proxy-targets \ --db-proxy-name my-proxy \ --db-instance-identifiers my-database ```

Cause 3: Instance Class Too Small

Each RDS instance class has a maximum connection limit.

Check current limits:

Instance ClassMax Connections (PostgreSQL)
db.t3.micro~85
db.t3.small~170
db.t3.medium~350
db.t3.large~700
db.r5.large~1,600
db.r5.xlarge~3,200

Scale up the instance:

bash
aws rds modify-db-instance \
  --db-instance-identifier my-database \
  --db-instance-class db.t3.large \
  --apply-immediately

Cause 4: Long-Running Transactions

Transactions that stay open consume connections.

Find long-running transactions:

```bash # PostgreSQL psql -h endpoint -U admin -d postgres -c " SELECT pid, now() - pg_stat_activity.query_start AS duration, query, state FROM pg_stat_activity WHERE state = 'idle in transaction' AND (now() - pg_stat_activity.query_start) > interval '5 minutes' ORDER BY duration DESC; "

# Terminate problematic connections psql -h endpoint -U admin -d postgres -c " SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE state = 'idle in transaction' AND (now() - pg_stat_activity.query_start) > interval '30 minutes'; " ```

Set idle transaction timeout:

```sql -- PostgreSQL ALTER SYSTEM SET idle_in_transaction_session_timeout = '300000'; -- 5 minutes SELECT pg_reload_conf();

-- MySQL SET GLOBAL wait_timeout = 300; SET GLOBAL interactive_timeout = 300; ```

Cause 5: Too Many Application Instances

Auto-scaling may create more instances than connections allow.

Calculate connection budget:

``` Total connections needed = (instances × connections_per_instance) + buffer

Example: - 10 EC2 instances - 10 connections each - 20% buffer = 10 × 10 × 1.2 = 120 connections minimum ```

Configure connection limits per instance:

python
# In your application config
DATABASE_POOL_SIZE = 5  # Per instance
DATABASE_MAX_OVERFLOW = 2

Cause 6: Improper Pool Configuration

Connection pools configured too large.

Right-size your pool:

```python # Formula: connections = ((core_count * 2) + effective_spindle_count)

# For a t3.medium (2 vCPU, 1 EBS volume): # connections = (2 * 2) + 1 = 5 connections per instance

# In SQLAlchemy engine = create_engine( DATABASE_URL, pool_size=5, max_overflow=2, pool_timeout=30, pool_recycle=1800 ) ```

Verification

After implementing fixes, verify connection management:

```bash # Monitor connections over time watch -n 5 'aws cloudwatch get-metric-statistics \ --namespace AWS/RDS \ --metric-name DatabaseConnections \ --dimensions DBInstanceIdentifier=my-database \ --start-time $(date -u -d "10 minutes ago" +%Y-%m-%dT%H:%M:%SZ) \ --end-time $(date -u +%Y-%m-%dT%H:%M:%SZ) \ --period 60 \ --statistics Maximum'

# Set up CloudWatch alarm aws cloudwatch put-metric-alarm \ --alarm-name rds-connections-high \ --alarm-description "RDS connections approaching limit" \ --namespace AWS/RDS \ --metric-name DatabaseConnections \ --dimensions DBInstanceIdentifier=my-database \ --statistic Average \ --period 300 \ --threshold 80 \ --comparison-operator GreaterThanOrEqualToThreshold \ --evaluation-periods 2 \ --alarm-actions arn:aws:sns:us-east-1:123456789012:alerts ```

Test connection pooling:

```python import psycopg2 from psycopg2 import pool import threading

# Create connection pool pool = pool.ThreadedConnectionPool( minconn=5, maxconn=20, dsn=DATABASE_URL )

def query_database(thread_id): conn = pool.getconn() try: cur = conn.cursor() cur.execute("SELECT pg_backend_pid()") pid = cur.fetchone()[0] print(f"Thread {thread_id}: Connection PID {pid}") finally: pool.putconn(conn)

# Test with multiple threads threads = [] for i in range(10): t = threading.Thread(target=query_database, args=(i,)) threads.append(t) t.start()

for t in threads: t.join()

print("Connection pool test completed successfully") ```

  • [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 CloudWatch MaxConnectionsExceeded Error", "description": "Step-by-step guide to fix MaxConnectionsExceeded errors in AWS. Resolve RDS connection limits, implement connection pooling, and prevent connection exhaustion.", "url": "https://www.fixwikihub.com/fix-aws-cloudwatch-maxconnectionsexceeded", "publisher": { "@type": "Organization", "name": "FixWikiHub", "url": "https://www.fixwikihub.com" }, "author": { "@type": "Person", "name": "FixWikiHub Editorial Team" }, "datePublished": "2026-04-27T10:03:00.000Z", "dateModified": "2026-04-27T10:03:00.000Z" } </script>