PostgreSQL Error Guide: 'could not resize shared memory segment' — Fix /dev/shm Exhaustion
Fix PostgreSQL 'could not resize shared memory segment' when parallel query DSM fails on a too-small /dev/shm. Diagnose with df, then size /dev/shm.
- #postgres
- #database
- #troubleshooting
- #errors
Stuck on this Postgres error? Get the free incident triage checklist
A one-page PDF — the exact steps to isolate, fix, and verify a production error like this one. No spam, unsubscribe anytime.
Overview
PostgreSQL raises this error when a backend tries to create or grow a piece of dynamic shared memory (DSM) and the operating system refuses the allocation. On Linux the DSM lives in /dev/shm (POSIX shared memory), and the failure almost always means that filesystem ran out of space:
ERROR: could not resize shared memory segment "/PostgreSQL.1234567890" to 2097152 bytes: No space left on device
The SQLSTATE is 53100 (disk_full). Despite mentioning “shared memory,” this is not the fixed shared_buffers region set at startup — it is a dynamic segment that parallel query workers and parallel hash/bitmap nodes allocate on demand while a query runs. When /dev/shm is too small for the concurrent DSM demand, the allocation fails and the query aborts.
Symptoms
- Queries fail intermittently with
could not resize shared memory segment ... No space left on device, often only under load or concurrency. - The same query succeeds when run alone and fails when several run at once, or fails only for large parallel scans/joins.
EXPLAINshows Parallel nodes (Gather, Parallel Seq Scan, Parallel Hash) on the failing queries.- The error clusters around big analytical or reporting queries, not small OLTP statements.
df -h /dev/shmshows the tmpfs at or near 100% used during the failure window.- Common inside containers (Docker/Kubernetes), where
/dev/shmdefaults to a small 64MB tmpfs.
Common Root Causes
- Too-small /dev/shm. The classic container default of 64MB is far below what parallel workers need for hash tables and shared tuplestores. This is the number-one cause.
- High parallel concurrency. Many parallel queries at once each allocate DSM; collectively they exhaust
/dev/shmeven if any one query would fit. - Large parallel hash joins / Parallel Hash. A big hash side allocates a large shared hash table in DSM; a single query can need hundreds of MB.
dynamic_shared_memory_type = posixwith a constrained tmpfs. The defaultposixtype uses/dev/shm; if that mount is small, DSM is capped by it.- Aggressive
work_mem* parallel workers. Larger per-node memory budgets translate into larger DSM segments for parallel nodes. - Container/orchestrator limits. Kubernetes pods without a sized
emptyDirmediumMemory/dev/shmmount inherit the tiny default.
Diagnostic Workflow
First, confirm the message and SQLSTATE in the server log to be sure it is DSM and not the fixed shared memory / lock table:
sudo journalctl -u postgresql --no-pager | grep -A1 "could not resize shared memory" | tail -20
Check the size and live usage of /dev/shm on the database host. Watch it while the workload runs:
df -h /dev/shm
Filesystem Size Used Avail Use% Mounted on
tmpfs 64M 64M 0 100% /dev/shm
Confirm the DSM type and parallelism-related settings from inside Postgres (all read-only):
SELECT name, setting, unit
FROM pg_settings
WHERE name IN (
'dynamic_shared_memory_type',
'max_parallel_workers',
'max_parallel_workers_per_gather',
'work_mem',
'hash_mem_multiplier',
'min_dynamic_shared_memory'
);
See which queries are running in parallel right now and how many workers are active:
SELECT pid, leader_pid, state, wait_event_type, wait_event,
left(query, 80) AS query
FROM pg_stat_activity
WHERE backend_type = 'parallel worker' OR leader_pid IS NOT NULL
ORDER BY leader_pid NULLS FIRST, pid;
Check whether the failing queries actually use parallelism (look for Gather, Parallel, and Parallel Hash):
EXPLAIN (ANALYZE, BUFFERS)
SELECT ...; -- the query that intermittently fails
If you cannot enlarge /dev/shm immediately, correlate temp/DSM pressure over time:
SELECT datname, temp_files, pg_size_pretty(temp_bytes) AS temp
FROM pg_stat_database
WHERE datname = current_database();
Example Root Cause Analysis
A reporting service ran fine in staging but threw could not resize shared memory segment ... No space left on device several times an hour in production. The two environments ran the same Postgres image; the difference was the container runtime.
df -h /dev/shm inside the production container showed a 64MB tmpfs sitting at 100% during the failures — the Docker default. EXPLAIN (ANALYZE) on the failing query showed a Parallel Hash Join with max_parallel_workers_per_gather = 4; with work_mem at 128MB and hash_mem_multiplier at 2, the shared hash table alone wanted far more than 64MB of DSM, and several such reports ran concurrently.
The fix had two parts. Short term, the container was restarted with a larger shared-memory mount (--shm-size=1g; in Kubernetes, an emptyDir volume with medium: Memory mounted at /dev/shm). Medium term, work_mem for the reporting role was trimmed so a single parallel hash didn’t demand an oversized DSM segment. After enlarging /dev/shm to 1GB, df -h /dev/shm peaked around 40% under the same load and the errors stopped entirely. The root cause was not Postgres memory tuning at all — it was an undersized /dev/shm tmpfs that capped every DSM allocation.
Prevention Best Practices
- Size /dev/shm for the workload. On bare metal it defaults to ~half of RAM and is usually fine; in containers set
--shm-size(Docker) or mount anemptyDirwithmedium: Memoryat/dev/shm(Kubernetes) to something like 256MB–1GB+. - Account for concurrency. Budget
/dev/shmfor the peak number of concurrent parallel queries, not one query in isolation. - Right-size parallel memory. Keep
work_memandhash_mem_multipliersane; larger values inflate DSM for parallel hash/bitmap nodes. - Consider
min_dynamic_shared_memory. Pre-reserving DSM in the main shared segment (this parameter) can reduce reliance on/dev/shmfor parallel query on some setups. - Fallback DSM type as a last resort. Setting
dynamic_shared_memory_type = mmapavoids/dev/shmbut writes segments to the data directory and is slower — prefer fixing the tmpfs size first. - Monitor /dev/shm. Alert on tmpfs usage the same way you alert on disk; it is invisible to ordinary data-volume monitoring.
Quick Command Reference
# Check /dev/shm size and live usage (watch during load)
df -h /dev/shm
# Find the error in the server log
sudo journalctl -u postgresql --no-pager | grep "could not resize shared memory"
# Docker: give the container more shared memory
docker run --shm-size=1g ...
-- DSM type and parallelism settings
SELECT name, setting FROM pg_settings
WHERE name IN ('dynamic_shared_memory_type','max_parallel_workers_per_gather','work_mem');
-- Active parallel workers and their leaders
SELECT pid, leader_pid, state, left(query,60)
FROM pg_stat_activity WHERE leader_pid IS NOT NULL;
-- Confirm a query uses parallel nodes
EXPLAIN (ANALYZE, BUFFERS) SELECT ...;
Conclusion
could not resize shared memory segment ... No space left on device is a disk-full error on /dev/shm, not a shared_buffers problem. It appears when parallel query workers try to allocate dynamic shared memory and the tmpfs backing DSM is too small — overwhelmingly a container default of 64MB. Diagnose it by watching df -h /dev/shm under load and confirming the failing queries use parallel nodes, then fix it by sizing /dev/shm for peak concurrency and keeping parallel work_mem reasonable. Reserve dynamic_shared_memory_type = mmap as a slower fallback only if you truly cannot enlarge the tmpfs. For fast triage, the free incident assistant can turn a DSM error log block into a /dev/shm sizing recommendation.
Fixed it? Get 500 Postgres & DevOps AI prompts — free
500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.
- 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
- Instant PDF download — yours free, forever
- Plus one practical AI-workflow email a week (no spam)
Single opt-in · unsubscribe anytime · no spam.
Did this fix your issue?
Get 500 Battle-Tested DevOps AI Prompts — Free
500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.
- 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
- Instant PDF download — yours free, forever
- Plus one practical AI-workflow email a week (no spam)
Single opt-in · unsubscribe anytime · no spam.