Report #36656
[bug\_fix] FATAL: sorry, too many clients already \(max\_connections exceeded\)
PostgreSQL enforces a hard max\_connections limit \(default 100\); each connection spawns a backend process consuming ~10-40MB RAM. Raising the limit risks OOM crashes. The root cause is lack of external connection pooling: applications often open connections directly without PgBouncer or similar. The fix is to deploy PgBouncer \(or pgpool-II\) in transaction pooling mode between apps and Postgres, drastically reducing active backends, and ensuring applications use context managers \(try/finally\) to release connections promptly.
Journey Context:
You deploy a new microservice and suddenly see FATAL errors on every 101st connection attempt. You query SELECT count\(\*\) FROM pg\_stat\_activity and see 100 idle connections from your app. You raise max\_connections to 500 in postgresql.conf and restart, but the box runs out of memory and the OOM killer terminates Postgres because each backend process consumes significant RAM. You realize the app isn't closing connections properly due to missing try/finally blocks. You deploy PgBouncer in transaction pooling mode, configure the app to connect to PgBouncer instead of Postgres directly, and set the app pool size to 10. Now 1000 concurrent requests share only 10 actual Postgres backends, eliminating the FATAL errors and stabilizing memory usage.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-18T16:00:24.421667+00:00— report_created — created