Postgres "FATAL: Remaining Connection Slots Are Reserved for Non-Replication Superuser Connections"
Quick answer
This specific error means PostgreSQL has hit its max_connections limit for regular users, but is deliberately still reserving a small number of slots...
This specific error means PostgreSQL has hit its max_connections limit for regular users, but is deliberately still reserving a small number of slots exclusively for superuser connections — this is a safety feature letting an administrator get in to investigate and fix the problem even when the connection pool is completely exhausted by regular application traffic.
The Problem
A regular application connection attempt fails specifically with this reserved-slots message, rather than a generic "too many connections" error:
FATAL: remaining connection slots are reserved for non-replication superuser connections
Notably, connecting as a superuser at this same moment might still succeed, since the reserved slots exist specifically to allow this.
Why It Happens
PostgreSQL's max_connections setting defines the absolute total connection ceiling, but a separate setting, superuser_reserved_connections, carves out a small number of those slots (commonly 3 by default) exclusively for superuser use. This means regular, non-superuser connections are actually capped at max_connections minus the reserved amount — once regular connections hit that lower effective ceiling, this specific error appears for any further non-superuser connection attempt, even though a few slots technically remain available (just reserved for superuser access only). Common underlying causes of hitting this ceiling in the first place:
- An application connection leak — connections being opened but not properly closed/released back to a pool, gradually consuming available slots over time until none remain for regular use
- Genuinely high concurrent legitimate traffic exceeding the configured
max_connectionsvalue, which may simply be set too conservatively for actual production load - No connection pooling in place at the application level, so every request opens a new direct connection rather than reusing a smaller, managed pool of connections
- Multiple separate application instances or services each maintaining their own connection pool, with the combined total across all of them exceeding the server's configured limit
The Fix
First, use the reserved superuser access this error message is telling you about to actually connect and investigate — this is precisely the scenario these reserved slots exist for:
psql -U postgres -h localhost
Once connected, check what's actually consuming the available connections:
SELECT count(*), usename, application_name, client_addr
FROM pg_stat_activity
GROUP BY usename, application_name, client_addr
ORDER BY count(*) DESC;
This immediately reveals whether a specific application or source is disproportionately consuming connections, which points toward either a leak in that specific application, or genuinely needing to raise capacity to accommodate its real traffic.
If you identify connections that are stuck idle and abandoned (particularly idle in transaction for an extended period), terminate them to immediately free up slots:
SELECT pid, state, now() - state_change AS idle_duration
FROM pg_stat_activity
WHERE state = 'idle in transaction'
ORDER BY idle_duration DESC;
SELECT pg_terminate_backend(<specific_pid>);
For a longer-term fix, implement or properly configure connection pooling at the application level (or via a dedicated external pooler like PgBouncer), which allows many application-level connections to share a much smaller number of actual server-side connections, dramatically reducing the chance of hitting the server's connection ceiling under normal operation:
# PgBouncer configuration example
[databases]
mydb = host=localhost port=5432 dbname=mydb
[pgbouncer]
pool_mode = transaction
max_client_conn = 1000
default_pool_size = 25
If genuine, legitimate concurrent demand exceeds your current max_connections setting even with reasonable pooling in place, raise it — though be aware each additional connection consumes real server memory, so this should be a deliberate, monitored increase rather than an arbitrarily large value:
ALTER SYSTEM SET max_connections = 200;
-- requires a PostgreSQL restart to take effect
Still Not Working?
If you can't connect even as a superuser despite the reserved slots existing specifically for this purpose, confirm you're actually connecting with a genuine superuser role, not just a role with elevated but non-superuser privileges — the reserved connection mechanism specifically checks for true superuser status, and a role with broad but not fully superuser permissions doesn't benefit from these reserved slots at all:
SELECT rolsuper FROM pg_roles WHERE rolname = current_user;
If this returns false, you're not actually connecting as a true superuser despite perhaps having significant other privileges, and you'll need to use an account that genuinely has the superuser attribute to access the reserved connection slots this error message is referring to.