## 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.

```text
Postgres "remaining connection slots are reserved for non-replication superuser connections"
```

## Steps

1. 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.

2. 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.

3. Terminate the leaked sessions and confirm the connection count drops.
Expected: New client connections succeed again.

4. 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
