Two architectures, two storage models
WSL1 has no Linux kernel at all: it translates Linux system calls into Windows ones in real time, and its files sit in a normal folder — historically %LOCALAPPDATA%\Packages\<Distro>\LocalState\rootfs — fully visible to Windows tools. That makes it light on disk and fast when scripts touch files on /mnt/c, but the translation is incomplete: Docker, systemd and anything needing exotic syscalls does not work. WSL2 runs a real Linux kernel in a lightweight utility VM, which fixes compatibility, but the distro's entire filesystem now lives inside an ext4.vhdx — a virtual disk image that Windows mounts but does not interpret.
The vhdx is stored under %LOCALAPPDATA%\Packages for Store-installed distros and under %LOCALAPPDATA%\wsl for more recent installs, and it has one nasty property: it grows on demand and never shrinks on its own. Deleting files inside the distro frees space inside the virtual disk, but the .vhdx file keeps its high-water mark until you compact it. Checking the file size in Explorer right after a big cleanup inside the distro is the classic disappointment: the number has not moved.
Where each one hides its gigabytes
Neither version cleans up after itself, and the space disappears into surprisingly few places:
- The WSL2 ext4.vhdx — every distro has one; a Docker-heavy dev setup routinely pushes it past 30 GB
- Docker Desktop's own data disk (docker_data.vhdx), which follows the same grow-only rule
- The WSL1 rootfs folder — modest by comparison, but old abandoned distros still hold their full install
- Linux package and build caches inside the distro — apt caches, node_modules, target/ and build folders that inflate the vhdx permanently
- wsl --export backups and downloaded distro images parked in Downloads and forgotten
Reclaiming space without breaking the distro
Clean inside first: apt autoremove and apt clean, docker system prune in Docker Desktop, npm and pip cache purges — anything that empties the virtual disk before you shrink its container. Then run wsl --shutdown, because a running distro locks its vhdx, and compact the image: Optimize-VHD with the -Mode Full option if you have Hyper-V tooling, or diskpart with select vdisk file="<path>", attach vdisk, compact vdisk, detach vdisk on any Windows. Recent WSL versions offer wsl --manage <Distro> --set-sparse true, which lets the vhdx release space automatically — a genuinely better long-term setting.
Two last resorts deserve their names. wsl --export packs the distro into a .tar you can import on another drive with wsl --import, which is the clean way to move a WSL2 install off a full C:. And wsl --unregister <Distro> deletes the distro and its vhdx entirely — that command has no undo, so treat it as the nuke it is. While you are at it, cap the VM's appetite with a .wslconfig file limiting memory and processors; idle WSL2 VMs otherwise hold gigabytes of RAM for nothing.
Questions and Answers
How do I shrink the WSL2 ext4.vhdx file?
Clean up inside the distro first, run wsl --shutdown, then compact the vhdx with diskpart (select vdisk file, attach vdisk, compact vdisk, detach vdisk) or Optimize-VHD. On recent WSL, wsl --manage <Distro> --set-sparse true makes the disk release space automatically.
Should I use WSL1 or WSL2?
WSL2 is the default and the only choice for Docker, systemd and anything needing a real kernel. WSL1 still wins for light command-line work that mostly reads and writes files on your Windows drives — no VM, no vhdx, no memory overhead.
Know what is included before you buy.
The one-time 30-minute trial covers core tools. PRO-labelled features stay locked until a paid license is activated.
Read next
Write to us: [email protected]