How WSL2's Virtual Disk Actually Grows (and Why It Won't Shrink on Its Own)
Each WSL2 distro lives inside a dynamically-expanding .vhdx file that grows with use but never shrinks back down automatically after deletions.
Every WSL2 distro’s entire Linux filesystem lives inside a single .vhdx (Virtual Hard Disk) file on your Windows drive — understanding how that file actually grows, and specifically why it doesn’t shrink automatically, explains a genuinely common source of “where did my disk space go” confusion.
What a .vhdx file actually is here
VHDX is a Microsoft virtual disk image format, the same general technology Hyper-V uses for full virtual machines — for WSL2, each installed distro gets its own .vhdx file (typically under %LocalAppData%\Packages\...) that Linux, running inside the WSL2 VM, sees and formats as a normal ext4 filesystem.
Why it starts small and grows automatically
WSL2’s .vhdx files use dynamic expansion — the file starts small and grows on disk as you actually write data inside the Linux filesystem, rather than pre-allocating its maximum possible size upfront. This means a fresh distro install consumes relatively little actual disk space on the Windows side, growing only as you genuinely use it.
The part that surprises people: it doesn’t shrink back automatically
Deleting a large file, or an entire directory, from inside your WSL distro frees that space within the ext4 filesystem inside the virtual disk — but the underlying .vhdx file on the Windows side generally does not automatically shrink back down to reflect that freed space. The virtual disk’s on-disk file size reflects its historical peak usage, not its current actual content size.
Why this isn’t a bug, just how dynamic VHD expansion works
Dynamically expanding virtual disk formats generally grow readily but require an explicit, deliberate compaction step to reclaim space after deletions — this is standard behavior for this class of virtual disk technology generally, not a WSL-specific oversight, and the same general behavior shows up in other VHD/VHDX-based virtualization contexts too.
What compaction actually requires
Reclaiming that unused space requires an explicit compaction operation using Windows’s own diskpart utility (or newer, more convenient WSL-specific tooling), specifically telling the underlying virtual disk format to shrink its physical file size down to match its actual current content — the exact steps for this are covered in this blog’s dedicated how-to guide.
Why this matters especially for large, transient data
Workflows that temporarily generate a large amount of data inside a WSL distro — building large projects, working with sizable datasets, container images pulled and later removed — can leave the .vhdx file substantially larger than the distro’s actual current content for a long time afterward, unless compaction is performed deliberately.
Why understanding this prevents a common, confusing troubleshooting dead-end
Without understanding this dynamic-expansion-without-auto-shrink behavior, “my C: drive is nearly full, but WSL’s actual files don’t add up to that much space” looks like a mystery — once you know the .vhdx file’s on-disk size reflects historical peak usage rather than current content, the actual fix (compaction, not searching Linux-side for phantom files) becomes obvious.
Confirming the gap directly before troubleshooting further
Rather than relying on the general explanation alone, confirm the actual gap on your own machine. From inside the distribution, df -h / reports Linux’s own view of used and free space on the ext4 filesystem. From Windows, checking the .vhdx file’s properties (or Get-Item in PowerShell) reports its current on-disk size. A large gap between what Linux reports as actually used and what the .vhdx file’s size shows on Windows is the concrete, measurable evidence of exactly the behavior described above — useful both for confirming this is genuinely what’s happening on your system and for judging how much space compaction would actually reclaim before spending time on it.
Why container workloads make this especially pronounced
Docker Desktop’s WSL2 backend, and any container tooling running directly inside a WSL distribution, stores image layers, build cache, and volumes inside that same .vhdx-backed filesystem. Because container workflows routinely pull, build, and discard large images in quick succession, they’re one of the most common sources of a .vhdx file growing substantially larger than a user’s own project files would suggest — docker system prune reclaiming space inside the Linux filesystem still leaves the outer .vhdx file at its previously grown size until a separate compaction pass runs.
The APFS and other virtual-disk comparison
This isn’t a WSL-specific design flaw — it’s a general property of dynamically-expanding virtual disk formats, including VHD/VHDX usage in Hyper-V generally and comparable sparse-disk formats in other virtualization platforms. Any system relying on a similarly dynamic disk format faces the same fundamental trade-off: fast, low-overhead growth in exchange for requiring an explicit step to reclaim space, rather than transparent, automatic shrinkage that would need to continuously track and compact free space in the background at a real, ongoing performance cost.
What compaction can’t reclaim, and why that matters
Compaction shrinks the .vhdx file down to match blocks the guest filesystem has actually marked free — it cannot reclaim space the guest still considers allocated, even if that data is logically redundant from your perspective (an old container image layer nobody references anymore, a build cache your tools would happily regenerate). Clearing that data from inside Linux first, confirming with df -h that Linux itself now reports it as free, is the necessary precondition before compaction has anything meaningful to reclaim — running compaction against a .vhdx whose guest filesystem still considers everything allocated will predictably reclaim little or nothing, which is a sign to look inside the distribution rather than assume compaction itself failed.
Checking a specific distro’s actual .vhdx size directly
Rather than reasoning about disk space abstractly, locate and check the specific file:
Get-ChildItem -Path "$env:LOCALAPPDATA\Packages" -Recurse -Filter "ext4.vhdx" -ErrorAction SilentlyContinue | Select-Object FullName, Length
Comparing this reported length against df -h / run inside the corresponding distribution gives the exact, concrete gap for your own machine, rather than relying on the general explanation alone — a genuinely useful first step before deciding whether compaction is worth the time it takes on a specific distro.
Related:
- How to Compact a WSL2 Virtual Disk to Reclaim Disk Space
- Fixing a WSL2 Virtual Disk That Won’t Shrink After Deleting Files
Sources: