Report #50090
[bug\_fix] FATAL: remaining connection slots are reserved for non-replication superuser connections
The root cause is the PostgreSQL parameter superuser\_reserved\_connections \(default 3\), which reserves a specific number of connection slots exclusively for superusers \(rolsuper\). When the total number of connections from regular roles reaches max\_connections minus superuser\_reserved\_connections, PostgreSQL rejects new regular connections with this specific error, even though the database technically has free slots \(the reserved ones\). The error 'too many clients already' appears only when absolute max\_connections is reached by superusers too. The fix requires either increasing the effective connection limit or reducing consumption: \(1\) Increase max\_connections in postgresql.conf \(requires restart on vanilla Postgres, or parameter group change on RDS/Cloud SQL\). Calculate required value: \(app\_pool\_size \* instance\_count\) \+ superuser\_reserved\_connections \+ monitoring/admin\_buffer. \(2\) Alternatively, reduce superuser\_reserved\_connections \(default 3\) to 1 or 0 if you don't need emergency superuser access via SQL \(you can still connect via local socket or SIGTERM handling\), though this is risky for lockout scenarios. \(3\) The robust fix is implementing external connection pooling \(PgBouncer in transaction mode or RDS Proxy\) to multiplex hundreds of application connections onto a small number of actual database connections, staying well below the \(max\_connections - reserved\) threshold.
Journey Context:
Your Go services start failing with 'remaining connection slots are reserved...'. You check Cloud SQL metrics and see only 80 connections used out of 100 max\_connections. You check the error message carefully and realize it's not 'too many clients' but specifically about reserved slots. You look at postgresql.conf and see superuser\_reserved\_connections = 3 \(default\). You calculate: 100 max - 3 reserved = 97 available, but you're hitting the limit at 97? No, the error says reserved for non-replication superuser. You realize the error occurs when connections reach max\_connections - superuser\_reserved\_connections. But you're using a regular user \(app\_user\), not superuser. When the count hits 97 \(100-3\), new regular connections are rejected with this error, even though slots 98-100 are technically free but reserved for superusers. Your monitoring only showed 97 connections, triggering the limit.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-19T14:33:35.791319+00:00— report_created — created