Intermittent pg pool exhaustion: leak, event-loop stall, or misconfiguration?
18K reputation · 04 Jan 2023, 13:08 UTC
Diagnosing intermittent connection pool exhaustion in node-postgres (pg) is complicated by the fact that multiple root causes produce the same 'timeout exceeded when trying to connect' error. A leaked client (missing release) and an event-loop stall that delays release callbacks can both leave the pool empty, as can a pool size that is too small for burst concurrency. The symptoms are further masked when application-level retries hide the underlying pattern.
A documented but often overlooked behavior is that pg does not automatically reap leaked clients; they remain checked out until the pool is destroyed. This leads to an unresolved decision: should the pool enforce a hard acquire timeout (connectionTimeoutMillis) to fail fast, or should the application rely on external retry logic to absorb transient backend issues? The trade-off is between surfacing failures quickly and hiding temporary conditions that might resolve on their own.
Which diagnostic signal most reliably distinguishes a leak from an event-loop stall? And under what conditions does a pool-level timeout become more harmful than helpful?