PostgreSQL 'Too Many Clients': How to Fix Exhausted Connections
"FATAL: sorry, too many clients already" means you've hit max_connections. The fix isn't always raising the limit — it's usually finding what's leaking connections. Here's how.
Step 1 — See who's connected
SELECT count(*) FROM pg_stat_activity;
SHOW max_connections;
If the count is at (or near) max_connections, you're saturated. Now break it down by state — this is the key diagnostic:
SELECT state, count(*) FROM pg_stat_activity GROUP BY state ORDER BY 2 DESC;
Step 2 — Read the states
- idle in transaction (a lot of them) — connections that opened a transaction and never committed or rolled back. This is a leak in the application, and the most common real cause.
- idle (a lot) — the app opens connections and never closes them, or there are simply too many app instances each holding a pool.
- active (a lot) — genuine load; queries are slow or concurrency is too high.
Step 3 — The fixes
- Add a connection pooler — put PgBouncer in front of Postgres so hundreds of app connections share a small pool of real backend connections. This is the single most effective fix.
- Fix idle-in-transaction — ensure the app commits/rolls back promptly, and set a guardrail:
idle_in_transaction_session_timeout = '60s'. - Right-size the app pool — too-large per-instance pools multiplied across instances exhaust the server; lower them.
- Raise max_connections only as a last resort — each connection costs memory, so a pooler is better than a bigger limit.
How Tech Matrix solves this in ~60 seconds
The hard part is telling a real load problem from a connection leak. Tech Matrix reads pg_stat_activity, the connection states and your config, tells you whether it's idle-in-transaction, an oversized app pool, or genuine load, and recommends the pooler/timeout settings for your Postgres version — with your approval on any change.
Frequently asked questions
You've reached max_connections. Usually it's a connection leak — often 'idle in transaction' sessions the app never closed — or too many app instances each holding a large pool.
Query pg_stat_activity: 'SELECT count(*) FROM pg_stat_activity;' for the total and 'SELECT state, count(*) FROM pg_stat_activity GROUP BY state;' to find idle and idle-in-transaction leaks.
Add a pooler like PgBouncer, fix idle-in-transaction sessions (and set idle_in_transaction_session_timeout), right-size the app's pool, and only raise max_connections as a last resort.