Deploy Error Decoder

Postgres 'sorry, too many clients already' — how to fix it

Quick answer: FATAL: sorry, too many clients already means Postgres reached max_connections. Raising it is a band-aid — each connection costs memory. The real fix is a connection pooler (like PgBouncer) plus a sane per-instance pool size, so 20 app replicas don't each open 20 direct connections and exhaust the server.

What the error looks like

New connections are refused once the slots are full:

FATAL: sorry, too many clients already

# or, when the reserve slots kick in:
FATAL: remaining connection slots are reserved for
non-replication superuser connections

Postgres connections are heavyweight — each is a backend process with its own memory. max_connections is deliberately modest, which is why pooling, not a higher limit, is the scalable answer.

Why it happens

Replicas × pool size > max_connections

Every app instance opens its own pool; multiply by replicas and you blow past the limit.

Connections aren't released

A leak or long-idle transactions hold slots that should have been returned.

Serverless / many short-lived clients

Functions that each open a direct connection exhaust slots under concurrency.

Idle-in-transaction sessions

Transactions left open hold a connection (and locks) indefinitely.

Diagnose it in three steps

1

See who's connected

SELECT count(*) FROM pg_stat_activity;
SELECT state, count(*) FROM pg_stat_activity GROUP BY state;
SHOW max_connections;
2

Find idle-in-transaction offenders

SELECT pid, state, query_start, query
FROM pg_stat_activity
WHERE state = 'idle in transaction'
ORDER BY query_start;
3

Cap pools and add a pooler

# app: cap the pool per instance (e.g. node-postgres)
new Pool({ max: 10 });
# infra: put PgBouncer in transaction mode in front of Postgres
The real fix

Pool connections; don't just raise the ceiling

A connection pooler (PgBouncer in transaction mode) lets thousands of client connections share a small set of real Postgres connections. Combine it with a modest per-instance pool and a timeout that reaps idle transactions:

-- reap sessions that hold a connection open doing nothing
ALTER ROLE app SET idle_in_transaction_session_timeout = '30s';

Raising max_connections alone trades the error for memory pressure on the database.

How Infraveil handles this

Dependency health, in one view

Infraveil doesn't pool your database for you, but it makes dependency trouble visible. Running on your own servers, it health-checks your services and surfaces failures — like a service that can't reach Postgres because the slots are full — in one place, so you see the cause instead of a wall of identical errors.

Service and dependency health surfaced in one status view
Automatic restart and recovery, approval-gated and recorded
Runs on servers you control — your database stays yours

Frequently asked questions

What does 'sorry, too many clients already' mean?

Postgres has reached max_connections and is refusing new connections. Each Postgres connection is a heavyweight backend process, so the limit is intentionally modest.

Should I just increase max_connections?

Rarely the right first move — each connection consumes memory, so a high limit can starve the database. Use a connection pooler and cap per-instance pools instead.

What is PgBouncer and why use it?

PgBouncer is a lightweight connection pooler. In transaction mode it lets many client connections share a small pool of real Postgres connections, which is how you scale connection counts safely.

How do I find connection leaks?

Query pg_stat_activity for sessions stuck in idle in transaction, and set idle_in_transaction_session_timeout to reap them. Also cap your application pool size.