Skip to content

zram vs zswap

A comparison of two memory compression techniques in Linux, which aim to be faster than just using swap, and also reduce writes to swap.

zram

zram is a kernel module which creates a RAM-based block device in memory, which can be used for swap, among other purposes.

The main parameters exposed by the module are:

  • comp_algorithm: Compression algorithm to use
  • disksize: Size of the block device
  • backing_dev: A backing device to write incompressible/idle pages to (optional)

zram also allows the user to set a limit on the amount of writeback to swap, which can help to prolong the life of SSDs.

The best compression algorithm appears to be zstd.

The current statistics can be viewed with zramctl:

❯ zramctl
NAME       ALGORITHM DISKSIZE DATA COMPR TOTAL STREAMS MOUNTPOINT
/dev/zram0 zstd         15.6G  28M  7.2M  8.6M       8 [SWAP]

zram can be enabled on NixOS with the zram module.

zswap

zswap is another kernel module which acts as a compressed cache in RAM, for swap pages. It intercepts pages in the process of being swapped out, and compresses them in RAM. See a thorough explanation on LWN.net.

The main parameters exposed by the module are (see all with ls -1 /sys/module/zswap/parameters/):

  • compressor: Compression algorithm to use
  • max_pool_percent: Maximum percentage of RAM to use for zswap
  • zpool: The zpool (compressed memory allocator) to use
  • shrinker_enabled: Whether to proactively write cold pages to swap

The current parameters can be viewed with:

grep -r . /sys/module/zswap/parameters/

Current statistics can be viewed via the debugfs interface:

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

Extra documentation for the choices of parameters (e.g. zpool) can be found in the Memory Management Kconfig menu and on the Arch Wiki.

NixOS

To enable zswap on NixOS, since there is currently no zswap option module, it can be set with kernel parameters instead, e.g.:

boot.kernelParams = [
    "zswap.enabled=1"
    "zswap.compressor=zstd"
    "zswap.zpool=zsmalloc"
    "zswap.max_pool_percent=50"
    "zswap.shrinker_enabled=1"
];

boot.initrd.kernelModules = [
    "zsmalloc"
    # Enable other modules as required, e.g.
    # "lz4"
    # "z3fold"
];

# Note that you also need a swap device setup, e.g.:
swapDevices = [
    {
        device = "/swapfile";
        size = 16 * 1024;
    }
];

The list of kernel parameters available can be viewed from source here (the parameters to module_param_cb and module_param_named).

You can view the current Kconfig parameters with zcat /proc/config.gz.

Test zswap

To check that zswap is working and writing back to swap:

# Stress memory
stress-ng --vm 2 --vm-bytes 4G --timeout 60s

# Check that written_back_pages is increasing
watch -n 1 grep -r . /sys/kernel/debug/zswap/

Virtual Memory Kernel Configuration

As these swap devices are faster than the filesystem, the swappiness and other parameters should be increased accordingly:

vm.swappiness = 180
vm.watermark_boost_factor = 0
vm.watermark_scale_factor = 125
vm.page-cluster = 0

Comparison

LinuxReviews found that on a memory constrained device compiling Chrome, zram was faster than zswap (article).

Currently I use zram with a disksize of 200% of RAM (suggested by this) on my 8G laptop.

Comments