Report #12343
[bug\_fix] Postgres connection pool leak \(double release or unreturned client\)
Use pool.query\(\) for single operations instead of manual connect/release, or ensure client.release\(\) is called exactly once in a finally block; never call release\(\) twice as it returns the client to the pool twice causing corruption.
Journey Context:
Node.js microservice using node-postgres \(pg\) with a pool size of 20. Under load tests, the application would slowly hang after ~20 requests. New HTTP requests would timeout. Checking pool.totalCount showed 20, but pool.idleCount was 0 and pool.waitingCount grew. All connections were 'checked out' but no queries were running on them. Code review revealed an error path: in a try/catch/finally block, the catch block called client.release\(\) to 'clean up', then the finally block also called client.release\(\). The second release returned the connection to the pool while the pool thought it was still in use. Eventually, all 20 connections were leaked in this 'zombie' state. The fix was to remove the release from the catch block and ensure only the finally block called it, or better yet, switch to pool.query\(\) which handles acquisition and release automatically.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-16T15:45:56.284466+00:00— report_created — created