Published by TekOnline
Date: 20 May 2026
Docker Desktop on Windows is convenient, especially with the WSL 2 backend. It is also very easy for it to quietly consume a lot of disk space.
Recently, we hit a familiar problem: Docker looked like it had tens of gigabytes of unused data, but even after pruning images and build cache, Windows still showed Docker using around 60GB.
The culprit was not a normal folder full of files. It was Docker Desktop’s WSL virtual disk:
C:\Users\<USER>\AppData\Local\Docker\wsl\disk\docker_data.vhdx
This article explains why that file grows, why Docker cleanup alone is not enough, and the exact process we used to shrink it safely.
The Symptom
Docker was using a large amount of disk space:
docker system df
The initial report showed:
TYPE TOTAL ACTIVE SIZE RECLAIMABLE
Images 61 18 51.8GB 40.89GB (78%)
Containers 20 2 1.047GB 1.047GB (99%)
Local Volumes 35 11 4.513GB 2.847GB (63%)
Build Cache 653 0 17.14GB 17.14GB
That looked straightforward: prune unused images and build cache.
After cleanup, Docker’s internal usage dropped substantially:
TYPE TOTAL ACTIVE SIZE RECLAIMABLE
Images 20 18 13.78GB 1.575GB (11%)
Containers 20 2 1.047GB 1.047GB (99%)
Local Volumes 35 11 4.513GB 2.847GB (63%)
Build Cache 0 0 0B 0B
But Windows still showed the Docker VHDX at about 60GB:
C:\Users\<USER>\AppData\Local\Docker\wsl\disk\docker_data.vhdx 60.44GB
That is the confusing part. Docker had freed space internally, but Windows had not reclaimed the physical disk space.
Why This Happens
Docker Desktop on Windows stores Linux container data inside WSL 2. WSL 2 stores its filesystem in a dynamically expanding virtual disk file, a VHDX.
Dynamic VHDX files grow as data is written. They do not necessarily shrink when files are deleted inside Linux. So there are two separate cleanup jobs:
- Remove unused Docker objects inside Docker.
- Trim and compact the WSL VHDX so Windows can reclaim the freed blocks.
Docker prune commands only handle the first job.
This is why you can delete images, containers, and build cache, then still see a huge docker_data.vhdx file on the Windows side.
Step 1: Check What Docker Can Reclaim
Start with Docker’s own disk usage report:
docker system df
This tells you how much space is used by:
- Images
- Containers
- Volumes
- Build cache
Volumes need special care. They often contain database files, uploads, local development state, or other data you may not be able to recreate. We did not prune volumes automatically.
Step 2: Prune Unused Images and Build Cache
We removed unused images:
docker image prune -a -f
Then removed build cache:
docker builder prune -a -f
You can also use docker system prune, but be deliberate with flags. In particular, avoid --volumes unless you have confirmed that unused volumes are disposable.
Docker’s own documentation notes that volumes are not removed automatically because doing so can destroy data.
Step 3: Find the Actual VHDX File
To locate Docker’s VHDX files:
Get-ChildItem -Path "$env:LOCALAPPDATA\Docker" -Force -Recurse -Include *.vhdx,*.vhd -ErrorAction SilentlyContinue |
Select-Object FullName,@{Name='SizeGB';Expression={[math]::Round($_.Length/1GB,2)}} |
Sort-Object SizeGB -Descending
On our system, the large file was:
C:\Users\<USER>\AppData\Local\Docker\wsl\disk\docker_data.vhdx
It was still around 60GB after Docker pruning.
Step 4: Trim Free Blocks Inside WSL
Before compacting the VHDX from Windows, run fstrim inside Docker’s WSL distribution:
wsl -d docker-desktop -u root -- fstrim -av
This tells the Linux filesystem to mark free blocks as discardable. Without this step, Windows compaction may run but fail to reduce the VHDX file size.
Step 5: Stop Docker and WSL
The VHDX cannot be compacted while Docker or WSL has it open.
Stop Docker Desktop and related backend processes:
Get-Process | Where-Object { $_.ProcessName -match 'Docker|docker|com\.docker' } |
Stop-Process -Force -ErrorAction SilentlyContinue
Then shut down WSL:
wsl --shutdown
Start-Sleep -Seconds 10
Confirm Docker’s WSL distro is stopped:
wsl -l -v
If the distro is still running, compaction will likely fail with:
The process cannot access the file because it is being used by another process.
Step 6: Compact the VHDX
Run the compaction from an elevated PowerShell prompt.
Create a small DiskPart script:
$dockerVhdx = Join-Path $env:LOCALAPPDATA 'Docker\wsl\disk\docker_data.vhdx'
$script = Join-Path $env:TEMP 'compact-docker-vhdx.diskpart'
Set-Content -LiteralPath $script -Value @"
select vdisk file="$dockerVhdx"
attach vdisk readonly
compact vdisk
detach vdisk
exit
"@ -Encoding ASCII
diskpart /s $script
Remove-Item -LiteralPath $script -Force
On our machine, the first compaction attempt failed because Docker still had the file open. After fully stopping Docker Desktop, Docker backend processes, and WSL, DiskPart completed successfully.
The result:
Before: 60.44GB
After: 24.46GB
That recovered roughly 36GB of disk space.
Step 7: Restart Docker Desktop
After compaction:
Start-Process "$env:ProgramFiles\Docker\Docker\Docker Desktop.exe"
Then verify Docker is back:
docker info --format '{{.ServerVersion}}'
Why We Avoided Sparse VHD Mode
Recent WSL versions include a sparse VHD option:
wsl --manage docker-desktop --set-sparse true
On our system, WSL refused to enable it and printed a warning that sparse VHD support was disabled due to potential data corruption. It suggested an --allow-unsafe flag.
We did not use that option. For a production or client machine, anything explicitly labelled unsafe should require careful review, backups, and manual opt-in.
Is This a Known Issue?
Yes. This is a well-known behaviour of Docker Desktop on Windows with WSL 2:
- WSL 2 VHDX files grow as data is written.
- Deleting Docker data does not guarantee the host VHDX shrinks.
- Docker prune cleans Docker’s internal objects, not the Windows virtual disk file.
- A full reclaim usually requires prune, trim, shutdown, and VHDX compaction.
Microsoft documents WSL disk behaviour and management. Docker documents pruning and the location of Docker Desktop’s disk image. There are also many community reports on Stack Overflow, GitHub, Reddit, and technical blogs describing the same issue.
Is There an Opportunity for a Tool?
Yes. This is low-hanging fruit for a small open-source Windows utility.
The tool should not blindly delete data. The valuable version would be conservative and transparent:
- Show Docker internal usage from
docker system df. - Show the physical size of
docker_data.vhdx. - Explain why those numbers differ.
- Prune unused images and build cache by default.
- Leave volumes alone unless explicitly requested.
- Run
fstriminside Docker’s WSL distro. - Stop Docker Desktop and WSL cleanly.
- Compact the VHDX using
diskpart,Optimize-VHD, or the Windows VirtDisk API. - Restart Docker Desktop.
- Show before and after sizes.
A safe command-line interface could look like this:
.\docker-vhdx-shrink.ps1
By default, it should print a plan and ask before making changes.
An advanced mode could be:
.\docker-vhdx-shrink.ps1 -PruneImages -PruneBuildCache -Trim -Compact -RestartDocker
The tool should avoid:
- Pruning Docker volumes by default.
- Using WSL
--allow-unsafeautomatically. - Killing unrelated WSL distributions without permission.
- Unregistering Docker WSL distributions.
- Assuming Hyper-V
Optimize-VHDis installed.
This is exactly the type of small utility that would save developers and IT teams time, as long as the defaults are safe.
Practical Takeaway
If Docker Desktop on Windows says it has freed space but your disk is still full, check the VHDX file. You probably need to compact Docker’s WSL virtual disk after pruning.
The short version is:
docker system df
docker image prune -a -f
docker builder prune -a -f
wsl -d docker-desktop -u root -- fstrim -av
wsl --shutdown
Then compact:
diskpart
select vdisk file="C:\Users\<USER>\AppData\Local\Docker\wsl\disk\docker_data.vhdx"
attach vdisk readonly
compact vdisk
detach vdisk
exit
Run the compaction elevated, and make sure Docker Desktop is fully stopped first.
Sources
- Docker Docs: Prune unused Docker objects
https://docs.docker.com/engine/manage-resources/pruning/ - Docker Docs:
docker buildx prune
https://docs.docker.com/reference/cli/docker/buildx/prune/ - Docker Docs: Docker Desktop settings and disk image location
https://docs.docker.com/desktop/settings-and-maintenance/settings/ - Docker Docs: Docker Desktop backup and
docker_data.vhdx
https://docs.docker.com/desktop/settings-and-maintenance/backup-and-restore/ - Microsoft Learn: Manage WSL disk space
https://learn.microsoft.com/en-us/windows/wsl/disk-space - Microsoft WSL GitHub issue about sparse VHD warning
https://github.com/microsoft/WSL/issues/13075 - Stack Overflow: Docker Desktop WSL VHDX too large
https://stackoverflow.com/questions/70946140/docker-desktop-wsl-ext4-vhdx-too-large - Stack Overflow: Resize Docker Desktop WSL2 disk usage
https://stackoverflow.com/questions/77062392/how-to-properly-resize-disk-usage-in-docker-desktop-wsl2 - Community guide: Shrink WSL2 and Docker virtual disks
https://mcdaqc.github.io/blog/2025/shrink-wsl2-docker-virtual-disks/
Leave a Reply