Skip to content
Navigation

Type at least two characters. Search covers page titles, headings, tags and database names.

↑ ↓ to navigateEnter to openEsc to close0 pages
PostgreSQLintermediate

PostgreSQL Common Problems

The failure modes that recur across PostgreSQL deployments, how to recognise each one, and what actually fixes it.

3 min readIntermediateUpdated Edit this page

Connection slots exhausted

FATAL: sorry, too many clients already. Usually the application opened more connections than max_connections, often because a pool was resized or instances were scaled up.

Raising max_connections treats the symptom and costs memory. Put a pooler in front and cap the total — see PgBouncer and the connection exhaustion playbook.

Table and index bloat

Symptoms: disk usage grows while row counts do not, and sequential scans get slower over time. The cause is nearly always something holding the transaction horizon back — a long transaction, an idle-in-transaction session, or an inactive replication slot. See Table Bloat.

Transaction ID wraparound warnings

database is not accepting commands to avoid wraparound data loss. Autovacuum has not frozen old rows fast enough. Alert on age(relfrozenxid) long before this point; recovery requires a vacuum that can run for hours.

A plan that changed overnight

A query that was fast yesterday now scans sequentially. The usual causes are stale statistics after a bulk load, a table that crossed the size where a different plan became cheaper, or a parameter value that is unrepresentative of the typical case.

ANALYZE orders;
EXPLAIN (ANALYZE, BUFFERS) SELECT …;   -- compare estimated with actual rows

If the estimate is far from the actual, the fix is better statistics — extended statistics for correlated columns, or a higher statistics target — not a query rewrite. See Query Planning.

Deadlocks

ERROR: deadlock detected
DETAIL: Process 4711 waits for ShareLock on transaction 89231; blocked by process 4712.

PostgreSQL detects deadlocks and aborts one transaction; the application must retry. Reduce their frequency by acquiring locks in a consistent order across code paths, keeping transactions short, and updating rows in a deterministic sequence. Enable log_lock_waits to see what precedes them.

Idle in transaction sessions

The most damaging state a session can be in. It holds locks and blocks vacuum indefinitely.

ALTER ROLE app_service SET idle_in_transaction_session_timeout = '30s';

The underlying cause is usually application code that opens a transaction and then performs an external call or waits on user input.

Replication lag on a standby

Identify which component is lagging — send, flush or replay — before acting. Replay lag is often caused by long queries on the standby conflicting with WAL apply, or by a single-threaded apply that cannot keep up with a bulk write on the primary. See the replication lag playbook.

Out-of-memory kills

A backend killed by the kernel causes the postmaster to restart every backend, dropping all connections. Nearly always caused by work_mem multiplied across nodes, workers and concurrency. See Memory Settings.

Disk full

Extension missing after a restore

A restore into a cluster without the same extensions installed fails or silently loses functionality. Extensions are part of the environment, not the dump. Record the extension list alongside the backup:

SELECT extname, extversion FROM pg_extension ORDER BY extname;