Get More from Less: How zswap Optimizes Memory in WSL2

Enhancing WSL2 Performance with zswap

Windows Subsystem for Linux 2 (WSL2) has transformed how developers and IT professionals interact with Linux environments on Windows, offering remarkable performance and integration. However, resource-intensive tasks may sometimes push memory limits, resulting in slower system performance.

What is zswap?

zswap is a kernel feature in Linux designed to improve the performance of swapping pages by compressing memory pages before writing them to swap space. Essentially, zswap minimizes I/O operations to the disk, resulting in faster system responsiveness, particularly in environments with limited memory resources.

Why use zswap instead of zram?

While zram also compresses memory pages, it creates a compressed RAM disk that directly occupies RAM space. In contrast, zswap complements the existing swap file used by WSL2, compressing pages in memory before they are written to disk, reducing disk writes without reserving significant amounts of RAM. This makes zswap particularly well-suited for WSL2, especially since it already uses a disk-based swap file.

Advantages of using zswap with WSL2

  1. Reduced Swap Usage: By compressing pages, zswap dramatically reduces the amount of data that needs to be written to and read from the disk, significantly speeding up swap operations.

  2. Extended SSD Lifespan: Decreasing write operations to SSDs helps extend their durability and lifespan, providing long-term benefits for users.

  3. Better Resource Efficiency: zswap efficiently manages memory resources, making it ideal for running multiple applications simultaneously with less performance degradation.

  4. Ideal for Virtualized Environments: WSL2 allocates a fixed portion of host RAM, typically half of the available memory in Windows. By compressing unused parts of programs and services that aren't ideally suited to WSL, zswap significantly optimizes memory usage, allowing you to do more with limited resources.

Setting up zswap in WSL2

The current version of WSL2 (2.4.12 at the time of writing) doesn't support zswap or loadable kernel modules by default. Therefore, recompiling the kernel with zswap enabled is necessary. You can find detailed build instructions here.

Alternatively, there's an automated script that simplifies this process and automatically enables zswap across all your WSL2 distributions:

curl https://raw.githubusercontent.com/dhanar10/wsl2-kernel-zswap/main/build.sh | bash

After running this script, you'll have a fully compiled kernel with zswap included and activated by default for every WSL2 distribution you use.

Activating the New Kernel in WSL2

After recompiling the kernel, you'll need to activate it.

  1. Using .wslconfig:

Create or edit .wslconfig in your Windows user directory (e.g., C:\Users\YourUsername\.wslconfig) and add:

[wsl2]
kernel=C:\path\to\your\compiled\kernel\bzImage

Then restart WSL2:

wsl --shutdown
  1. Using WSL Settings Application (if available):

If your WSL version provides a GUI settings application, you can specify the new kernel path directly in the settings.

Verify that zswap is active:

cat /sys/module/zswap/parameters/enabled

You should see output as Y confirming it is enabled.

Recommended zswap Configuration: Swappiness 133

To further enhance performance, setting a high swappiness value is beneficial. The recommended swappiness value when using zswap in WSL2 is 133. This value directs the system to aggressively compress memory pages, prioritizing file system cache and optimizing performance, even in low-memory situations.

To set swappiness persistently across reboots, use the following commands:

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

Bonus: Checking zswap Usage and RAM Savings

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

sudo ./zswap_stats.sh

Here's the script along with an example of typical output:

#!/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 WSL2 autoMemoryReclaim

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

Conclusion

Leveraging zswap within WSL2 provides tangible performance benefits, especially under demanding workloads. For users looking to maximize their productivity and maintain optimal performance within their Windows and Linux hybrid workflows, activating zswap is highly recommended.


Ready to experience better performance? Give zswap a try today!


Whitewater Foundry specializes in WSL solutions, helping businesses build efficient, reliable, and productive Linux development environments on Windows. Let our WSL experts empower your developers and boost your team's productivity today! Contact us to learn more.