Ever had an incident where latency on a trivial SELECT spikes from a few milliseconds to several seconds, CPU on the Postgres box is basically flat, and there's no slow query or missing index anywhere in sight?
That's not a database problem. That's connection pool exhaustion at the PgBouncer layer — and it's one of the most common (and most misdiagnosed) production incidents in Postgres-backed systems.
I just wrote a deep dive on this: how it happens, how to diagnose it live, and how to size your pool correctly instead of guessing. Here's the short version.
The core issue
PgBouncer sits between potentially thousands of client connections and a small, fixed number of physical Postgres backends. That works fine — until something makes transactions hold connections longer than expected: a slow downstream API call, a lock wait, a runaway transaction. When that happens, the queue of waiting clients grows unbounded, and every request behind it pays the tax, even the fast ones.







