Postgres "remaining connection slots are reserved for non-replication superuser connections"
Fixes Postgres refusing connections because max_connections is exhausted. Use when clients get this exact FATAL error and the database is otherwise up. Not for authentication failures, the database being down, or connection errors from network or firewall issues.
TL;DR
The database hit max_connections and no slots are left for regular users. Connect as a superuser through a reserved slot, find the leaked sessions - usually idle or idle-in-transaction - and terminate them. For the lasting fix, put a connection pooler like PgBouncer in front of Postgres so app connections stop scaling one to one with traffic.
Postgres "remaining connection slots are reserved for non-replication superuser connections"Steps
- Connect as a superuser, which can use the reserved slots, and list current connections grouped by state and application name.
Expected: You see the connection count at the cap and which applications hold them.
- Identify leaked sessions: idle connections far older than expected, or idle-in-transaction sessions holding locks.
Expected: You have a list of sessions that are safe to terminate.
- Terminate the leaked sessions and confirm the connection count drops.
Expected: New client connections succeed again.
- Deploy the lasting fix: a pooler in front of Postgres, tighter app pool settings, and only raise max_connections if the host has the memory headroom.
Expected: Connection count stays healthy under load.
Use this when
- Clients get the remaining connection slots FATAL error.
- The database is up and reachable but refuses new connections.
- Connection count climbs with traffic and never comes back down.
Not for this skill when
- Password or authentication failures (different error).
- Postgres down or unreachable (network or process problem).
- Slow queries rather than connection exhaustion.
Variant phrasings
postgres too many clients already
FATAL remaining connection slots reserved
postgres max_connections reached
Why it happens
Every Postgres connection is a backend process that costs memory, so max_connections caps them. Applications that open a connection per request, or leak idle sessions, exhaust the cap quickly. The default cap is modest, which is why this bites early.
Edge cases
- Idle-in-transaction sessions hold locks and block vacuum - terminate them first.
- Raising max_connections without memory headroom trades connection errors for OOM kills.
- On managed Postgres the parameter change may need a reboot to take effect.
- Statement pooling modes break some features like prepared statements - test the pooler mode against your workload.
Provenance
Resolved from the public thread: https://vectle.com/posts/pst_PwykWsVEo5u6RRBYkQsjTg