Docker Desktop Memory Usage on Mac: Measured on an 8GB MacBook
Docker memory usage looks small in docker stats. On a Mac, that is not what your Mac actually pays. Docker Desktop runs your containers inside a Linux virtual machine, and the VM’s memory is what macOS sees. On my MacBook (Intel, 8GB RAM) I started containers, made one hold 1.5GB, then removed them, and recorded the Mac-side memory at each step. Three runs.
Short answer
- Containers cost more than
docker statsshows. Three idle containers (Postgres, Redis, Node) totalled about 85MiB indocker stats, but Docker’s memory on the Mac (RSS) grew by 320 to 472MiB. - Memory freed inside the VM does not come straight back to macOS. After removing the 1.5GB container, usage inside the VM dropped back to about 0.95GB within 60 seconds. On the Mac side, Docker was still 129 to 991MiB above its pre-container level three minutes later.
- Removing every test container still leaves it higher than where it started: 266 to 1,376MiB above the starting value, two minutes after cleanup.
- The VM does reuse what it already holds. Running the 1.5GB container again in runs 2 and 3 added only 288 and 442MiB on the Mac, versus 1,126MiB the first time.
- The ceiling is the VM memory setting. With the default 4GiB VM, the highest Mac-side figure I saw was 3,063MiB. On an 8GB Mac, treat Settings → Resources → Memory limit as the most Docker can take from you.
Setup
MacBook Pro 13-inch 2020 (Intel, 4 cores, 8GB RAM), macOS 14.0, Docker Desktop 4.73.0 (engine 29.4.3), VM memory 4GiB (default). Two containers I normally use (about 540MiB inside the VM) kept running throughout; they are part of every row equally.
- Mac side: summed RSS of the Docker.app processes and the virtual machine process (
com.apple.Virtualization.VirtualMachine). - Inside the VM:
free -mused, run inside the VM. - One run: start → run Postgres 16, Redis 7 and Node 22, wait 60s → add a container that holds 1.5GB in memory, wait 40s → remove it, read at 60s and 180s → remove all test containers, wait 120s. Repeated three times.
| Step | Docker on the Mac (MiB), runs 1·2·3 | Used inside VM (MiB), runs 1·2·3 |
|---|---|---|
| Start | 1,422 · 2,394 · 1,812 | 904 · 882 · 918 |
| 3 containers running | 1,742 · 2,775 · 2,284 | 936 · 966 · 934 |
| 1.5GB container added | 2,868 · 3,063 · 2,726 | 2,361 · 2,506 · 2,449 |
| 60s after removing it | 3,026 · 2,899 · 2,791 | 992 · 987 · 979 |
| 180s after removing it | 2,733 · 2,904 · 2,561 | 946 · 950 · 920 |
| 120s after removing all test containers | 2,798 · 2,660 · 2,618 | 889 · 904 · 898 |
Caveats
- This is RSS only. macOS compresses or pages out memory nobody touches. Between runs (about three minutes) the Mac-side number fell from 2,798 to 2,394 and from 2,660 to 1,812MiB. So the memory is not kept forever; it just does not come back within minutes. I did not measure the compressed amount.
- One machine, three runs. An Apple silicon Mac or another Docker Desktop version may give different numbers.
- The 320 to 472MiB for three containers includes cache the VM picked up while reading image files. The containers’ own processes are closer to the
docker statsfigures (Postgres 60MiB, Redis 15MiB, Node 9MiB). - I did not try other VM memory settings. “The setting is the ceiling” means the maximum stayed under it at 4GiB.
On an 8GB Mac
- The Memory limit in Settings → Resources is the most Docker can take. 4GiB on an 8GB Mac is tight once a browser and an IDE are open. If you only run one or two databases, lowering it helps the whole Mac.
- If the Mac feels slow after a heavy job in a container (a big build, a large data load), removing the container will not free it right away. Restarting Docker Desktop starts a fresh VM and brings the memory back to the starting state.
- When judging container memory, look at Docker and the virtual machine process in Activity Monitor, not only
docker stats.
Reproduce
The script (measure.sh) and the raw results (results.tsv, environment in env.txt) are in the experiment folder. Run bash measure.sh on a Mac with Docker Desktop running. Test containers are named ddm- and nothing else is touched.
All measured RAM numbers in one table: 16GB vs 32GB RAM for programming