PG
PRO
53300FATALTier 2 — Caution✅ HIGH confidence

remaining connection slots are reserved for non-replication superuser connections

Category: Too Many ConnectionsVersions: All Postgres versions

What this means

The connection limit has been reached. Postgres reserves a small number of connection slots exclusively for superusers (controlled by superuser_reserved_connections, default 3). Non-superuser clients receive this error when max_connections minus the reserved slots are all occupied.

Why it happens

  1. 1Application connection pool misconfiguration: too many connections created relative to max_connections
  2. 2Connection leak: application code opens connections but does not close them
  3. 3max_connections is set too low for the workload
  4. 4Idle connections accumulating (idle_in_transaction sessions not timing out)

How to reproduce

A non-superuser connection attempt when all non-reserved slots are occupied.

trigger — this will ERROR
-- Check current connection state:
SELECT count(*) AS total,
       sum(CASE WHEN state = 'idle' THEN 1 ELSE 0 END) AS idle,
       sum(CASE WHEN state = 'idle in transaction' THEN 1 ELSE 0 END) AS idle_in_txn
FROM pg_stat_activity
WHERE pid <> pg_backend_pid();

SHOW max_connections;
SHOW superuser_reserved_connections;
FATAL: remaining connection slots are reserved for non-replication superuser connections

Fix 1: Use a connection pooler (PgBouncer)

When many application processes each open their own connections to Postgres.

fix
-- PgBouncer sits between the application and Postgres.
-- Configure pool_size in pgbouncer.ini to limit Postgres connections.
-- Applications connect to PgBouncer (e.g. port 6432) instead of Postgres directly.

-- Verify pooler is working:
SELECT count(*) FROM pg_stat_activity; -- should be low even under high app load

Why this works

PgBouncer multiplexes many application connections onto a small number of real Postgres backend connections. In transaction pooling mode, a Postgres connection is only held for the duration of a transaction, then returned to the pool. This can reduce required Postgres connections by 10-50x.

Fix 2: Terminate idle connections and tune timeouts

As an immediate relief measure to free connections.

fix
-- Terminate idle connections older than 10 minutes:
SELECT pg_terminate_backend(pid)
FROM pg_stat_activity
WHERE state = 'idle'
  AND query_start < NOW() - INTERVAL '10 minutes'
  AND pid <> pg_backend_pid();

-- Prevent future accumulation:
ALTER SYSTEM SET idle_in_transaction_session_timeout = '5min';
SELECT pg_reload_conf();

Why this works

pg_terminate_backend() sends SIGTERM to idle backends, freeing their connection slots immediately. idle_in_transaction_session_timeout automatically terminates backends stuck in an open transaction after the specified interval, preventing slot leakage.

What not to do

Increase max_connections indefinitely to accommodate all connections

Why it's wrong: Each Postgres connection uses ~5-10MB of shared memory; very high max_connections increases memory pressure and can degrade performance due to lock contention in shared memory.

Version notes

Postgres 14+Connection slot reservation for replication connections is now controlled separately by reserved_connections (for replication workers) in addition to superuser_reserved_connections.

Sources

📚 Official docs: https://www.postgresql.org/docs/current/errcodes-appendix.html

📚 Feature docs: https://www.postgresql.org/docs/current/runtime-config-connection.html#GUC-MAX-CONNECTIONS

🔧 Source ref: src/backend/postmaster/postmaster.c — ConnCreate()

📖 Further reading: Connection Configuration

📖 Further reading: PgBouncer

Confidence assessment

✅ HIGH confidence

Well-documented and very common in production. The PgBouncer recommendation is universally accepted best practice. Edge case: in Postgres 14+ the reserved_connections parameter was added for replication worker slots, subtly changing the slot allocation math.

See also

📄 Reference pages

max_connectionsPgBouncerConnection Pooling
⚙️ This error reference was generated with AI assistance and reviewed for accuracy. Examples are provided to illustrate common scenarios and may not cover every case. Always test fixes in a development environment before applying to production. Spotted an error? Suggest a correction →