Introduction

RDS does not fail gradually when connection demand outruns the configured limit. Once max_connections is exhausted, new application requests start failing with database connection errors even if CPU and storage still look healthy. In most incidents, the durable fix is not just raising the limit. You need to find why connections are piling up in the first place.

Symptoms

  • Applications return too many connections or connection refused errors
  • CloudWatch DatabaseConnections stays pinned near the RDS limit
  • Connection pools time out even though the database instance is still running
  • Idle or sleeping sessions accumulate faster than they are released

Common Causes

  • The application opens more concurrent connections than the database tier can sustain
  • Idle sessions are never returned to the pool or never closed
  • Connection spikes follow deploys, autoscaling, or worker fan-out events
  • The database has no pooling layer such as RDS Proxy or PgBouncer

Step-by-Step Fix

  1. 1.Measure current connection usage by state
  2. 2.Start by separating active queries from idle sessions so you know whether the pressure is real workload or connection leakage.
sql
SELECT count(*) FROM pg_stat_activity;
SELECT state, count(*) FROM pg_stat_activity GROUP BY state;
  1. 1.Identify long-idle or stuck sessions
  2. 2.If the majority of sessions are idle, the application or worker pool is likely leaking connections rather than needing a bigger database limit.
sql
SELECT pid, usename, application_name, state, state_change
FROM pg_stat_activity
ORDER BY state_change ASC;
  1. 1.Add or fix connection pooling before raising limits
  2. 2.RDS Proxy, PgBouncer, or an application-side pool usually helps more than simply increasing max_connections.
bash
aws rds create-db-proxy \
  --db-proxy-name my-proxy \
  --engine-family POSTGRESQL \
  --role-arn arn:aws:iam::123456789012:role/RDSProxyRole
  1. 1.**Tune max_connections only after the session pattern is understood**
  2. 2.If the workload is legitimate and the instance has headroom, adjust the parameter group carefully and account for memory impact.
bash
aws rds modify-db-parameter-group \
  --db-parameter-group-name my-param-group \
  --parameters "ParameterName=max_connections,ParameterValue=500,ApplyMethod=pending-reboot"

Prevention

  • Size application pools against the database limit instead of letting every worker open unbounded sessions
  • Monitor DatabaseConnections and idle session growth together
  • Use connection pooling for bursty web and job workloads
  • Review connection behavior after deploys, queue worker scaling, and traffic surges