If you build Docker images regularly on your Mac, docker build cache taking up space is one of the sneakiest storage problems you will face. The cache is invisible in Finder, it does not show up under System Settings > General > Storage, and it quietly compounds over weeks until you are suddenly 10, 20, or even 40 GB short. This guide explains exactly where that data lives on macOS Sequoia and Tahoe (Apple Silicon and Intel), how to measure it precisely, and how to delete it safely — from the surgical to the scorched-earth approach.
Where Docker Stores Its Build Cache on a Mac
Docker Desktop for Mac runs inside a lightweight Linux virtual machine managed by Apple's Virtualization framework (Apple Silicon) or HyperKit (older Intel Macs). All Docker data — images, containers, volumes, and build cache — lives inside a single virtual-machine disk image rather than scattered across your normal home folder.
- Apple Silicon:
~/Library/Containers/com.docker.docker/Data/vms/0/data/Docker.raw - Intel:
~/Library/Containers/com.docker.docker/Data/vms/0/data/Docker.raw(same path, different backing driver)
The .raw file is a sparse disk image, so the number you see with ls -lh reflects reserved space, not necessarily bytes written to physical NAND. What matters is the allocated size reported by Docker itself.
Separately, the BuildKit daemon caches intermediate layers in a content-addressable store inside that same VM. When you run docker buildx build, each RUN, COPY, and ADD instruction produces a cache entry keyed by a hash of its inputs. Those entries accumulate across every project you have ever built.
How Much Space Is the Build Cache Actually Using?
Before pruning anything, get a real number. Run this in your terminal:
docker system df
You will see output like:
TYPE TOTAL ACTIVE SIZE RECLAIMABLE
Images 23 8 14.2GB 9.1GB (64%)
Containers 4 1 42MB 38MB
Local Volumes 11 3 2.3GB 1.1GB
Build Cache 187 0 22.4GB 22.4GB
The Build Cache row is the one to watch. A clean Mac with a few months of active development can easily show 15–30 GB here. For a more granular view:
docker buildx du
This lists individual cache records with their size, creation time, and whether they are currently referenced by an image.
Build Cache vs. Other Docker Storage: A Sizing Breakdown
| Storage type | Typical size (active dev machine) | Safe to delete? | Command to remove |
|---|---|---|---|
| Build cache (BuildKit) | 10 – 40 GB | Yes — builds just take longer next time | docker buildx prune |
| Dangling images (untagged) | 1 – 8 GB | Yes — not referenced by any container | docker image prune |
| Stopped containers | 50 – 500 MB | Yes — unless you need the logs | docker container prune |
| Named images (tagged) | 5 – 20 GB | Conditional — only delete images you can re-pull | docker image prune -a |
| Volumes | 500 MB – 5 GB | Careful — may contain persistent data (databases) | docker volume prune |
How to Prune Docker Build Cache on macOS: Step by Step
The safest workflow is layered: start surgical and escalate only as needed.
-
Check current usage first.
Note the Build Cache size. If it is under 2 GB, you can skip straight to maintenance.docker system df -
Prune only unused build cache (safest). This removes cache entries that are not currently referenced by an existing image tag. Builds that rely on still-present images will not be slowed down.
Docker will ask for confirmation and tell you exactly how much it is about to free.docker buildx prune -
Prune cache older than a threshold. If you want to keep recent cache but clear the old long tail, use the
--keep-storageflag or a filter:
Thedocker buildx prune --filter until=168h168hvalue means "keep anything touched in the last 7 days." Adjust to24h,72h, or720has needed. -
Nuclear option: wipe all build cache. Add
--allto delete every cache entry, including those still referenced by existing images. The images themselves are untouched; only the intermediate layer cache is gone.
Your next full build for each project will hit the network, but subsequent builds will repopulate the cache incrementally.docker buildx prune --all -
Verify the result.
The Build Cache row should now show a dramatically reduced number.docker system df
docker system prune vs. docker buildx prune: Which One to Use
Both commands clean up Docker storage, but they target different scopes:
docker buildx prune— targets only the BuildKit build cache. Safe for everyday use. Does not touch running containers, named images, or volumes.docker system prune— removes stopped containers, dangling images, unused networks, and by default also the build cache. Adding--volumeswill additionally nuke unnamed volumes, which can destroy database data. Use with care.
For routine maintenance, prefer docker buildx prune. Reserve docker system prune for a full cleanup pass before, say, handing off a machine or running a major project migration.
Automating Build Cache Housekeeping
Instead of manually pruning every few months, add a weekly launchd job or a simple cron entry. A lightweight approach using cron:
crontab -e
Add a line like:
0 2 * * 0 /usr/local/bin/docker buildx prune --keep-storage 5gb --force
The --keep-storage 5gb flag tells BuildKit to retain up to 5 GB of the most recently used cache entries while evicting the rest. The --force flag suppresses the interactive confirmation, which is required for non-interactive cron execution. Adjust the threshold to match how much cache acceleration is worth to you versus the disk space you want to reclaim.
On Apple Silicon Macs, docker may live at /usr/local/bin/docker or /Applications/Docker.app/Contents/Resources/bin/docker — confirm the path with which docker before scheduling.
Other Developer Caches That Accumulate Alongside Docker
Build cache bloat rarely travels alone. While you are reclaiming space, it is worth checking neighboring caches that follow the same pattern of invisible growth. If you are on a Node-heavy project, cleaning up node_modules on Mac is often the next biggest win after Docker. For a broader audit of everything eating your disk — Xcode DerivedData, Gradle caches, Cargo build artifacts, pip wheels, and more — a tool like Crumb can audit all of these at once and show what is safe before you delete.
- Xcode derived data:
~/Library/Developer/Xcode/DerivedData - Gradle build cache:
~/.gradle/caches - Cargo build artifacts:
~/.cargo/registryand~/.cargo/git - Maven local repository:
~/.m2/repository - pip wheel cache:
~/Library/Caches/pip - CocoaPods cache:
~/Library/Caches/CocoaPods
None of these show up under macOS's built-in storage report because they live in locations the OS does not categorize as user data. For a fuller picture of what the system-level storage breakdown is hiding, see what "System Data" means on Mac storage.
Shrinking the Docker.raw Disk Image After Pruning
There is one more step that most guides miss. After you prune Docker data, the Docker.raw sparse image does not automatically return space to macOS. The Linux VM has freed the blocks internally, but the .raw file on your APFS volume stays the same allocated size until Docker reclaims it.
To trigger reclamation, open Docker Desktop, go to Settings > Resources > Advanced, and click Reclaim disk space. This runs an fstrim inside the VM and tells APFS that the underlying blocks are now unused, allowing macOS to report that space as truly available in Finder and System Settings.
On Docker Desktop 4.x and later, you can also trigger this from the CLI:
docker run --privileged --rm docker/desktop-reclaim-space
After this step, open System Settings > General > Storage and you should see the freed gigabytes reflected in the actual available space bar.