Inspect actual query plans.
EXPLAIN shows estimates. EXPLAIN (ANALYZE, BUFFERS) runs the query and reports actual rows, time, and buffer use. Do not use ANALYZE on a write unless executing the write is safe.
EXPLAIN (ANALYZE, BUFFERS) SELECT …;A query runs inside a transaction, over a database connection, using a plan chosen by PostgreSQL. This guide visualises the key concepts when using PostgreSQL.
BEGIN; SELECT title FROM projects WHERE owner_id = 42 LIMIT 10; COMMIT;
A session lasts from connect to disconnect and can contain many transactions. A transaction groups statements into one unit: all changes commit together or roll back together.
SET. It remains until disconnect.SET LOCAL values. It ends at COMMIT or ROLLBACK.Before running a query, PostgreSQL compares valid ways to execute it. The estimates come from table statistics and cost settings; they are not measured execution times.
The planner estimates a plan before execution. EXPLAIN ANALYZE then runs it and records actual work. Large differences between estimated and actual rows often explain a poor plan.
cost=a..bEstimated startup and total work, not milliseconds.rowsEstimated rows before execution; actual rows after it.actual time=a..bMilliseconds to first row and all rows, per loop.loopsTimes the node ran. Multiply per-loop rows to get total rows.Buffershit came from cache; read required storage I/O.Large estimate error: refresh statistics with ANALYZE after major data changes. Skewed or correlated columns may need a higher statistics target or extended statistics.
EXPLAIN (ANALYZE, BUFFERS).Optimization guidePostgreSQL EXPLAINA direct connection keeps one PostgreSQL server process, called a backend, for one client. A transaction pooler shares fewer backends among many clients and assigns one only while a transaction runs.
Both read changes from the write-ahead log (WAL). Physical replication copies the whole database cluster at the storage level. Logical replication sends selected row changes to tables on another PostgreSQL server.
PostgreSQL has separate limits for a running statement, a lock wait, an idle session, and an idle or long-running transaction. An application deadline is still needed for the complete request.
Select a phase to see which timeout applies.
These defaults suit common application workloads. Confirm them against real query plans, traffic, and provider limits.
EXPLAIN shows estimates. EXPLAIN (ANALYZE, BUFFERS) runs the query and reports actual rows, time, and buffer use. Do not use ANALYZE on a write unless executing the write is safe.
EXPLAIN (ANALYZE, BUFFERS) SELECT …;Do not wait for user input or network calls inside a transaction. An open transaction can retain locks and delay removal of old row versions.
Transaction pooling fits workloads with many short transactions. Limit database connections to the number PostgreSQL can run efficiently, not the number of application clients.
Use a stable connection for migrations, LISTEN, session advisory locks, temporary-table workflows, and other features tied to one backend.
An index can reduce reads for selective filters, but it uses storage and adds work to writes. Check the plan with representative data.
Set a deadline for the complete application request, statement_timeout for database work, and lock_timeout where blocked queries should fail quickly.