Zswap Makes Swap Go Zoom

Last edited on 2026-07-10 Tagged under  #zswap   #zbm   #grub   #void   #lmde   #linux 

Linux kernel features zswap and zram both provide a compressed storage area in RAM for swap memory. But each takes a very different approach to achieve a fast(er) swap.



Start Here

The most apparent difference between the two approaches to swap management are that while zswap works in tandem with a swapfile or swap partition, zram does not require a backing swap device. So zram all the way, right? At least I thought so. I've used zram in the past to keep swap contents in speedy RAM vs not-as-speedy-storage, but after reading this comprehensive debunking of zswap and zram myths I've switched to zswap on my machines.

Different bootloaders initiate zswap differently. For the purposes of this HOWTO I profile two systems, each with a different bootloader: a Void Linux desktop using ZFSBootMenu (ZBM), and a Linux Mint Debian Edition (LMDE) laptop using GRUB. Both systems were provisioned with a swap partition during install.

To use zswap, I need to supply the desired arguments to the kernel at boot. These are the arguments I use:

  • zswap.enabled=1           # the master switch
  • zswap.compressor=lz4       # prioritize the lowest latency vs a higher compression ratio
  • zswap.zpool=zsmalloc       # most modern and efficient memory allocator
  • zswap.max_pool_percent=10   # zswap can use up to 10% of physical RAM

Configure the Bootloader

ZBM

If the system bootloader is ZBM, view the current boot arguments for (example) zroot/ROOT:

$ zfs get org.zfsbootmenu:commandline zroot/ROOT
NAME        PROPERTY                     VALUE                    SOURCE
zroot/ROOT  org.zfsbootmenu:commandline  quiet hibernate=no       local

NOTE
I had added the quiet and hiberate=no parameters earlier during the Void install.

Add the following boot arguments to ZBM:

sudo zfs set org.zfsbootmenu:commandline="quiet hiberate=no zswap.enabled=1 zswap.compressor=lz4 zswap.zpool=zsmalloc zswap.max_pool_percent=10" zroot/ROOT

Reboot the system.

GRUB

If the system bootloader is GRUB, view the current boot arguments by inspecting cmdline:

$ cat /proc/cmdline
BOOT_IMAGE=/boot/vmlinuz-6.12.95+deb13-amd64 root=UUID=<long_string_of_characters> ro quiet splash

Add the desired zswap boot arguments to GRUB by modifying the GRUB_CMDLINE_LINUX_DEFAULT setting, which exists in /etc/default/grub.

However, settings in this file can be overridden if additional config files exist in the /etc/default/grub.d directory. In LMDE this is indeed the case, which has a /etc/default/grub.d/50_lmde.cfg file. Higher numbered files in this directory are read later by GRUB in generating its config, and take precedence over earlier settings.

Since any changes made to 50_lmde.cfg may be lost in a future system upgrade, I create a custom file to hold the boot arguments:

echo 'GRUB_CMDLINE_LINUX_DEFAULT="quiet splash zswap.enabled=1 zswap.zpool=zsmalloc zswap.max_pool_percent=10"' | sudo tee /etc/default/grub.d/99_cmdline.cfg

NOTE
I've made a slight alteration here, dropping the zswap.compressor=lz4 argument. The reason is that on (all?) Debian-based distros like LMDE, the default lzo compressor is loaded very early in the boot process before the lz4 modules are considered (even if included in the initramfs) and the argument will fail. An alternative is described below in "Troubleshooting".

Update GRUB:

sudo update-grub

Reboot the system.

Verify

Cmdline

Arguments used to boot the system:

ZBM on Void

$ cat /proc/cmdline 
root=zfs:zroot/ROOT/void quiet hiberate=no zswap.enabled=1 zswap.compressor=lz4 zswap.zpool=zsmalloc zswap.max_pool_percent=10 spl.spl_hostid=0x00bab10c

GRUB on LMDE

$ cat /proc/cmdline
BOOT_IMAGE=/boot/vmlinuz-6.12.95+deb13-amd64 root=UUID=<long_string_of_characters> ro quiet splash zswap.enabled=1 zswap.zpool=zsmalloc zswap.max_pool_percent=10

Dmesg

Confirm zswap was loaded during boot:

Void

$ sudo dmesg | grep zswap
.
.
.
[    0.507529] zswap: loaded using pool lz4

LMDE

$ sudo dmesg | grep zswap
.
.
.
[    0.746379] zswap: loaded using pool lzo/zsmalloc

Parameters

NOTE
On systems that are running more recent (6.18+) kernels (like Void) zsmalloc is now the exclusive backend for zswap, and the zpool option has been removed.

View live settings:

Void

$ grep -r . /sys/module/zswap/parameters/
/sys/module/zswap/parameters/enabled:Y
/sys/module/zswap/parameters/shrinker_enabled:N
/sys/module/zswap/parameters/max_pool_percent:10
/sys/module/zswap/parameters/compressor:lz4
/sys/module/zswap/parameters/accept_threshold_percent:90

LMDE

$ grep -r . /sys/module/zswap/parameters/
/sys/module/zswap/parameters/enabled:Y
/sys/module/zswap/parameters/shrinker_enabled:N
/sys/module/zswap/parameters/max_pool_percent:10
/sys/module/zswap/parameters/compressor:lzo
/sys/module/zswap/parameters/zpool:zsmalloc
/sys/module/zswap/parameters/accept_threshold_percent:90

Statistics

View how zswap is performing:

sudo grep -r . /sys/kernel/debug/zswap/

If the above command outputs the error message:

grep: /sys/kernel/debug/zswap/: No such file or directory

...mount debugfs:

sudo mount -t debugfs none /sys/kernel/debug

...and re-run grep.

Troubleshooting

To use the zswap compressor of our choice on a system that won't accept it as a boot argument (i.e. lz4 on LMDE), one approach is to create a systemd service file that will switch compressors after zswap starts at boot.

Create zswap-compress.service:

sudo nano /etc/systemd/system/zswap-compress.service

Add:

[Unit]
Description=Configure zswap compressor to LZ4
After=systemd-modules-load.service

[Service]
Type=oneshot
ExecStart=/bin/bash -c 'echo lz4 > /sys/module/zswap/parameters/compressor'
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target

Save changes and exit.

Enable the service:

sudo systemctl enable --now zswap-compress.service

Verify:

cat /sys/module/zswap/parameters/compressor

It should output lz4.

On the next reboot, dmesg may show a lz4 not available, using default log entry from the beginning of boot, but the systemd service will override it seconds later. After login, running the cat command above will output the current compressor handling the swap pool.

Resources

You can like, share, or comment on this post on the Fediverse 💬

Thanks for reading! Read other posts?

« Previous: Install Linux Mint Debian Edition (LMDE 7) in Expert Mode