Summary

WSL 2 的 ext4.vhdx 虛擬硬碟採用動態擴充機制,刪除資料後不會自動回收空間。本文說明如何透過兩種方式壓縮:Hyper-V 的 Optimize-VHD(Windows Pro/Enterprise)或 diskpart(通用方法),並附帶 .bat 自動化腳本和 wsl --export/import 的替代方案。

WSL 2’s ext4.vhdx dynamically expands but never auto-reclaims space after deletion. This article covers two compression methods — Optimize-VHD (requires Hyper-V) and diskpart (universal) — plus a .bat automation script and wsl --export/import as a nuclear option.

Key Points

  • WSL 2 virtual disk only grows, never auto-shrinks — requires manual compact after deleting large amounts of data (e.g., Docker images).
  • Step 1: Clean inside WSL first — docker builder prune -a, apt-get clean/autoremove, npm/yarn cache clean, then sudo fstrim -v / to mark freed blocks.
  • Step 2: Shut down WSL completely — wsl --shutdown — before touching the .vhdx file.
  • Method A (Hyper-V, Windows Pro+): Optimize-VHD -Path <path> -Mode Full
  • Method B (universal): diskpartselect vdiskattach vdisk readonlycompact vdiskdetach vdisk
  • Nuclear option: wsl --exportwsl --unregisterwsl --import creates fresh minimal .vhdx.
  • A ready-to-use CompactVHDX.bat script is provided in the article.

Insights

The fstrim step before compacting is critical and often missed — without it, the filesystem doesn’t mark freed blocks as available, so compact vdisk recovers nothing. The readonly mount during compaction prevents corruption. The Docker use case is common: every docker pull and failed build layer expands the .vhdx, but docker system prune only frees space inside the filesystem, not the .vhdx itself.

Connections

Raw Excerpt

WSL 2 的虛擬硬碟採用動態擴充機制,它會隨著寫入資料而變大,但在刪除資料後不會自動釋放空間回 Windows 系統,因此必須手動執行壓縮 (Compact) 操作。