How to Clear the Docker Build Cache (and When Not To)
The build cache is not stored in your images, so deleting images does not touch it. It has its own command, and on a busy machine it is usually the largest single thing Docker is holding.
BuildKit keeps the result of every build step so a rebuild can skip work that has not changed. That cache lives separately from images and containers, which is why docker image prune can free nothing while docker system df still reports tens of gigabytes in use.
There are two commands depending on which builder you used, and one common mistake that clears nothing at all.
See what it is actually using first
docker system df
TYPE TOTAL ACTIVE SIZE RECLAIMABLE
Images 42 3 12.4GB 9.8GB (79%)
Containers 5 1 1.2GB 980MB (81%)
Local Volumes 8 2 3.1GB 2.4GB (77%)
Build Cache 214 0 31.7GB 31.7GBClear it
# The build cache, and nothing else
docker builder prune # dangling cache only, prompts first
docker builder prune -a -f # everything, no prompt
# If you build with buildx (the default for docker build since v23)
docker buildx prune -a -f
# Only what has not been touched in a week
docker builder prune --filter until=168hThe mistake: --no-cache does not clear the cache
docker build --no-cache tells one build to ignore what is already cached. It does not delete anything, and the build it runs then writes a fresh set of cache entries on top of the old ones, so disk usage goes up rather than down. If the goal is free space, prune. If the goal is a clean rebuild because you suspect a stale layer, --no-cache is right and the space question is separate.
Which command for which problem
| You want to | Command | Also removes |
|---|---|---|
| Free build cache only | docker builder prune -a | Nothing else |
| Free everything unused | docker system prune -a --volumes | Stopped containers, unused images, unused volumes and networks |
| Rebuild ignoring cache | docker build --no-cache | Nothing, and adds more cache |
| Cap the cache instead of clearing it | docker buildx prune --max-used-space 20GB | Nothing else |
In CI this is a different problem entirely
On an ephemeral runner there is no cache to clear, because the machine is new. The problem there is the opposite one: every build starts cold and pays full price for layers that have not changed. The fix is an external cache backend rather than a prune command, and it is worth setting up before you optimise anything else about a container build.
Measure before you optimise
Pipeline optimisation usually targets the step people assume is slow. Get the real per-step timings first, because the answer is frequently dependency install or a cold cache rather than the build itself.
# per-job timings for the last 20 runs
gh run list --limit 20 --json databaseId,conclusion,createdAt,updatedAt \
--jq '.[] | "\(.conclusion)\t\(.createdAt)\t\(.updatedAt)"'
# per-step timing inside one run
gh run view <run-id> --log | grep -E "^\S+\s+.*Run |##\[group\]" | head -40Frequently asked questions
How do I delete the Docker build cache?
docker builder prune -a -f, or docker buildx prune -a -f if you build through buildx. Without -a only dangling entries are removed, which on a machine that builds the same project repeatedly is often a small share of the total.Why is my disk still full after docker image prune?
image prune does not touch it. Run docker system df and look at the Build Cache row; on a development machine it is frequently larger than every image combined.Does docker build --no-cache clear the cache?
Is it safe to clear the build cache?
How do I stop the build cache growing without pruning it constantly?
docker buildx prune --max-used-space 20GB, or configure the limit on the builder itself. That keeps the recent, useful entries and discards the rest automatically.