Cookbook recipe

Disk-Based Sort Spill

Applies to PostgreSQL 13–17 Last reviewed May 2026 Grounded in source
Estimated investigation4 min

Scenario

Scenario An analytics team reports that monthly report queries with ORDER BY created_at DESC are slow and taking 45+ seconds. Disk I/O on the database server spikes during these runs. The DBA notices large files appearing…

Investigation Path

Scenario

An analytics team reports that monthly report queries with ORDER BY created_at DESC are slow and taking 45+ seconds. Disk I/O on the database server spikes during these runs. The DBA notices large files appearing and disappearing in $PGDATA/base/pgsql_tmp/ during query execution.

How to Identify

Conditions:

  • EXPLAIN ANALYZE shows Sort Method: external merge Disk instead of quicksort Memory
  • Large files appearing in $PGDATA/base/pgsql_tmp/ during query execution
  • pg_stat_bgwriter shows elevated buffers_alloc
  • pg_stat_database.temp_files and temp_bytes increasing
  • log_temp_files in postgresql.conf captures the events in server logs

Analysis Steps

-- 1. Identify sort spill in query plan
EXPLAIN (ANALYZE, BUFFERS, FORMAT TEXT)
SELECT * FROM events ORDER BY created_at DESC;
-- Look for: Sort Method: external merge Disk

-- 2. Check temp file stats at database level
SELECT datname, temp_files, temp_bytes,
       pg_size_pretty(temp_bytes) AS temp_size
FROM   pg_stat_database
WHERE  datname = current_database();

-- 3. Check current work_mem
SHOW work_mem;

-- 4. Monitor active temp file usage (PG 13+)
SELECT pid, query, wait_event, state,
       query_start
FROM   pg_stat_activity
WHERE  state = 'active';

-- 5. Estimate memory needed to sort in-memory
-- Rule of thumb: ~2x the result set size
-- For 1M rows * 100 bytes avg = 100MB * 2 = ~200MB work_mem needed

Pitfalls

  • Do not increase work_mem globally to a high value. Each backend can use multiple sort operations simultaneously. With 100 connections each running 3 sorts at 256MB: 100 × 3 × 256MB = 76GB potential RAM usage.
  • external merge Disk in the Sort node is the diagnostic signal, not external sort. Both exist — know the difference.
  • Adding an index on the ORDER BY column eliminates the sort entirely for queries that use it — often a better fix than increasing work_mem.
  • log_temp_files = 0 logs ALL temp files. Set a reasonable threshold (e.g., log_temp_files = 10240 for 10MB+) to avoid log flooding.

Resolution Approach

Two approaches — choose based on query pattern:

This is a Pro lesson

Get every Learning Pathway and cookbook recipe — grounded in PostgreSQL source code, with diagnostics, fixes, and prevention for each topic.

Continue this lesson to learn:

  • Mitigation Actions
  • All 36 Learning Pathway lessons
  • 170+ cookbook recipes
  • Source-grounded diagnostics & fixes

Secure checkout Cancel anytime Source-grounded

Career Impact

This scenario builds production judgment and operational confidence under pressure.

Open Career Dashboard →

Keep going

Related & next steps

Was this helpful?

← All cookbook recipes