How to Compact a WSL2 Virtual Disk to Reclaim Disk Space
A complete diskpart walkthrough for shrinking a WSL2 distro's .vhdx file after deleting large data, since Windows never reclaims that space on its own.
Because WSL2’s virtual disk grows dynamically but doesn’t automatically shrink back down after you delete files inside it, reclaiming that space requires a specific, deliberate compaction process — this walks through doing it correctly.
Step 1: identify which distro’s disk you want to compact
wsl --list --verbose
Step 2: find the exact .vhdx file location
Get-ChildItem -Path "$env:LOCALAPPDATA\Packages" -Recurse -Filter "ext4.vhdx" -ErrorAction SilentlyContinue
This searches for the virtual disk file across installed distro packages — note the specific path for the distro you intend to compact.
Step 3: shut down WSL completely first
wsl --shutdown
The virtual disk cannot be compacted while mounted and in active use — this step is mandatory, not optional.
Step 4: open diskpart as Administrator
diskpart
Step 5: select the virtual disk file
select vdisk file="C:\Users\YourName\AppData\Local\Packages\CanonicalGroupLimited.Ubuntu...\LocalState\ext4.vhdx"
Use the exact path identified in Step 2.
Step 6: attach it in read-only mode
attach vdisk readonly
Attaching read-only is specifically required for the compact operation — this doesn’t modify or risk your data, it’s a prerequisite for the shrink operation itself.
Step 7: run the actual compaction
compact vdisk
This is the step that actually reclaims space — it can take anywhere from seconds to several minutes depending on the virtual disk’s current size.
Step 8: detach and exit diskpart
detach vdisk
exit
Step 9: verify the file size actually decreased
Get-Item "C:\Users\YourName\AppData\Local\Packages\...\LocalState\ext4.vhdx" | Select-Object Length
Compare against the size before compaction to confirm space was genuinely reclaimed.
Step 10: restart your distro normally
wsl -d Ubuntu
Confirm your distro still starts and your files are all intact — compaction only affects the underlying file’s physical size, not its actual logical content.
Step 11: consider scripting this for repeated use
# save the diskpart commands from steps 5-8 as a .txt script
# and run: diskpart /s compact-script.txt
For anyone doing this regularly (after large builds, container image cleanup, or dataset work), scripting the diskpart commands avoids retyping the same steps each time.
Why this manual process is necessary rather than automatic
WSL2’s dynamically-expanding virtual disk format prioritizes fast, simple growth over automatic shrinkage — reclaiming freed space requires this explicit compaction step specifically because that’s how this class of virtual disk technology works generally, not because of anything WSL-specific that could easily be automated away without added complexity elsewhere in the system.
Preflight checklist
This procedure is the controlled offline runbook, not the diagnostic explanation. Before starting, update WSL, close Linux shells and Windows applications using \\wsl.localhost, stop databases cleanly, and create a verified export of irreplaceable data. Note the VHD’s current byte size so the result is measurable. Confirm the exact distribution name:
wsl --list --verbose
wsl --status
Inside the distribution, delete only data you have reviewed, then confirm filesystem free space. Container engines often keep images, build cache, and volumes even after application files are removed.
Offline DiskPart workflow
Stop all WSL distributions from an elevated PowerShell window:
wsl --shutdown
Confirm no terminal or integration immediately restarts WSL. Start diskpart, then select the exact VHDX using its full path:
select vdisk file="C:\path\to\ext4.vhdx"
detail vdisk
attach vdisk readonly
compact vdisk
detach vdisk
exit
detail vdisk is the deliberate guardrail: verify the selected object before attachment. Read-only attachment prevents filesystem writes during this host-side operation. Microsoft documents that compact vdisk reduces the physical size of a dynamically expanding VHD; it does not change the guest filesystem’s logical capacity.
Verification and rollback
Compare the Windows file size with the recorded baseline, start the distribution, and check it:
wsl -d <DistributionName>
df -h /
dmesg | tail -n 50
Open representative projects and test any database or container workload that was stopped. If the disk will not attach, do not force it: re-run wsl --shutdown, identify the process holding the file, and validate the path. If the distribution fails after maintenance, preserve the VHD and logs; do not unregister it. Restore from the verified export into a different distribution name so the original remains available for recovery.
Newer WSL versions may expose sparse-disk management documented by Microsoft. Prefer the command supported by the installed wsl --version; do not copy an experimental flag from an old issue into production automation. Schedule compaction only when measured growth justifies downtime, and always serialize it against backups, updates, and container activity.
Primary references: Microsoft WSL disk-space documentation, DiskPart select vdisk, DiskPart compact vdisk.
Automation guardrails
Do not put these commands in an unattended loop that guesses VHD paths. A safe wrapper should accept an allow-listed distribution, refuse to run while WSL is active, verify a recent backup, record pre/post size, capture DiskPart output, and stop on any selection or attachment error. It should never call unregister as cleanup. On shared workstations, coordinate downtime because wsl --shutdown stops every running distribution, not only the disk being compacted.
Keep the maintenance log with the WSL version and Windows build. That evidence makes a later failure diagnosable and prevents an old sparse-disk workaround from surviving after Microsoft changes the supported workflow.
Related:
- Fixing a WSL2 Virtual Disk That Won’t Shrink After Deleting Files
- How WSL2’s Virtual Disk Actually Grows (and Why It Won’t Shrink on Its Own)
Sources: