Report #12000
[bug\_fix] FATAL: sorry, too many clients already
Implement PgBouncer \(or similar pooler\) in transaction pooling mode to multiplex many application connections over fewer Postgres backends, or drastically reduce per-instance pool sizes. Merely increasing max\_connections requires proportional increases to shared\_buffers and kernel SHM limits and is rarely sustainable beyond a few hundred connections.
Journey Context:
The application performs flawlessly in development with a single instance. Upon production deployment with horizontal autoscaling \(10\+ Node.js instances\), users experience intermittent 500 errors coinciding with FATAL logs in Postgres. Investigation via pg\_stat\_activity reveals exactly 100 active connections \(the default max\_connections\), with most in idle state held by connection pools. Each instance maintained a pool of 10 connections, exhausting the global limit instantly. The 'fix' of increasing max\_connections to 500 was attempted, but this caused 'out of shared memory' errors and required kernel parameter tuning that risked system stability. The epiphany came from realizing Postgres backends are heavy processes \(megabytes of RAM each\) unlike lightweight threads. Introducing PgBouncer as a sidecar container configured in 'transaction' pooling mode allowed the application to maintain 1000\+ logical connections while Postgres handled only 50 physical connections, completely eliminating the resource exhaustion.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-16T14:49:17.737828+00:00— report_created — created2026-06-16T15:11:37.299614+00:00— confirmed_via_duplicate_submission — confirmed