WSL2 Optimization

How to Shrink and Compact ext4.vhdx Without Data Loss

If you develop on Windows with WSL2 long enough, you’ll eventually notice your Linux disk file growing: the ext4.vhdx keeps expanding as you install packages, build projects, pull Docker images, and delete them. But unlike a native filesystem, deleting files doesn’t automatically return space to Windows. This guide shows you exactly How to Shrink and Compact ext4.vhdx Without Data Loss so you can reclaim tens (sometimes hundreds) of gigabytes safely. You’ll learn why the issue happens, what prerequisites you need, multiple ways to compact, how to keep it from growing unnecessarily, and how to troubleshoot related performance issues.

H2: Overview

The core of the problem: In WSL2, each distro lives inside a virtual disk file named ext4.vhdx. It expands as data is written. When you delete data inside the Linux filesystem, the file’s size on Windows does not automatically shrink. That’s normal for thin-provisioned virtual disks. The fix is a two-part process:

  • Inside WSL: Mark free space as reclaimable (e.g., via fstrim).
  • On Windows: Run a compaction tool that reclaims the free blocks from the VHDX.

Typical scenarios where you’ll need this:

  • You frequently build large projects (Node.js, Java, C/C++) and caches explode in size.
  • You use Docker with the WSL2 backend; pulling/pruning images and containers balloons docker-desktop-data.
  • You installed big SDKs or datasets, then deleted them.
  • You imported/exported distros and saw the file size jump.

This guide covers the recommended approach with fstrim + Optimize-VHD, a Docker-specific path, and a fully safe export/import method—along with newer WSL features that can help with automatic reclamation.

H2: Quick Reference Table

Command Purpose Example Output
wsl –status Show WSL version and kernel info Default Distribution: Ubuntu; Kernel version: 5.15.xx
wsl -l -v List distros and versions NAME STATE VERSION; Ubuntu Running 2
wsl –update Update WSL (Store version) Checking for updates… The operation completed successfully.
sudo fstrim -av Mark free space as discardable (TRIM) /: 12.4 GiB (13330321408 bytes) trimmed
wsl –shutdown Stop all WSL VMs so the VHDX is unlocked (no output)
Optimize-VHD -Path “C:…\ext4.vhdx” -Mode Full Windows-side compaction of the VHDX Progress bar or no output if run in script
diskpart → select vdisk file=… → compact vdisk Alternative compaction (varies by system) DiskPart successfully compacted the virtual disk file.
wsl –export Distro C:\path\backup.tar Safe backup/export of a distro Export in progress…
wsl –import NewDistro C:\path\NewDir C:\path\backup.tar –version 2 Re-import to a fresh VHDX Importing…
docker system prune -a Remove unused Docker data Total reclaimed space: 15.2GB

Note: Optimize-VHD is part of the Hyper-V PowerShell module (Management Tools). Prefer Optimize-VHD over diskpart for VHDX. If diskpart compact doesn’t work on your system, use Optimize-VHD.

H2: Key Concepts & Prerequisites

H3: What you need

  • Windows 10 2004 or later, or Windows 11. Windows 11 with the Microsoft Store version of WSL is recommended.
  • WSL2 distros (check with wsl -l -v).
  • Administrative rights on Windows to run compaction commands and enable features.
  • Optional but recommended: Hyper-V PowerShell module (Management Tools only) to get Optimize-VHD.
    • Turn Windows features on or off → Hyper-V → check “Hyper-V Management Tools” (you do NOT need “Hyper-V Platform” to use the PowerShell module).
  • Sufficient free space to create a backup copy of the VHDX before compacting (strongly recommended).
  • Basic command-line familiarity on both Windows PowerShell and Linux.

H3: Where to find ext4.vhdx

  • Store-installed distros: %LOCALAPPDATA%\Packages\\LocalState\ext4.vhdx
  • Imported distros: wherever you chose as the install directory.
  • Docker Desktop data: %LOCALAPPDATA%\Docker\wsl\data\ext4.vhdx (or a similar path under the Docker package).
See also  The Only .wslconfig Guide You Need (Memory/CPU/Swap for Stability)

H3: Why fstrim matters

fstrim tells the filesystem to discard blocks that are no longer used. Without this, the Windows compactor won’t know which blocks can be reclaimed and your ext4.vhdx won’t shrink much (or at all).

H3: Safety first

Compaction is safe when done correctly, but always:

  • Make a backup of ext4.vhdx before you start.
  • Ensure WSL is fully shut down to release the file lock (wsl –shutdown).
  • Avoid interruptions during compaction.

