AWS `FATAL: remaining connection slots are reserved`: What It Means and How to Fix It
FATAL: remaining connection slots are reserved is a PostgreSQL instance at its connection ceiling — usually a pooling problem rather than a load problem. It comes from RDS, and the message reads:
FATAL: remaining connection slots are reserved for non-replication superuser connections
If you are here mid-incident, skip to how to tell which cause you have — the command there narrows it down faster than reading the list.
Quick reference
| Error | FATAL: remaining connection slots are reserved |
| Service | RDS |
| Message | FATAL: remaining connection slots are reserved for non-replication superuser connections |
| Most common cause | Lambda concurrency multiplied by connections per invocation |
What it actually means
PostgreSQL uses a process per connection, so max_connections is a hard ceiling with real memory behind it. When it is reached, PostgreSQL keeps a few slots back for superusers so an administrator can still get in and fix things — and everyone else gets this error.
On RDS for PostgreSQL, max_connections defaults to LEAST({DBInstanceClassMemory/9531392}, 5000) — memory divided by roughly 9.5 MB per connection, capped at 5,000. Small instances therefore have a surprisingly small ceiling, and it scales with the instance class rather than with anything you configured.
Do not estimate it. Ask the instance:
SHOW max_connections;
The important reframing: this is rarely too much traffic. It is usually too many idle connections held open by too many clients.
Why it happens
Ranked by how often each one turns out to be the answer.
| # | Cause | Fix |
|---|---|---|
| 1 | Lambda concurrency multiplied by connections per invocation | Each concurrent execution opens its own connection and holds it for the container lifetime. A hundred concurrent Lambdas is a hundred connections, and none of them are pooling with each other. RDS Proxy exists precisely for this. |
| 2 | Application pools sized per instance, not per cluster | Twenty pods each with a pool of 20 is 400 connections. Size the pool as ceiling / replicas, not as a comfortable per-process number. |
| 3 | Connections leaked by unclosed transactions | Sessions sitting in idle in transaction hold both a slot and locks. Look for them first — they are the most damaging kind. |
| 4 | A too-small instance class | The formula ties max_connections to memory. Scaling up raises it, but so does pooling, at a fraction of the cost. |
| 5 | Monitoring or migration tools opening extra connections | Easy to forget in the budget. |
How to tell which one you have
-- What is the ceiling, and where are we?
SHOW max_connections;
SELECT count(*) FROM pg_stat_activity;
-- Who is holding connections, and in what state?
SELECT usename, application_name, client_addr, state, count(*)
FROM pg_stat_activity
GROUP BY 1,2,3,4 ORDER BY count DESC;
-- Idle in transaction is the dangerous state.
SELECT pid, usename, state, now() - state_change AS duration, left(query, 60)
FROM pg_stat_activity
WHERE state = 'idle in transaction'
ORDER BY duration DESC;
# From outside: the CloudWatch metric
aws cloudwatch get-metric-statistics --namespace AWS/RDS \
--metric-name DatabaseConnections \
--dimensions Name=DBInstanceIdentifier,Value=my-db \
--start-time "$(date -u -d '6 hours ago' +%Y-%m-%dT%H:%M:%SZ)" \
--end-time "$(date -u +%Y-%m-%dT%H:%M:%SZ)" --period 300 --statistics Maximum
Preventing it
Put RDS Proxy in front of anything with variable concurrency, and Lambda especially. It multiplexes many client connections onto few database connections and survives failovers without the application noticing.
Set idle_in_transaction_session_timeout so leaked transactions clean themselves up rather than accumulating until the ceiling. Alarm on DatabaseConnections at 80% of max_connections — the metric is there, and the alarm turns a 3am outage into a Tuesday afternoon ticket.
Related errors
ThrottlingException / RequestLimitExceeded— All AWS APIsTask timed out after N seconds— Lambda- All AWS error references — the full index
Quota codes, limits and behaviour on this page were last checked against AWS documentation on 2026-08-22. AWS changes these; if something here does not match what you are seeing, trust the console and tell us.