Lesson 6 of 12

work_mem and Spills: Where Sorts and Hashes Go to Disk

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

The one thing to understand first

work_mem is the memory budget for a single sort, hash, or similar operation — not per query and not per connection. A complex query can have many such operations running at once, each entitled to its own work_mem. With parallel workers, each worker also gets its own allotment. This multiplicative behaviour is why a seemingly modest work_mem can still exhaust RAM under load.

work_mem is charged per operation, not per query — so the real ceiling is work_mem × concurrent nodes × parallel workers. Set it too low and sorts and hashes spill to temp files; set it too high and a burst of concurrency OOMs the server. The whole skill is “modest global, generous local.”

Sorts: quicksort vs external merge

The sort code (src/backend/utils/sort/tuplesort.c) keeps tuples in memory and quicksorts them if they fit in work_mem. If they do not, it switches to an external merge sort: it writes sorted runs to temporary files and merges them. EXPLAIN ANALYZE shows the difference directly:

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:

  • Hash joins: build side must fit
  • Hash aggregates can spill too
  • Sizing it safely
  • Layer 3 — Watch it happen on your own database
  • Layer 4 — The levers this hands you
  • Layer 5 — What an Oracle DBA should expect vs what they get
  • All 36 Learning Pathway lessons
  • 170+ cookbook recipes
  • Source-grounded diagnostics & fixes

Secure checkout Cancel anytime Source-grounded

Was this helpful?

← Back to 02 — Performance: Query & Index Mastery