H2: Step-by-Step Guide

H3: 1) Verify your WSL status and version

Run these on Windows PowerShell:

wsl –status
wsl -l -v
wsl –update

  • Confirm your distro is on Version 2.
  • Update WSL so you have the latest features and bug fixes.

H3: 2) Free up space inside your distro

Open your WSL distro and remove unused data:

  • Package caches and logs:

sudo apt-get clean
sudo apt-get autoremove -y
sudo journalctl –vacuum-time=7d

  • Language/package managers:

npm cache clean –force
yarn cache clean
pip cache purge

  • Docker (if using Docker in WSL):

docker system prune -a
docker volume prune
docker builder prune -a

  • Find large folders/files:

sudo du -xh / | sort -h | tail -n 50

Remove what you don’t need.

H3: 3) TRIM free space with fstrim

In your WSL distro:

sudo fstrim -av

You should see output like:

/: 12.4 GiB (13330321408 bytes) trimmed

If fstrim isn’t available or doesn’t reclaim much space, you can zero-fill as a fallback (slower):

sudo dd if=/dev/zero of=~/zero.fill bs=64M || true
sync
rm ~/zero.fill
sync

Then run fstrim again:

sudo fstrim -av

H3: 4) Shut WSL down

Back in Windows PowerShell:

wsl –shutdown

Wait a few seconds. Ensure no Linux processes remain (e.g., vmmem should disappear in Task Manager).

H3: 5) Back up ext4.vhdx

Strongly recommended before compaction. Example:

