PostgreSQL Temporary File Spilling & Out of Memory: work_mem Tuning, Disk Spill Forensics & Query Optimization
Diagnosing excessive work_mem x concurrency spikes, disk sort spills, and temp_file_limit violations, emergency session overrides, and safe memory budgeting formula.
Operational Verification & Reliability Metadata
The error string is a symptom, not the root cause. Do not restart the server blindly. Run the diagnostic queries below to pinpoint the actual failure mode.
▸Symptom
Large analytical queries fail with:
ERROR: temporary file size exceeds temp_file_limit (10485760kB)
ERROR: out of memory
DETAIL: Failed on request of size 33554432 in memory context "ExecutorState".▸What You See in Production
Queries abort with quota exhaustion. pg_stat_database.temp_bytes spikes drastically, generating heavy disk I/O.
▸Root Cause Matrix
| Probability | Root Cause | Description |
|---|---|---|
| %50 | Massive Sort/Hash Spill | Execution nodes spill gigabytes to disk until hitting temp_file_limit. |
| %30 | Aggressive `work_mem` Multiplier | High work_mem multiplied across concurrent queries triggers OS OOM. |
| %20 | Restrictive `temp_file_limit` | Limit set too low for legitimate batch workloads. |
▸EMERGENCY RUNBOOK (0-5 min)
-- 1. Identify active sessions spilling to disk
SELECT pid, usename, query, pg_size_pretty(temp_bytes) AS temp_size
FROM pg_stat_activity WHERE temp_bytes > 0 ORDER BY temp_bytes DESC;
-- 2. Cancel offending query
SELECT pg_cancel_backend(12345);
-- 3. Grant temporary session headroom
SET temp_file_limit = '20GB';
SET LOCAL work_mem = '256MB';▸PERMANENT BLUEPRINT
- 1Safe `work_mem` Sizing: Apply $(RAM \times 0.25) / (max\_connections \times 2)$.
- 2Session Elevation: Apply larger
work_memstrictly within specific sessions usingSET LOCAL. - 3Telemetry: Log spills exceeding 10MB via
log_temp_files = 10240.
▸Verification
SHOW work_mem;
SHOW temp_file_limit;
SELECT datname, temp_files, pg_size_pretty(temp_bytes) FROM pg_stat_database WHERE datname = current_database();Other Database Error Triage Playbooks
Other battle-tested diagnostic guides for high-severity database errors.
PostgreSQL Connection Exhaustion & too many clients Triage
Root causes of FATAL: sorry, too many clients already and remaining connection slots errors, read-only pg_stat_activity diagnosis with privilege boundaries, and two-tier pooling mitigation.
PostgreSQL password authentication failed: Root Cause and Fix
Four root causes of psql password authentication failed: incorrect password, md5/SCRAM mismatch, pg_hba.conf rule ordering, and port/cluster confusion. Step-by-step triage.
PostgreSQL connection refused: 8-Step Definitive Triage
Difference between connection refused, timeout, and no pg_hba entry; triage for listen_addresses, port conflicts, firewalls, and Docker container mappings.