PostgreSQL Performance Cheat Sheet

EXPLAIN, vacuum, planner settings, indexing, and practical tuning recipes.

View
StandardDetailedCompact
Export
Copy the compact sheet, download it, or print it.
Download
`D` dense toggle · `C` copy all

EXPLAIN and Plan Analysis

Read plans and compare query behavior.

EXPLAIN query

Show the planner's chosen execution plan.

sqlANYexplainplanner
sql
EXPLAIN SELECT * FROM orders WHERE customer_id = 42;
Notes

See summary for usage details.

EXPLAIN ANALYZE

Run the query and show actual timing and buffer usage.

sqlANYexplainanalyzebuffers
sql
EXPLAIN (ANALYZE, BUFFERS) SELECT * FROM orders WHERE customer_id = 42;
Notes

See summary for usage details.

EXPLAIN VERBOSE

Include more detail about output columns and active settings.

sqlANYexplainverbose
sql
EXPLAIN (ANALYZE, VERBOSE, BUFFERS, SETTINGS) SELECT * FROM orders WHERE customer_id = 42;
Notes

See summary for usage details.

EXPLAIN JSON format

Return the plan as machine-readable JSON.

sqlANYexplainjson
sql
EXPLAIN (ANALYZE, FORMAT JSON) SELECT * FROM orders;
Notes

See summary for usage details.

Enable auto_explain

Log slow query plans automatically in the server logs.

sqlANYauto_explainperformance
sql
LOAD 'auto_explain';
SET auto_explain.log_min_duration = '200ms';
SET auto_explain.log_analyze = on;
Notes

See summary for usage details.

Vacuum, Analyze, and Maintenance

Routine health tasks that keep PostgreSQL fast.

Vacuum one table

Reclaim dead tuples and maintain visibility data.

sqlANYvacuummaintenance
sql
VACUUM public.users;
Notes

See summary for usage details.

Vacuum analyze one table

Vacuum and refresh planner stats in one command.

sqlANYvacuumanalyze
sql
VACUUM (ANALYZE) public.users;
Notes

See summary for usage details.

VACUUM FULL table

Rewrite a bloated table more aggressively.

sqlANYvacuumfullmaintenance
sql
VACUUM (FULL, ANALYZE) public.users;
Notes

Requires more locking and space; use carefully.

Reindex table

Rebuild all indexes on a table.

sqlANYreindexmaintenance
sql
REINDEX TABLE public.users;
Notes

See summary for usage details.

Analyze verbose

Show extra detail while updating planner statistics.

sqlANYanalyzestats
sql
ANALYZE VERBOSE public.users;
Notes

See summary for usage details.

Show autovacuum setting

Check whether autovacuum is enabled.

sqlANYautovacuumsettings
sql
SHOW autovacuum;
Notes

See summary for usage details.

Planner Settings and Statistics

Inspect or tweak optimizer behavior during investigations.

Show work_mem

Inspect a setting that affects sort and hash memory usage.

sqlANYsettingswork_mem
sql
SHOW work_mem;
Notes

See summary for usage details.

Set LOCAL work_mem

Increase work_mem for the current transaction only.

sqlANYsettingswork_memsession
sql
SET LOCAL work_mem = '256MB';
Notes

See summary for usage details.

Show effective_cache_size

Inspect a planner estimate of OS cache availability.

sqlANYsettingsplanner
sql
SHOW effective_cache_size;
Notes

See summary for usage details.

Show random_page_cost

Inspect a cost parameter that influences index-vs-seqscan decisions.

sqlANYsettingsplannercost
sql
SHOW random_page_cost;
Notes

See summary for usage details.

Disable seqscan for investigation

Temporarily discourage sequential scans while investigating plans.

sqlANYplannerdebug
sql
SET enable_seqscan = off;
Notes

Do not use as a permanent performance fix.

Inspect pg_stats

Inspect statistics the planner uses.

sqlANYpg_statsplannerstats
sql
SELECT schemaname, tablename, attname, n_distinct, most_common_vals
FROM pg_stats
WHERE tablename = 'orders';
Notes

See summary for usage details.

High-value Query Performance Patterns

Recipes users often search for when tuning SQL.

Keyset pagination

Prefer keyset pagination over deep OFFSET scans for large result sets.

sqlANYpaginationperformance
sql
SELECT *
FROM orders
WHERE (created_at, order_id) < ('2026-03-01', 1000)
ORDER BY created_at DESC, order_id DESC
LIMIT 50;
Notes

See summary for usage details.

Select needed columns

Avoid fetching unnecessary columns, especially wide rows.

sqlANYquery-designperformance
sql
SELECT order_id, customer_id, total_amount FROM orders WHERE status = 'open';
Notes

See summary for usage details.

Covering index with INCLUDE

Use included columns to support index-only reads for certain queries.

sqlANYindexincludeperformance
sql
CREATE INDEX idx_orders_customer_created_inc
ON orders (customer_id, created_at DESC)
INCLUDE (status, total_amount);
Notes

See summary for usage details.

Batch updates

Chunk large writes into batches to reduce contention and WAL spikes.

sqlANYbatchupdateperformance
sql
UPDATE orders
SET archived_at = now()
WHERE order_id IN (
  SELECT order_id FROM orders WHERE created_at < now() - interval '1 year' LIMIT 10000
);
Notes

See summary for usage details.

Batch deletes

Delete in chunks to avoid huge transactions.

sqlANYbatchdeletemaintenance
sql
DELETE FROM audit_log
WHERE ctid IN (
  SELECT ctid FROM audit_log WHERE created_at < now() - interval '180 days' LIMIT 10000
);
Notes

See summary for usage details.

Create range-partitioned table

Partition large time-series tables by range.

sqlANYpartitioningtableperformance
sql
CREATE TABLE metrics (
  ts timestamptz NOT NULL,
  device_id bigint NOT NULL,
  value numeric NOT NULL
) PARTITION BY RANGE (ts);
Notes

See summary for usage details.

Attach partition

Add a partition for a date range.

sqlANYpartitioningddl
sql
CREATE TABLE metrics_2026_03 PARTITION OF metrics
FOR VALUES FROM ('2026-03-01') TO ('2026-04-01');
Notes

See summary for usage details.

Recommended next

No recommendations yet.