A 1 TB MacBook with two container runtimes installed often loses 110 GB before a single docker run. Most of it is invisible to docker system df, which only sees inside the VM currently running. The same pattern is in a developer's writeup of freeing 200 GB on a full disk: "Docker was the biggest culprit... The volumes were almost entirely unused, probably from old postgres/redis containers I'd stopped months ago." That story is Docker Desktop, but Colima and OrbStack have the same shape of problem with different filenames.
Why is Colima vs OrbStack disk usage on Mac even a question?
Because both tools solve the same problem (run Linux containers on a Mac) with different storage assumptions, and most developers install one as a Docker Desktop replacement without uninstalling Docker Desktop first. The result is two or three Linux VMs on the same SSD, each with its own copy of every base image and its own grown-and-never-trimmed disk file.
The macOS Storage bar makes that worse. Docker.raw, the Colima qcow2, and OrbStack's sparse image all end up under the gray System Data bar, alongside Xcode caches and AI tool state. The same labelling pattern is what xcode-vs-system-data-storage walks through for the iOS side.
Where does each runtime store its disk on Mac?
The three paths to know. Everything else hangs off these.
| Runtime | VM disk path on host | File type | Default size cap |
|---|---|---|---|
| Docker Desktop | ~/Library/Containers/com.docker.docker/Data/vms/0/data/Docker.raw |
Raw, allocated on first write | 64 GB (configurable in Settings, Resources) |
| Colima | ~/.colima/<profile>/diskimage |
qcow2 | 60 GB default, --disk N on colima start |
| OrbStack | ~/.orbstack/data/orbstack.img |
Sparse image | 100 GB virtual, grows as needed |
| Lima (Colima backend) | ~/.lima/<instance>/diffdisk |
qcow2 | tied to the Colima --disk flag |
| Podman Machine | ~/.local/share/containers/podman/machine/... |
qcow2 | 100 GB default |
A stale Lima instance from a past experiment can sit at ~/.lima/<old-instance>/diffdisk and keep consuming bytes after colima delete, a silent contributor to the Colima half.
How do I measure all three honestly?
A read-only audit. Nothing gets deleted. Paste this into Terminal.
# Read-only Colima vs OrbStack vs Docker Desktop disk usage audit on Mac
{
printf "\n=== Docker Desktop ===\n"
du -sh ~/Library/Containers/com.docker.docker/Data/vms/0/data/Docker.raw 2>/dev/null
du -sh ~/Library/Group\ Containers/group.com.docker 2>/dev/null
printf "\n=== Colima profiles ===\n"
du -sh ~/.colima 2>/dev/null
du -sh ~/.colima/*/diskimage 2>/dev/null
printf "\n=== Lima instances (Colima backend) ===\n"
du -sh ~/.lima 2>/dev/null
du -sh ~/.lima/*/diffdisk 2>/dev/null
printf "\n=== OrbStack ===\n"
du -sh ~/.orbstack 2>/dev/null
du -sh ~/.orbstack/data/orbstack.img 2>/dev/null
printf "\n=== Total free disk ===\n"
df -h /
} | tee ~/Desktop/container-disk-audit.txt
That file on your Desktop is the real before-shot. docker system df only sees inside one VM at a time, whichever runtime owns the socket your docker CLI is currently pointing at. The host file is the truth. A missing path is a zero in the audit.
Why is OrbStack usually the smallest of the three?
Three architectural choices. First, OrbStack uses a sparse image, so the 100 GB number in ls -l is the virtual size and the actual on-disk size is closer to what was written. Docker.raw is technically sparse too, but Docker writes patterns that defeat sparseness over time, so the on-disk size creeps up to the cap.
Second, OrbStack runs a periodic trim inside the VM and propagates discards to the host image. Docker Desktop has no equivalent. Colima can do it with colima stop plus a manual qemu-img convert, but not by default.
Third, OrbStack ships a Compact button in Settings, Storage, and a orbctl compact CLI. No one-click in Docker Desktop, and Colima's path is multi-step. A Mac with mixed container experiments often shows 60 GB of Docker.raw, 40 GB of Colima qcow2, and 12 GB of OrbStack for similar workloads. OrbStack is not magic, it is just trimming.
Why is Docker Desktop still the worst offender?
The 64 GB Docker.raw cap is the default on every fresh install. The file is allocated lazily, but anything written tends to stick around: Docker layers, the BuildKit cache, and stopped containers all write into the same filesystem and only get freed when both Linux and macOS sides cooperate.
The biggest contributors inside Docker.raw: image layers kept after tag reuse, BuildKit cache mounts (/var/lib/buildkit) hitting 20 GB on a busy monorepo, stopped containers with their writable layer (200 MB to 2 GB each), dangling volumes from docker compose down without -v (Postgres, Redis, Mongo data), and unrotated *-json.log log files.
The mechanics and the exact docker subcommand that frees each one are in docker-system-prune-explained. For the host side, docker-raw-shrink-mac covers the UI trick and the qemu fallback that reclaims bytes back to APFS.
What about the Colima middle ground?
Colima uses qcow2 instead of raw, so the file is genuinely smaller than the in-VM filesystem size, but it does not trim aggressively, so the host file grows monotonically with use. The honest cleanup is four steps, each reversible until the last.
# 1. See what is inside the current Colima VM
colima ssh -- docker system df
# 2. Inside the VM, prune everything dangling
colima ssh -- docker system prune -a --volumes -f
# 3. Stop the VM so the qcow2 is consistent
colima stop
# 4. Either keep the slimmer VM, or recreate with a smaller disk
# Option A, recreate with a 40 GB cap
colima delete
colima start --disk 40 --memory 4 --cpu 4
# Option B, archive the current image before recreating
mv ~/.colima/default/diskimage ~/.Trash/colima-diskimage-$(date +%Y%m%d-%H%M%S)
Archiving the qcow2 to Trash before colima delete is the rollback escape hatch. If a container or volume turns out to have mattered, the qcow2 is a complete VM disk and can be re-mounted with qemu-img. Without that step, colima delete is immediate and unrecoverable. The safety rationale for Trash-first container cleanups is the same one move-to-trash-vs-rm-rf walks through.
What does an OrbStack cleanup actually look like?
Three commands. The cheapest reclaim of the three runtimes.
# 1. Prune images, containers, networks, and volumes inside OrbStack
orbctl run docker system prune -a --volumes -f
# 2. Compact the sparse image back to its real size
orbctl compact
# 3. Confirm host-side savings
du -sh ~/.orbstack/data/orbstack.img
The GUI equivalent is OrbStack, Settings, Storage, Compact disk image. A Mac showing 38 GB of orbstack.img after a few months of mixed work often falls back to 8 to 12 GB after one compact pass, with no container or volume lost.
Colima vs OrbStack vs Docker Desktop, side by side
What you actually need on the decision page.
| Property | Docker Desktop | Colima | OrbStack |
|---|---|---|---|
| Default host VM file | Docker.raw (raw) |
diskimage (qcow2) |
orbstack.img (sparse) |
| Default size cap | 64 GB | 60 GB | 100 GB virtual, grows on use |
| Auto-trim inside VM | No | No | Yes |
| One-click compact | No | No (multi-step) | Yes (Settings or orbctl compact) |
| Typical 12-month footprint | 50 to 100 GB | 30 to 70 GB | 8 to 25 GB |
| Subscription | Required for some org sizes | Free, open source | Free for personal, paid for work |
| Where macOS Storage files it | System Data | System Data | System Data |
| Risk of leftover Lima images | N/A | Yes, ~/.lima/<old>/diffdisk |
N/A |
| Reclaim difficulty | High (UI plus rebuild) | Medium (CLI multi-step) | Low (one command) |
Pick by what bites first. Low-disk warning on a 512 GB MacBook, OrbStack reclaims the most for the least effort. Docker Desktop subscription notice, Colima removes the subscription without changing the daily docker workflow. Parity with a Linux server in CI, Docker Desktop is still the closest match and the reclaim difficulty is a one-time tax.
What is the safe order to reclaim disk from all three?
Each step is reversible from Trash for seven days. Order is high reward, low risk first.
- Run the audit above. Note the three numbers as the baseline.
- If OrbStack is installed, run
orbctl run docker system prune -a --volumes -fandorbctl compact. Easy 10 to 40 GB. - If Colima is installed, run
colima ssh -- docker system prune -a --volumes -f. In-VM win, host file does not shrink yet. - If Docker Desktop is unused for a month, quit it and move
Docker.rawto Trash. Docker Desktop recreates a fresh, small one on next launch. - Active Docker Desktop users, follow the docker-raw-shrink-mac two-step instead.
- Check
~/.lima/for orphan Lima instances. Eachdiffdiskis a complete VM image. Move stale ones to Trash with a timestamp. - Re-run the audit. Empty Trash after seven days if nothing regressed.
That order is the same review-first floor why-cleanmydev-shows-receipts argues for across every category on a developer Mac.
What does CleanMyDev do that this article does not?
The audit script above is honest, but it requires a terminal and a memory of which runtimes you tried in the last two years. CleanMyDev runs the same scan automatically across Docker Desktop, Colima, Lima, OrbStack, and Podman, shows per-row sizes with last-modified dates next to each VM disk and each dangling volume, and routes anything you tick to Finder Trash with a timestamp.
If a low-disk warning is the reason this tab is open, grab CleanMyDev for $9.99 lifetime on the pricing page. One purchase, no subscription, no telemetry, covers Colima, OrbStack, Docker Desktop, every JS install cache, the AI coding tool footprint, and the Xcode side.
Related reading
- docker-raw-shrink-mac for the Docker Desktop side of the audit and the qemu-img path to actually reclaim bytes.
- docker-system-prune-explained for what each
docker system pruneflag really deletes inside the VM. - find-all-node-modules-mac for the per-project
node_modulessweep that pairs with a container runtime cleanup.