Copy-Item “$env:LOCALAPPDATA\Packages\CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc\LocalState\ext4.vhdx” `
“$env:USERPROFILE\Desktop\ext4-backup-$(Get-Date -Format yyyyMMdd-HHmm).vhdx”

Adjust the path for your distro. If you are unsure of the path, search:

Get-ChildItem “$env:LOCALAPPDATA\Packages” -Directory |
Where-Object { $.Name -match “Ubuntu|Debian|openSUSE|kali|Arch” } |
ForEach-Object {
$vhd = Join-Path $
.FullName “LocalState\ext4.vhdx”
if (Test-Path $vhd) { “$($_.Name) => $vhd” }
}

H3: 6) Compact the VHDX on Windows (recommended: Optimize-VHD)

Load the Hyper-V module and run Optimize-VHD:

Import-Module Hyper-V
Optimize-VHD -Path “C:\Users\\AppData\Local\Packages\\LocalState\ext4.vhdx” -Mode Full

-Mode Full is thorough; -Mode Quick is faster but may reclaim less.

If you can’t install the Hyper-V module, try DiskPart (works on many systems):

diskpart
select vdisk file=”C:\Users\\AppData\Local\Packages\\LocalState\ext4.vhdx”
compact vdisk
exit

Note: DiskPart’s compact support for VHDX can vary. If it fails or reports no change, use Optimize-VHD.

H3: 7) Start WSL again and verify

Start your distro:

wsl -d

Check everything is intact (files, tools). Confirm the file size shrank:

Get-Item “C:\Users\\AppData\Local\Packages\\LocalState\ext4.vhdx” | Select-Object Name, Length, LastWriteTime

Compare Length to your backup copy or the size observed before compaction.

H3: 8) Optional: Compact Docker’s docker-desktop-data

Docker Desktop’s WSL2 backend stores images and layers in its own ext4.vhdx. To reclaim space:

  • In Docker Desktop: Settings → Resources → WSL Integration: disable temporarily, then exit Docker Desktop.
  • Free space within Docker (inside your Linux shell) first:

docker system prune -a
docker volume prune
docker builder prune -a

  • Shut down WSL:

wsl –shutdown

  • Compact the Docker vhdx (path may vary; common paths shown):

Optimize-VHD -Path “$env:LOCALAPPDATA\Docker\wsl\data\ext4.vhdx” -Mode Full

  • Restart Docker Desktop.

H3: 9) Alternative, bulletproof method: export, re-import (new, smaller VHDX)

If Optimize-VHD isn’t available or didn’t shrink enough, exporting and re-importing compresses your distro to exactly what’s used.

  • Export (safe backup):
See also  Docker Desktop vs Docker in WSL2: Which Is Faster in 2025?

wsl –export Ubuntu C:\WSL\Backups\Ubuntu-$(Get-Date -Format yyyyMMdd).tar

  • Import to a new distro name:

wsl –import Ubuntu-compact C:\WSL\Ubuntu-compact C:\WSL\Backups\Ubuntu-20250101.tar –version 2

  • Test the new distro:

wsl -d Ubuntu-compact

  • If everything is good, you may switch and remove the old one:

wsl –unregister Ubuntu

Note: For Canonical Ubuntu appx, set default user if needed:

ubuntu config –default-user

Or create /etc/wsl.conf in the new distro to set the default user.

H2: Troubleshooting

H3: DNS not working inside WSL2

Symptoms: apt update fails to resolve, curl can’t resolve host.

Fix 1: Regenerate resolv.conf

  • Ensure WSL manages resolv.conf:

sudo rm /etc/resolv.conf
echo “[network]” | sudo tee /etc/wsl.conf
echo “generateResolvConf = true” | sudo tee -a /etc/wsl.conf
wsl –shutdown

Reopen WSL and test.

Fix 2: Set static DNS servers

  • Prevent auto-gen and set your own:

echo “[network]” | sudo tee /etc/wsl.conf
echo “generateResolvConf = false” | sudo tee -a /etc/wsl.conf
sudo rm /etc/resolv.conf
echo “nameserver 1.1.1.1” | sudo tee /etc/resolv.conf
echo “nameserver 8.8.8.8” | sudo tee -a /etc/resolv.conf
wsl –shutdown

Fix 3: In .wslconfig

  • If corporate VPN/DNS is complex, try disabling DNS proxy:

In Windows at %UserProfile%.wslconfig:

[wsl2]
dnsProxy=false

Then:

wsl –shutdown

H3: Git is slow on WSL2

  • Avoid working in /mnt/c. Keep repos in the Linux filesystem (e.g., ~/code).
  • Enable Git file system cache:

git config –global core.fscache true

  • Disable executable bit changes if not needed:

git config –global core.fileMode false

  • If antivirus is scanning, exclude your project directory or the VHDX file (security trade-off; consult your org’s policy).

H3: Disk space keeps bloating

  • Clean caches regularly:

sudo apt-get clean && sudo apt-get autoremove -y
npm cache clean –force
yarn cache clean
pip cache purge
docker system prune -a

  • TRIM and compact periodically:

sudo fstrim -av
wsl –shutdown
Optimize-VHD -Path “…\ext4.vhdx” -Mode Full

  • Consider export/import if compaction stalls.

H3: File I/O slowness

  • Keep active projects in the Linux filesystem, not on /mnt/c.
  • Use WSLg/Plan9 file sharing sparingly for hot paths.
  • Exclude heavy dev folders from real-time antivirus scans (evaluate risk).
  • Tune WSL resources (.wslconfig) to reduce swapping and contention.

H2: Optimization & Best Practices

H3: Configure .wslconfig for better resource usage

Create or edit %UserProfile%.wslconfig on Windows:

[wsl2]
memory=6GB
processors=4
swap=0
localhostForwarding=true
pageReporting=true
autoMemoryReclaim=gradual

Requires recent WSL (Store) builds:

sparseVhd=true

  • memory: Cap VM RAM to prevent runaway use.
  • processors: Set CPU cores for balance.
  • swap=0: Reduces host disk churn; if you need swap, set a small file instead.
  • pageReporting and autoMemoryReclaim: Encourage WSL to return memory to Windows.
  • sparseVhd=true: Enables automatic sparse trimming of the VHD where supported, helping keep ext4.vhdx from bloating.

After changes:

wsl –shutdown

H3: Keep Docker layers under control

  • Prune regularly:

docker system prune -a
docker volume prune
docker builder prune -a

  • Use multi-stage builds and .dockerignore to minimize layer size.
  • Place Docker bind mounts inside the Linux filesystem for speed.

H3: Work in the right filesystem

  • Put your source code, node_modules, and build artifacts in the Linux filesystem (e.g., /home/you/project). Accessing /mnt/c can be much slower and can exacerbate disk bloat.

H3: Automate housekeeping

  • Add a weekly scheduled task on Windows that runs:

wsl.exe -e /usr/sbin/fstrim -av
wsl.exe –shutdown
PowerShell -NoProfile -Command “Import-Module Hyper-V; Optimize-VHD -Path ‘C:…\ext4.vhdx’ -Mode Quick”

  • Or trigger it after large CI-like builds.

H3: Backups and exports

  • Use wsl –export to back up distros before major changes. Export/import doubles as a defragment/compact operation.
See also  GPU Compute in WSL2: CUDA/DirectML—What Actually Works

H2: Project-Based Example: Speeding Up a Node.js Monorepo and Reclaiming 30+ GB

Scenario: You run a large Node.js monorepo (pnpm + TurboRepo) on WSL2 with Docker. Builds are heavy and frequent. Disk usage soared; Docker images accumulate, and the ext4.vhdx is 70+ GB.

Step 1: Move your project into Linux filesystem

  • Clone into ~/work/monorepo instead of /mnt/c/Users/you/monorepo. This immediately improves I/O performance.

Step 2: Clean caches and logs inside WSL

  • Node and package caches:

pnpm store prune
npm cache clean –force
yarn cache clean

  • Build artifacts:

rm -rf dist .turbo node_modules/.cache

  • System packages:

sudo apt-get clean && sudo apt-get autoremove -y

Step 3: Trim Docker data

  • Remove stale images, containers, and builders:

docker system prune -a
docker volume prune
docker builder prune -a

Step 4: fstrim the filesystem

sudo fstrim -av

Expect to see several gigabytes trimmed.

Step 5: Shut down WSL

wsl –shutdown

Step 6: Compact both your distro and Docker’s data

  • Optimize your primary distro VHDX:

Optimize-VHD -Path “C:\Users\you\AppData\Local\Packages\CanonicalGroupLimited.UbuntuonWindows_…\LocalState\ext4.vhdx” -Mode Full

  • Optimize Docker’s VHDX:

Optimize-VHD -Path “$env:LOCALAPPDATA\Docker\wsl\data\ext4.vhdx” -Mode Full

Step 7: Add .wslconfig tuning

Create/edit %UserProfile%.wslconfig:

[wsl2]
memory=8GB
processors=8
swap=0
pageReporting=true
autoMemoryReclaim=gradual
sparseVhd=true

Step 8: Validate improvements

  • Confirm ext4.vhdx sizes dropped significantly.
  • Run pnpm install and TurboRepo builds from the Linux filesystem; verify improved cold and warm build times.
  • Observe lower memory pressure and faster I/O overall.

Optional: If Optimize-VHD fails to reclaim enough space, perform export/import to a new distro name and switch once validated.

H2: Conclusion

You now know exactly How to Shrink and Compact ext4.vhdx Without Data Loss on WSL2. The process is straightforward: Clean up inside Linux, run fstrim to mark free space, shut down WSL, then compact the VHDX from Windows—preferably with Optimize-VHD. If needed, export/import gives you a fresh, right-sized virtual disk. Add .wslconfig optimizations (including sparseVhd where supported), keep Docker layers tidy, and work from the Linux filesystem to avoid I/O pitfalls. With these practices, WSL2 stays fast, lean, and reliable for everyday development.

H2: FAQ

H4: Does compacting ext4.vhdx risk my data?

Compaction is safe when done correctly. Always back up the ext4.vhdx file before you start. Ensure WSL is fully shut down (wsl –shutdown) and avoid interrupting Optimize-VHD or diskpart while they’re running.

H4: I don’t have the Hyper-V PowerShell module. Can I still shrink?

Yes. Try diskpart’s “compact vdisk.” If that doesn’t shrink VHDX on your system, use the export/import method (wsl –export … then wsl –import …). Export/import always creates a clean, right-sized VHDX.

H4: Why did fstrim not report much reclaimed space?

Perhaps there isn’t much free space to reclaim, or files were recently zeroed but not truly freed (e.g., moved to trash-like locations). Clean caches (apt/npm/docker/etc.), remove big artifacts, run fstrim again, then compact from Windows. As a last resort, try the zero-fill trick before rerunning fstrim.

H4: Can I shrink Docker’s WSL2 data too?

Yes. Prune Docker data, run fstrim, shut down WSL, then compact the Docker data VHDX (often under %LOCALAPPDATA%\Docker\wsl\data\ext4.vhdx). Doing both your distro and Docker’s VHDX often yields major space savings.

H4: How do I keep ext4.vhdx from growing so fast?

  • Keep repos in the Linux filesystem, not /mnt/c.
  • Prune Docker regularly.
  • Clean package caches.
  • Run periodic fstrim and compaction.
  • On recent WSL builds, set [wsl2] sparseVhd=true in .wslconfig to help automatic reclamation.

You’ve got this—keep your WSL2 environment lean, fast, and ready for work!

About the author

Jonathan Dudamel

Jonathan Dudamel

I'm Jonathan Dudamel, an experienced IT specialist and network engineer passionate about all things Windows. I have deep expertise in Microsoft project management, virtualization (VMware ESXi and Hyper-V), and Microsoft’s hybrid platform. I'm also skilled with Microsoft O365, Azure ADDS, and Windows Server environments from 2003 through 2022.

My strengths include Microsoft network infrastructure, VMware platforms, CMMS, ERP systems, and server administration (2016/2022).