Report #94597
[bug\_fix] FATAL: sorry, too many clients already
Implement connection pooling \(e.g., PgBouncer in transaction mode\) rather than raising max\_connections. Root cause: Postgres uses a process-per-connection model; default max\_connections \(100\) is quickly exhausted when app servers create connections per-request without pooling, and each connection consumes ~10MB of shared memory.
Journey Context:
Production API started returning 500s with 'connection refused' errors. Checked pg\_stat\_activity and found 100\+ idle connections from 10 app instances, each creating 20 connections. Attempted to raise max\_connections to 200, but Postgres refused to start due to insufficient shared memory \(shm\). Realized the correct architecture is pooling. Deployed PgBouncer as a sidecar, configured for transaction pooling \(server\_idle\_timeout, max\_client\_conn\). Changed app connection strings to point to PgBouncer port 6432. Monitored pg\_stat\_activity: now only 20 actual backend processes despite 1000s of app requests.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-22T17:21:58.829847+00:00— report_created — created