Why WSL2 and Docker Eat Your Disk: How to Shrink ext4.vhdx
The Virtual Disk Grows, and Never Shrinks on Its Own
Short answer: WSL2 keeps its entire Linux filesystem in a virtual disk called `ext4.vhdx`. That file grows on demand but does NOT shrink when you delete files inside it. To reclaim the space, first clear data inside the distribution, then run `wsl --shutdown` and compact the disk with `diskpart`.
This is the single most common cause of "my C drive is full and I cannot find what is using it" on a developer machine. Disk analysis tools show you one 80 GB file and you hesitate to touch it — because deleting it would take your whole Linux environment with it. This guide explains what that file is, how to shrink it safely, and how to stop it from ballooning again.
Key Takeaways
- WSL2 stores your whole Linux filesystem in a single `ext4.vhdx` virtual disk that grows but never shrinks automatically.
- The file usually sits at `%LOCALAPPDATA%\Packages\<distro>\LocalState\ext4.vhdx`; Docker Desktop keeps its own `docker_data.vhdx`.
- Order matters: delete data INSIDE the distribution first, then compact the virtual disk. Compacting only returns space that is already free inside.
- For Docker, `docker system prune -a --volumes` alone often frees tens of gigabytes.
- `wsl --shutdown` is mandatory before compacting; the file cannot be shrunk while it is in use.
- On WSL 2.0 and later, adding `sparseVhd=true` to `.wslconfig` lets the disk shrink itself over time.
Why It Grows but Never Shrinks
WSL2 is a real virtual machine, and it keeps the whole Linux filesystem in one file on the Windows side: `ext4.vhdx`. It is a dynamically expanding virtual disk. With 5 GB of data inside, the file takes roughly 5 GB; write 60 GB and the file grows to 60 GB.
The problem starts in the other direction. Delete a 50 GB Docker image inside and Linux reports the space as free — but the VHDX file on Windows stays exactly the same size. The virtual disk format marks the freed blocks as unused without physically shortening the file. The result: `df -h` shows plenty of room inside while Windows reports a full C drive.
Docker Desktop on the WSL2 backend doubles the effect. Docker installs its own distribution and keeps images, layers and volumes in a separate `docker_data.vhdx`. On a development machine used for a couple of years, those two files together comfortably pass 100 GB.
Inside First: What to Delete Before Compacting
Compacting is not magic; it only returns blocks that are genuinely free inside. So the first step is always cleaning the distribution. On Debian and Ubuntu based distros, `sudo apt clean` removes the downloaded package cache and `sudo apt autoremove --purge` drops dependencies nothing needs any more.
If you use Docker, that is where the real win is. `docker system df` breaks down how much space images, containers, volumes and build cache each take. `docker system prune -a --volumes` removes everything not currently in use — note that this also deletes unused volumes, so export any database you want to keep first.
Build cache is often the largest line item and the easiest to overlook. `docker builder prune -a` targets only the cache and leaves your images alone. On Node.js projects, `node_modules` folders inside WSL plus `~/.npm` and `~/.cache` can add tens of gigabytes of their own.
Compacting: Giving the Space Back to Windows
Once the inside is clean, the virtual disk has to be physically shortened. The prerequisite is that WSL is fully stopped: run `wsl --shutdown` in PowerShell and close Docker Desktop if it is open. If any process still holds the file, compacting fails with an access-denied error.
In an elevated PowerShell, start `diskpart` and run these steps in order: `select vdisk file="C:\Users\name\AppData\Local\Packages\...\ext4.vhdx"`, then `attach vdisk readonly`, then `compact vdisk`, and finally `detach vdisk`. The read-only attach matters; if you mount the disk writable, compacting will not run.
On systems with the Hyper-V components installed there is a one-line alternative: `Optimize-VHD -Path "path\ext4.vhdx" -Mode Full`. That cmdlet is missing on Windows Home editions, which makes the `diskpart` route the safer default. When it finishes, the file size should be close to the real usage inside.
Stopping It From Happening Again
With WSL 2.0, Microsoft added support for sparse virtual disks. Add `sparseVhd=true` under an `[experimental]` heading in `%USERPROFILE%\.wslconfig`, run `wsl --shutdown`, and newly created disks begin shrinking themselves as space frees up inside. To convert an existing distribution, use `wsl --manage <distro> --set-sparse true`.
Two habits help on top of that. First, prune the Docker build cache on a schedule — running `docker builder prune -a` once a month is enough on most machines. Second, keep large datasets on the Windows side and reach them through `/mnt/c` instead of storing them in the WSL filesystem, so the data never inflates the virtual disk.
Spotting these files in the first place is its own problem, because they appear as a single file and folder-size tools do not make them stand out. Disk Mop's Large Files module sorts the biggest files on a drive by size, and `ext4.vhdx` usually lands in the top three. The Disk Treemap view shows the same file as one rectangle covering a large part of the screen.
Frequently Asked Questions
Can I just delete ext4.vhdx?
No. That file is your entire WSL distribution: installed packages, projects and databases all live inside it. Deleting it removes the distribution completely. The correct way to reclaim space is to clean the contents and then compact the disk.
Does compacting risk my data?
No. `compact vdisk` only discards unused blocks of the virtual disk file; it does not touch the data in the filesystem. Even so, shutting WSL down properly with `wsl --shutdown` first, and having a backup of critical projects, is a good habit.
Where is the Docker Desktop file?
On current Docker Desktop versions it is at `%LOCALAPPDATA%\Docker\wsl\disk\docker_data.vhdx`. Older versions ship a separate `docker-desktop-data` WSL distribution with the file at `%LOCALAPPDATA%\Docker\wsl\data\ext4.vhdx`.
With sparseVhd on, do I never need to compact again?
Usually not, but sparse disks reclaim gradually rather than instantly. After one very large deletion, a manual compact still gets you the space faster. Note also that `sparseVhd` applies automatically only to disks created after you enable it.
Verdict
WSL2 and Docker inflating your disk is not a bug, it is how virtual disks behave. The rule is simple: clean the inside, shut WSL down, compact the disk. Those three steps reclaim 20-60 GB in one go on most development machines.
For a lasting fix, turn on `sparseVhd=true` and prune the build cache regularly. If you want to see what else has quietly accumulated on the drive, Disk Mop's Large Files and Disk Treemap modules surface this kind of single-huge-file situation in seconds.
See what other giant files are hiding on your drive
One-time payment for lifetime access to all features. No subscription, no hidden fees.
Download Disk Mop Now