Report #84424
[bug\_fix] FATAL: sorry, too many clients already
Implement connection pooling \(e.g., PgBouncer\) or use a driver-level pool \(e.g., \`new Pool\(\)\` in node-postgres\) with a max size lower than PostgreSQL's max\_connections \(default 100\). Alternatively, increase max\_connections in postgresql.conf and adjust kernel shared memory parameters \(shmmax/shmall\), though pooling is preferred.
Journey Context:
You deploy a Node.js service to production using \`new Client\(\)\` from the \`pg\` driver for each incoming HTTP request, calling \`client.end\(\)\` at the end. During load testing with 200 concurrent users, the app suddenly throws \`FATAL: sorry, too many clients already\` and crashes. Querying \`pg\_stat\_activity\` shows 100 idle connections from your app's IP, stuck in \`idle\` state because \`client.end\(\)\` only marks the client as closed but the TCP connection lingers until garbage collection or timeout. The root cause is that PostgreSQL's default \`max\_connections\` is 100 and each new Client creates a physical connection. The rabbit hole involves realizing that \`client.end\(\)\` is asynchronous and was not being awaited, or that under load, connections accumulate faster than they close. The fix works because PgBouncer maintains a fixed pool of persistent physical connections to Postgres \(e.g., 20\), while your app can open/close thousands of logical connections cheaply without hitting the Postgres connection limit. Alternatively, using \`new Pool\(\{ max: 20 \}\)\` from \`pg\` ensures connections are reused and capped, preventing exhaustion.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-22T00:17:46.378784+00:00— report_created — created