Docker stores images, containers, volumes, and build cache. BuildKit's intermediate layers speed up repeat builds but accumulate over time. This article covers diagnosis and selective cleanup. All numbers and command output are an illustrative snapshot from one Ubuntu system; your results will differ.
Identify the source of disk usage
docker info --format '{{.DockerRootDir}}'
df -h
docker system df
Record the available space reported by df -h for the filesystem containing Docker's data directory. For bind mounts, also check the filesystems containing the corresponding host directories: their data is not included in Local Volumes.
TYPE TOTAL ACTIVE SIZE RECLAIMABLE
Images 21 13 12.64GB 3.146GB (24%)
Containers 13 13 712.7kB 0B (0%)
Local Volumes 1 1 68.07MB 0B (0%)
Build Cache 857 0 281.3GB 19.79GB
TYPE is the category; TOTAL is the object count; ACTIVE is the count in use; SIZE is the accounted size; RECLAIMABLE is Docker's cleanup estimate, not a guarantee of increased free space.
Images: 13 of 21 images are used by containers. Docker estimates 3.146 GB asRECLAIMABLEfor images, but the actual disk-space gain may differ. Unused images may include versions kept for rollback.Containers: all 13 are active; their writable layers occupy 712.7 kB. Logs and data in volumes or bind mounts are excluded from this size; check them separately with the logging driver and mount paths in mind.Local Volumes: the only volume (68.07 MB) is used by a container and may hold persistent application or database data; do not remove it. Bind mounts are excluded.Build Cache: 857 entries account for 281.3 GB of cache. TheRECLAIMABLEfigure here is Docker's estimate, not a promise to free 19.79 GB on disk.
Inspect images and containers
docker system df -v shows image sizes, shared and unique layers, the number of containers using each image, container writable layers, volumes, and cache entries. In its image table, SIZE is the full logical size, SHARED SIZE is the layers shared with other images, UNIQUE SIZE is image-only data, and CONTAINERS is the number of containers using the image. Do not add image sizes: several .NET applications, for example, may share one .NET Runtime layer. Removing one image will not free a layer that another still needs.
docker system df -v
docker ps -a --size
Example container size: 24.6kB (virtual 279MB). The first value is its writable layer; virtual includes the base image. Do not add virtual values across containers because layers may be shared. docker ps -a --size excludes logs, volumes, and bind mounts, so it does not show the container's full associated disk usage.
If IMAGE shows an ID such as 8e12852cff3c instead of a name, its tag was usually moved to a newer image or lost. A running container still retains the original image and the layers it needs.
Check for unused objects
docker container ls -a --filter status=exited
docker image ls --filter dangling=true
docker volume ls --filter dangling=true
The first command finds containers with the exited status; a header-only result means there are none. The second finds dangling images: images without a name or tag, often left after a rebuild. The third lists volumes with no container references, both anonymous and named. An empty result means there are no objects matching that filter. All three lists were empty in the illustrative snapshot.
Understand the BuildKit cache
For the standard Docker Engine builder (default), run:
docker buildx du --builder default
Shared: 261.5GB
Private: 19.79GB
Reclaimable: 281.3GB
Total: 281.3GB
Shared is data also used by other resources, usually images; an asterisk after an individual entry's size (1.372GB*) means the same. Deleting the cache entry leaves the layer on disk while an image still needs it. Private is data not shared in this way: 19.79 GB is only a guide to possible cleanup. Reclaimable is the logical size of entries eligible for deletion; true in an individual entry's RECLAIMABLE column means it is not currently in use. Total is the overall logical cache size.
docker system df and docker buildx du account for resources differently. Removing 281.3 GB of logical cache does not guarantee the same gain in free space: images retain shared layers, and other disk activity affects the result. Compare df -h on the same filesystem before and after for the actual difference.
Clean up build cache
For unused cache from the standard Docker Engine builder:
docker builder prune -a
Docker asks for confirmation. This removes unused BuildKit cache but does not stop or remove running containers, volumes, or application images. Subsequent builds may be slower while dependencies and intermediate layers are recreated.
To keep recently used cache, limit cleanup to entries unused for 7 or 14 days:
docker builder prune -a --filter "until=168h"
docker builder prune -a --filter "until=336h"
Clean up images and volumes if needed
Images
docker image prune
docker image ls
docker image prune -a
docker image prune removes only dangling images and will reclaim almost nothing if that list is empty. Before docker image prune -a, review docker image ls: -a removes all images unused by existing containers, including named SDK images, base images kept for future builds, and application versions retained for rollback. Docker estimated 3.146 GB of such images in the snapshot; the actual disk space gained may differ.
Volumes
docker volume ls --filter dangling=true
docker volume prune
By default, docker volume prune removes only unused anonymous local volumes with no container references. The docker volume ls --filter dangling=true list is broader: it also includes unused named volumes. docker volume prune --all adds them to cleanup. Volumes may contain databases, uploaded files, and application state; remove them only after confirming the data is no longer needed. If the list is empty, no volume cleanup is needed.
Verify the result
docker buildx du --builder default
docker system df
df -h
Compare the same builder and filesystem with the pre-cleanup state. The cache entry count may fall, and Private may decrease if unique entries were removed; running containers will keep working. The actual free-space gain appears in df -h and may differ from Docker's estimates.