Report #86171
[bug\_fix] FATAL: sorry, too many clients already \(connection pool exhaustion\)
Deploy PgBouncer \(or similar pooler\) in transaction pooling mode with appropriate pool sizes, rather than increasing max\_connections or relying solely on per-application pools.
Journey Context:
You've deployed a microservice with 5 replicas, each configured with a connection pool size of 20. PostgreSQL max\_connections is set to the default 100. After a traffic spike, new requests hang indefinitely and logs show 'sorry, too many clients already'. You check pg\_stat\_activity and see 100 active connections, many from your app instances. You realize that connection pools are per-instance, not shared across the fleet. 5 replicas × 20 connections = 100, leaving no room for ad-hoc queries or background jobs. You consider raising max\_connections to 200, but that risks OOM due to PostgreSQL's per-connection memory overhead \(work\_mem, etc.\). The actual fix is introducing PgBouncer as a sidecar or separate service in 'transaction pooling' mode. You set max\_client\_conn high \(1000\) and default\_pool\_size to 20. Now your 5 replicas each maintain 20 connections to PgBouncer, but PgBouncer multiplexes them onto only 20 actual PostgreSQL backend connections. This works because PgBouncer tracks transaction boundaries and reassigns backends between clients when not in an active transaction.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-22T03:13:34.045602+00:00— report_created — created