Get More From Less: How zswap Optimizes Memory in WSL2 (2026 Update)

WSL2 has matured significantly in the past year. With the rollout of the 6.x kernel series, Microsoft introduced a more modern memory pipeline, improved page-reclaim behavior, and deeper coordination with the Windows memory manager. Alongside these improvements, a key capability continues to deliver disproportionate value: zswap.

This update revisits our original 2025 article and incorporates the latest architectural changes in WSL2, including the modular VHDX-based swap design, improved compression backends, and kernel-level enhancements that meaningfully elevate performance in developer workflows.


What zswap Does (and Why It Matters)

zswap acts as a compressed in-memory cache for swapped pages. Instead of writing memory pages directly to the swap VHDX, the kernel compresses them and keeps them in RAM. Only when the cache reaches pressure thresholds does Linux write pages out to disk.

This drives four core advantages:

  1. Reduced disk I/O Fewer writes to the swap file translate into smoother performance during sustained loads.

  2. Lower memory pressure under peak workloads Compressed pages consume less RAM, creating additional headroom for builds, containers, and AI tools.

  3. More responsive developer experience Long-running npm, Maven, Python, Rust or container workloads reduce their stall time and improve overall throughput.

  4. Reduced SSD wear By compressing and holding pages in memory—rather than immediately persisting them to the swap VHDX—zswap significantly reduces write amplification on the host SSD. It helps extend SSD lifespan and maintain consistent NVMe performance over time.


Why zswap Matters in Kernel 6.x

Kernel 6.x introduced architectural changes that affect how custom features like zswap must be enabled and maintained, but these changes do not inherently improve zswap performance. The key points relevant to WSL2 users are factual and mechanical:

1. Module Storage Moved to modules.vhdx

WSL2 now ships modules inside a dedicated VHDX volume. This does not change performance, but it changes the integration model: any custom kernel (including one with zswap support) must provide its own modules.vhdx built from the same configuration.

2. zswap Still Requires a Custom Kernel

The Microsoft-provided kernel continues to ship without zswap support. Enabling it still requires compiling your own kernel with the relevant options. Kernel 6.x does not simplify or accelerate zswap internally.

3. Expected Behavior Under Load Remains Unchanged

zswap’s advantages—reduced I/O, lower SSD wear, and better responsiveness under memory pressure—remain tied to its design, not to new coordination layers or changes in Windows. Kernel 6.x does not introduce any officially documented improvements in this area.

zswap vs zram: Why zswap Remains the Right Fit for WSL2

Although zram creates a compressed RAM-backed swap device, it competes with workloads for RAM and bypasses WSL2’s optimized swap design. In contrast, zswap complements the existing swap VHDX and aligns with how Windows orchestrates system memory globally.

This makes zswap the right strategy for both individual developers and enterprise fleets.

How to Enable zswap in WSL2 (Kernel 6.x)

The current WSL2 kernel from Microsoft does not include zswap support out of the box and, starting with kernel 6.x, it also separates the kernel image from its modules into a modules.vhdx file. To enable zswap you need to:

  1. Build a custom WSL2 kernel with zswap enabled using the script.
  2. Use the generated bzImage and modules.vhdx.
  3. Point WSL2 to both files via .wslconfig.

Step 1. Download and run the script

The official repository of the script is:

curl -O https://raw.githubusercontent.com/dhanar10/wsl2-kernel-zswap/main/build.sh
less build.sh   # optional but recommended: review the script
bash build.sh
# or, in one line:
# curl https://raw.githubusercontent.com/dhanar10/wsl2-kernel-zswap/main/build.sh | bash

The script automatically:

  • Detects whether you are on a 5.x or 6.x WSL2 kernel.
  • For 6.x, builds the kernel without FRONTSWAP (since it was removed) and generates the module image.

What the script produces

After the build finishes you should have at least:

arch/x86/boot/bzImage
modules.vhdx

On kernel 6.x both are mandatory:

  • bzImage – the compiled kernel for WSL2
  • modules.vhdx – the VHDX volume containing the kernel modules

Step 2. Copy the files into Windows

Copy the build artifacts into a stable location, for example:

bzImage      →  C:\wsl-zswap\bzImage
modules.vhdx →  C:\wsl-zswap\modules.vhdx

Step 3. Configure .wslconfig

Edit:

%UserProfile%\.wslconfig

and add or update the [wsl2] section:

[wsl2]
kernel=C:\\wsl-zswap\\bzImage
kernelModules=C:\\wsl-zswap\\modules.vhdx

Then restart WSL:

wsl --shutdown

The next time you start any WSL2 distribution, it will boot with your custom kernel and modules, including zswap support.

Step 4. Verify that zswap is active

Inside WSL:

cat /sys/module/zswap/parameters/enabled

It should return:

Y

You can also confirm the configuration:

cat /sys/module/zswap/parameters/compressor
cat /sys/module/zswap/parameters/zpool

Recommended tuning: vm.swappiness = 133

To get the most out of zswap in WSL2, you can increase vm.swappiness so the kernel is more aggressive about compressing pages and using swap:

sudo bash -c 'echo "vm.swappiness=133" >> /etc/sysctl.conf'
sudo sysctl -p

This pushes the system to favor compressed memory (zswap) and filesystem cache, which tends to deliver better behavior under heavy WSL2 workloads.



Bonus: Checking zswap Usage and RAM Savings

Save the following script as zswap_stats.sh, make it executable, and run it with:

sudo ./zswap_stats.sh

Script

#!/bin/bash

# Function to calculate RAM savings
calculate_zswap_savings() {
    local stored_pages=$(cat /sys/kernel/debug/zswap/stored_pages)
    local pool_total_size=$(cat /sys/kernel/debug/zswap/pool_total_size)
    local page_size=$(getconf PAGE_SIZE 2>/dev/null || echo 4096)

    local ram_uncompressed=$((stored_pages * page_size))
    local ram_saved=$((ram_uncompressed - pool_total_size))

    echo "Stored Pages: $stored_pages"
    echo "Pool Total Size: $(numfmt --to=iec --suffix=B $pool_total_size)"
    echo "Uncompressed RAM: $(numfmt --to=iec --suffix=B $ram_uncompressed)"
    echo "RAM Saved: $(numfmt --to=iec --suffix=B $ram_saved)"
}

# Print header
echo "Zswap Statistics:"
echo "-----------------"

# Calculate and display zswap savings
calculate_zswap_savings

Example Output

Zswap Statistics:
-----------------
Stored Pages: 514837
Pool Total Size: 709MB
Uncompressed RAM: 2.0GB
RAM Saved: 1.3GB

Important Note on autoMemoryReclaim

In testing, the autoMemoryReclaim setting in .wslconfig set to gradual may conflict with zswap. If you use this option, monitor your system carefully. disabled or dropcache have shown no issues.

Final Thoughts

WSL2 Kernel 6.x, combined with the new module VHDX architecture and a tuned zswap configuration, provides a substantially improved experience for developers running Linux workloads on Windows. The addition of reduced SSD wear makes zswap not only a performance optimization but also a long-term reliability investment for both personal and enterprise hardware.

This update ensures your WSL2 setup remains optimized, efficient, and ready for modern workloads.