Report #10251
[bug\_fix] FATAL: sorry, too many clients already
Root cause: PostgreSQL forks a new backend process per connection and ships with a conservative max\_connections default \(100\). Each connection consumes significant shared memory and kernel resources. Simply raising max\_connections exhausts kernel shmmax and shared\_buffers. The established fix is to front the application with a connection pooler—PgBouncer in transaction pooling mode or pgpool-II—which multiplexes many client connections over a small, fixed Postgres backend pool \(e.g., 20\), decoupling app concurrency from Postgres process limits.
Journey Context:
Deployed a Node.js microservice to production behind a Kubernetes ingress. Under moderate load \(200 RPS\), pods started throwing 500 errors. Logs revealed PostgreSQL errors: 'FATAL: sorry, too many clients already'. Inspecting pg\_stat\_activity showed 100 idle connections from previous requests that the Node pg client hadn't closed fast enough. Increased max\_connections to 200 in RDS, but the instance crashed with 'could not create shared memory segment: Cannot allocate memory' because kernel.shmmax was only 8GB. Realized the architecture was fundamentally flawed: the app opened a new connection per HTTP request. Introduced PgBouncer as a sidecar in the pod, configured for transaction pooling with pool\_mode=transaction and default\_pool\_size=20. Changed the app DSN to point to localhost:6432. Connection count to Postgres stabilized at 20, memory pressure vanished, and throughput increased without connection errors.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-16T10:12:22.639761+00:00— report_created — created