Why do Docker containers get only 64 MB of /dev/shm by default, and when do you raise it?
answer
- A tiny filesystem nobody remembers exists
- Multiprocess workers passing data without copying
- The crash arrives as a signal
- df inside the container tells you at once
- 64 MB, raised with a run flag
basics
~20 sDocker mounts a 64 MB tmpfs at /dev/shm in every container. Workloads that pass bulk data between processes through POSIX shared memory exhaust it and die with a bus error rather than a clear message. Raise it with --shm-size.
solid answer
~40 s`/dev/shm` is a tmpfs used for POSIX shared memory, and Docker gives every container its own, fixed at 64 MB. Anything that moves bulk data between processes through shared memory — a data loader with several worker processes, a headless browser, a rasteriser pool — will exhaust it, and the symptom is not a clean error but `Bus error (core dumped)`: writing to a tmpfs page that cannot be allocated raises SIGBUS. Confirm with `docker exec <c> df -h /dev/shm`, which shows the 64M ceiling. Fix it with `--shm-size=2g` on `docker run`, `shm_size` in Compose, or `default-shm-size` in `daemon.json` for a host-wide default. `--ipc=host` also works by handing the container the host's `/dev/shm`, but it removes IPC isolation, so prefer sizing the container's own.
code
bash · 8 lines# Diagnose
docker exec pdf-raster df -h /dev/shm
# Fix: size the container's own /dev/shm
docker run -d --name pdf-raster --shm-size=512m pdf-signer:4.7
# Blunt alternative: share the host's, losing IPC isolation
docker run -d --ipc=host pdf-signer:4.7go deeper
Remember the number and the flag: containers get a 64 MB /dev/shm, and --shm-size changes it. Checking with df -h /dev/shm inside the container is the whole diagnosis.
Explain what /dev/shm is used for and why exhausting a tmpfs mapping raises SIGBUS rather than returning a write error, so a bus error becomes a recognisable signature rather than a mystery.
Size it from the real working set, know that tmpfs pages are charged to the container's memory accounting so the failure can move to an out-of-memory kill, and justify --shm-size over --ipc=host on isolation grounds.
Decide where the default belongs — a per-service setting, a host-wide default-shm-size on a dedicated fleet, or a startup assertion in the image — so that a workload cannot be deployed into an environment that silently under-provisions it.
### What `/dev/shm` is `/dev/shm` is a tmpfs — a filesystem living in page cache — and it is where POSIX shared memory lands. When a process calls `shm_open()`, the kernel creates a file there; when two processes map that file, they share physical pages and can pass data between them with no copy through a socket or a pipe. Anything that wants zero-copy IPC uses it: Python's `multiprocessing`, PyTorch's `DataLoader` when `num_workers` is above zero, Chromium-based headless browsers, some database engines, and most multiprocess image or document pipelines. ### Why containers get 64 MB A container gets its own IPC namespace and its own tmpfs at `/dev/shm`, so it cannot see or collide with the host's shared-memory segments. Docker sizes that tmpfs at **64 MB** by default. The number is a conservative historical default rather than a derived one — a tmpfs is charged against memory when it is filled, and an unbounded default would let any container quietly consume host memory through shared segments. Small containers never notice; anything doing real multiprocess data movement notices immediately. ### The symptom is a bus error, not a disk-full error This is what makes it an interview-worthy failure. A process that maps a shared file and then writes past what the tmpfs can allocate does not get a friendly `ENOSPC` on write — it takes a page fault that cannot be satisfied, and the kernel delivers **SIGBUS**. So the visible output is: ``` Bus error (core dumped) ``` or, from a data loader, a message about a worker being killed by signal `Bus error`. Some libraries do surface `No space left on device` when they create the segment rather than when they touch it, which is why the same underlying cause shows up under two very different-looking errors. Neither mentions `/dev/shm`, and neither is affected by the container's memory limit, so people chase the wrong thing for hours. ### Confirming it ``` docker exec pdf-raster df -h /dev/shm Filesystem Size Used Avail Use% Mounted on shm 64M 64M 0 100% /dev/shm ``` A 64M line is diagnostic on its own. Watching `Used` climb toward the ceiling while the workload runs turns a suspicion into a fact. ### Fixing it * **Per container:** `docker run --shm-size=2g …`. The value takes `b`, `k`, `m` or `g` suffixes. * **Compose:** `shm_size: 2gb` on the service. * **Host-wide default:** `default-shm-size` in `/etc/docker/daemon.json`, applied to containers created after a daemon restart. Useful on a host dedicated to one class of workload; a blunt instrument elsewhere. * **`--ipc=host`:** shares the host's IPC namespace and therefore the host's `/dev/shm`, which is typically half of RAM. It works, and it dissolves IPC isolation — the container can see and interfere with host shared-memory segments and those of other containers using the same namespace. Use `--ipc=shareable` plus `--ipc=container:<id>` when two containers genuinely need to share segments with each other; reach for `--ipc=host` only when a vendor requires it. ### Sizing it honestly The size is not free. tmpfs pages are charged to the cgroup that faults them in, so a container with a memory ceiling that also fills a large `/dev/shm` can trade a bus error for an out-of-memory kill — the failure moves rather than disappears. Size `/dev/shm` from the actual working set (worker count multiplied by the payload each worker has in flight, plus headroom) and make sure the container's memory ceiling has room for it, rather than setting both to round numbers and hoping. ### Worked example A PDF-signing service — a Node.js API on an alpine base — grew a batch path that rasterises documents in a pool of six worker processes before signing them. On a 340-page contract the workers began dying with `Bus error`, with nothing in the application log and no out-of-memory kill recorded. `docker exec` showed `/dev/shm` pinned at 64M with 100% used. Each worker held roughly 38 MB of page bitmaps in flight, so six workers wanted about 230 MB. The container was recreated with `--shm-size=512m` and its memory ceiling raised to keep the same headroom; the batch path completed, and a startup assertion was added that reads the size of `/dev/shm` and refuses to start below 256 MB, so the next environment that forgets the flag fails loudly at boot instead of mysteriously mid-batch. ### The one-line takeaway If a containerised multiprocess workload dies with a bus error and no application-level error, look at `/dev/shm` before you look at anything else.
- Why does exhausting `/dev/shm` produce SIGBUS rather than a write error?Because the memory is reached through a mapping, not through `write()`. The process maps the shared file and touches a page; if the tmpfs cannot allocate backing for that page, the fault cannot be satisfied and the kernel delivers SIGBUS to the faulting process. Some libraries do fail earlier with `No space left on device` when they first create or extend the segment, which is why the same root cause appears under two unrelated-looking errors.
- What do you give up by using `--ipc=host` instead of `--shm-size`?IPC isolation. The container joins the host's IPC namespace, so it shares the host's `/dev/shm` and its System V segments and semaphores — it can read and clobber shared memory belonging to the host and to any other container in that namespace, and a leak inside the container consumes host memory directly. Sizing the container's own `/dev/shm` gets the same capacity with the isolation intact.
It is a shared workbench between processes: Docker gives every container a very small one, and the workers do not get a warning when they run out of bench — they just fall over.
saying these in an interview costs you the question
- Thinks a bigger `--memory` limit fixes a /dev/shm shortage
- Believes /dev/shm grows on demand inside a container
- Reads `Bus error` as a hardware or corrupted-image problem
- Reaches for `--ipc=host` as the normal fix
- Assumes shared-memory pages are free of the memory limit