Docker cleanup can be misleading on Windows with WSL2.
You can delete images and caches, but still see almost no free-space gain on C:.
This happened because Docker data lived inside a large virtual disk:
C:\Users\<you>\AppData\Local\Docker\wsl\disk\docker_data.vhdx
The fix was:
- Clean unused Docker data
- Stop Docker + WSL
- Compact the VHDX file
Why This Happens
docker system prune frees space inside the Linux filesystem, but Windows may keep the .vhdx file at its old size until it is compacted.
So Docker says usage is low, but C: still looks full.
Step 1: Check Usage
Run in PowerShell:
Get-PSDrive -Name C | Select-Object Name,@{n='UsedGB';e={[math]::Round($_.Used/1GB,2)}},@{n='FreeGB';e={[math]::Round($_.Free/1GB,2)}}
docker system df
Get-Item "$env:LOCALAPPDATA\Docker\wsl\disk\docker_data.vhdx" | Select-Object FullName,@{n='SizeGB';e={[math]::Round($_.Length/1GB,2)}}
Step 2: Prune Docker Safely
This removes unused objects (not running containers):
docker system prune --volumes -f
docker image prune -a -f
docker builder prune -a -f
Optional trim inside Docker distro:
wsl -d docker-desktop -u root sh -lc "fstrim -v /mnt/docker-desktop-disk || true; fstrim -v / || true"
Step 3: Compact docker_data.vhdx (Important Step)
Open PowerShell as Administrator and run:
$dockerCli = Join-Path $env:ProgramFiles 'Docker\Docker\DockerCli.exe'
$dockerDesktop = Join-Path $env:ProgramFiles 'Docker\Docker\Docker Desktop.exe'
$vhd = Join-Path $env:LOCALAPPDATA 'Docker\wsl\disk\docker_data.vhdx'
$dp = Join-Path $env:TEMP 'docker-compact.txt'
if (Test-Path $dockerCli) { & $dockerCli -Shutdown }
wsl --shutdown
@"
select vdisk file="$vhd"
attach vdisk readonly
compact vdisk
detach vdisk
exit
"@ | Set-Content -Path $dp -Encoding ascii
diskpart /s $dp
Start-Process $dockerDesktop
Notes:
diskpartcompaction can take a while (progress may appear to pause).- Keep Docker/WSL stopped until compaction is complete.
- You may get a UAC prompt or admin permission requirement.
Step 4: Verify Results
Get-PSDrive -Name C | Select-Object Name,@{n='UsedGB';e={[math]::Round($_.Used/1GB,2)}},@{n='FreeGB';e={[math]::Round($_.Free/1GB,2)}}
docker system df
Get-Item "$env:LOCALAPPDATA\Docker\wsl\disk\docker_data.vhdx" | Select-Object @{n='SizeGB';e={[math]::Round($_.Length/1GB,2)}}
In my case, this was the step that finally returned the big chunk of space to C: (ending around 99 GB free).
Bonus: Other Easy Space Wins
Also check these common heavy hitters:
C:\Users\<you>\Downloads(old installers,.zip,.partfiles)C:\Users\<you>\AppData\Roaming\Cursor\User\globalStorage(largestate.vscdbbackups)- Large media in
OneDriveandVideos
Useful commands:
npm cache clean --force
dotnet nuget locals all --clear
pip cache purge
Quick Summary
- Docker cleanup alone is often not enough on Windows + WSL2
- The real reclaim is usually VHDX compaction
- Compacting
docker_data.vhdxafter prune is the key move
Leave a Reply