dynamic_shared_memory_type picks the operating-system mechanism PostgreSQL uses for dynamic shared memory — memory allocated after startup, as opposed to the fixed shared_buffers region grabbed once at boot. The context is postmaster, so it’s a restart to change, and the default is chosen by initdb from what your platform supports: posix on Linux and most Unix, windows on Windows. You will probably never set it deliberately. You may, however, end up cursing it in a container, and that’s the part worth your attention.

What dynamic shared memory is for

The fixed shared memory PostgreSQL allocates at startup can’t grow, but some features need shared memory whose size isn’t known until runtime — chiefly parallel query, where the leader and its workers need a shared scratch space sized to the plan: parallel hash tables, shared tuple stores, the bitmap for a parallel bitmap scan. Dynamic shared memory (DSM) is how that space gets allocated and handed around between cooperating processes, and dynamic_shared_memory_type chooses the kernel facility underneath it.

The choices, in the priority initdb considers them on a non-Windows box: posix (POSIX shared memory via shm_open, which on Linux means a file under the /dev/shm tmpfs), sysv (System V shared memory via shmget, governed by the old SHMMAX/SHMALL kernel limits that used to make PostgreSQL installation miserable before 9.3), and mmap (memory-mapped files in $PGDATA/pg_dynshmem). On Windows there’s just windows. The default lands on posix essentially everywhere modern, and it’s the right choice — fast, no sysadmin-visible kernel limits, no disk involvement.

mmap deserves one sentence of warning: the docs discourage it because the OS may write its modified pages back to disk repeatedly, turning fast inter-process memory into I/O load. It exists for platforms without the better options, or for debugging with pg_dynshmem on a RAM disk. It is not a performance setting and not a place to go looking for one.

The container trap

Here is why a parameter you’d never touch shows up in your life. POSIX shared memory on Linux is backed by the tmpfs mounted at /dev/shm, and that filesystem has a size. On a normal host it’s large — half of RAM by default. Inside a Docker container it is, by default, 64 MB, and Kubernetes’ default emptyDir shared-memory behavior is similarly stingy. Parallel query allocates its DSM segments from that 64 MB, and a parallel hash join over any real data wants far more, so the query dies with:

1ERROR: could not resize shared memory segment "/PostgreSQL.NNNNN" to NNN bytes: No space left on device
2CONTEXT: parallel worker

This is one of the most common “PostgreSQL works on my laptop but not in the container” failures there is, and when Thomas Munro diagnosed an early report of it, the answer was simply that the container had mounted /dev/shm at 65536k and the error was working exactly as designed. The segment couldn’t grow because the tmpfs it lives in was full.

The fix is almost never this parameter. It’s to give the container a real /dev/shm: docker run --shm-size=1g, or shm_size: '1g' in a Compose file, or a memory-backed emptyDir (or --ipc=host) on Kubernetes. Size it the way you’d size memory generally — the peak DSM demand scales with concurrent queries times parallel workers times work_mem, the same product that governs ordinary memory, just with a separate hard ceiling the container imposed. People do sometimes “fix” it by switching dynamic_shared_memory_type to sysv or mmap, or by disabling parallelism with max_parallel_workers_per_gather = 0, and all of those make the error go away — but sysv trades the tmpfs ceiling for the System V kernel limits, mmap trades fast IPC for disk I/O, and disabling parallelism throws away the feature instead of feeding it. Resizing /dev/shm is the correct move; the others are how you make a symptom quiet without treating it.

Leave dynamic_shared_memory_type at its platform default. If you’re seeing the resize error, the parameter isn’t broken and isn’t the lever — your container’s /dev/shm is too small, and the fix lives in the container runtime, not in postgresql.conf.