Alan Doyle

   Swap vs ZSwap vs zRAM

... for all the times you need Swap (which I think is always).

SODIMM RAM stick - Possessed Photography (https://unsplash.com/photos/nuc3NFB_6po)

What is Swap and why do we need it?

Some backstory, Linux divides its RAM into chunks of memory called Pages. Swapping is the process whereby a page of memory is copied to the preconfigured space, usually on the hard disk, called swap space, to free up that page of memory. Freeing up memory pages allows more applications to allocate more memory when needed which can help the application to run smoother and perform better. The bigest caveat is that there can be a performance hit when the swapped out memory is needed again hence there are multiple types of swap depending on the requirements.

On Linux there are 3 popular types of swap: Swap, ZSwap and zRAM.

I’ll be discussing these in the context of how to configure on Ubuntu 22.04 which is my current preferred Linux distribution. I’ve tested these instructions on Ubuntu Server and Ubuntu Desktop. The commands used should also work on Ubuntu derivatives like Kubuntu, Xubuntu, etc. but I’ve not tested them and your mileage may vary.

So what’s the difference between them?

  • Swap is the most basic verion and simply consists of a file, files, partition or partitions on a hard drive or SSD marked as swap space which Linux can use to store swapped out memory pages.
  • ZSwap operates as a compressed RAM cache and works in conjunction with an uncompressed standard swap device described above.
  • zRAM is a compressed swap device that resides solely in RAM and does not require a backing swap device (i.e. uncompressed swap space on a hard drive or SSD).

Both zRAM and ZSwap use compression to fit more pages into memory thus allowing more memory to be swapped into a smaller space and reduce the number of read/writes to a backing swap device (if configured) which is especially useful if the backing swap device is flash based e.g. an SSD or eMMC drive. That’s the theory, however in practice it’s the kind of data in the memory page which affects how compressable the memory page is, for example: a memory page containing JPEG data is much less compressable than a memory page containing text data.

Why do we need any swap nowadays when RAM is cheap and plentiful?

It’s common knowledge that using swap space instead of RAM can severely slow down performance, especialy when the swap space is located on a regular hard drive. So, you may ask yourself, since I have plenty of RAM available, wouldn’t it better to disable swap? The short answer is, No. There are actually performance benefits when swap is enabled, even when you have more than enough RAM.

The 2 main benefits are:

  1. Swapping out unused Memory pages means there is more actual memory available to be allocated to running applications which can improve responsiveness on desktops and laptops making for a better overall user experience.
  2. For server admins swap gives them time to react to low memory issues, i.e. the server slows down but doesn’t crash.

The main disadvantage of swap over more RAM is that swap usage becomes a performance bottleneck when the Linux Kernel is pressured to continuously move memory pages in and out of memory and swap space i.e. there isn’t enough RAM to hold all the currently active applications in memory so pages of actively used applications are swapped out when another application needs memory and vice versa when the original application requests the active memory back from the swap device. This makes the entire system run very slowly and usually involves a lot of hard drive active. This is commonly called Thrashing and is very bad. If this happens the best solution is to either close some of the active applications/services or invest in more RAM to alleviate the problem (if possible).

How much do you need?

Some recommend no swap (not usually advised) or swap size slightly larger than the total RAM if the swap space is located on a hard drive or SSD. However, this is hardly the case on production servers, and you should instead balance your decision with the effects swap will have on your specific applications. Swap does not change the amount of RAM required for a healthy server, or desktop for that matter. It’s designed to be complementary to the performance of healthy systems.

Check swap space

By default an Ubuntu install will set up a small swap file /swap.img To check swap space run the following command from a terminal window…

swapon
NAME      TYPE SIZE USED PRIO
/swap.img file   4G   4M   -2

Alternatively run the following command from a terminal window…

free --mega
               total        used        free      shared  buff/cache   available
Mem:           16617        2317         370          12       13929       13942
Swap:           4294           3        4291

Notice that even on this 16Gb system with more than 12Gb available some swap is still used.


Basic swap space

Hard drive

To add more swap space run the following set of commands…

sudo fallocate -l 2G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
Setting up swapspace version 1, size = 2 GiB (2147479552 bytes)
no label, UUID=cba13513-5ba0-480a-a0f9-d3e22807dc1a

To activate the swap run the following command…

sudo swapon /swapfile

To check if it’s enabled run the following command…

sudo swapon --show
NAME      TYPE SIZE USED PRIO
/swap.img file   4G   4M   -2
/swapfile file   2G   0B   -3

Enable at boot

To enable the swap at the next boot run the following command…

echo "/swapfile none swap sw 0 0" | sudo tee -a /etc/fstab

Now the swap will be active every time the computer boots.


ZSwap

RAM on Hard drive

ZSwap makes very efficient use of swap. It will minimizes Disk I/O by both reducing the number of writes and reads required (data is compressed and held in RAM) and by reducing the bandwidth of these I/O operations as the data is in a compressed form. Also as the compressed data is held in RAM you will not face sudden slowdowns when your system runs out of memory and tries to read/write the swap drive, even if that drive is an SSD.

Caveats

  • ZSwap needs a Swap partition/file. If you don’t want/need a Swap partition or file but do want to use a compressed memory swap device then use zRAM.
  • With a CPU speed less than 1ghz there will be a performance hit as compressing/decompressing data requires a fast, preferrably a multi-core, CPU.
  • ZSwap should not be used with zRAM. They both provide a compressed cache and would wind up using more system memory than each individually. It makes no sense.

Check Kernel supports ZSwap

For ZSwap to work it must be built into the Linux Kernel being run.

To check if your OS Kernel comes with ZSwap by running the command below.

cat /boot/config-`uname -r` | grep -i zswap
CONFIG_ZSWAP=y
# CONFIG_ZSWAP_COMPRESSOR_DEFAULT_DEFLATE is not set
CONFIG_ZSWAP_COMPRESSOR_DEFAULT_LZO=y
# CONFIG_ZSWAP_COMPRESSOR_DEFAULT_842 is not set
# CONFIG_ZSWAP_COMPRESSOR_DEFAULT_LZ4 is not set
# CONFIG_ZSWAP_COMPRESSOR_DEFAULT_LZ4HC is not set
# CONFIG_ZSWAP_COMPRESSOR_DEFAULT_ZSTD is not set
CONFIG_ZSWAP_COMPRESSOR_DEFAULT="lzo"
CONFIG_ZSWAP_ZPOOL_DEFAULT_ZBUD=y
# CONFIG_ZSWAP_ZPOOL_DEFAULT_Z3FOLD is not set
# CONFIG_ZSWAP_ZPOOL_DEFAULT_ZSMALLOC is not set
CONFIG_ZSWAP_ZPOOL_DEFAULT="zbud"
# CONFIG_ZSWAP_DEFAULT_ON is not set

If the response is CONFIG_ZSWAP=y, you are OK to proceed.

NOTE: Ubuntu Kernels have ZSwap configured, as do the Xanmod Kernels.

Enable ZSwap

To manually enable ZSwap on the next reboot run the following commands…

echo GRUB_CMDLINE_LINUX_DEFAULT="\$GRUB_CMDLINE_LINUX_DEFAULT zswap.enabled=1 zswap.compressor=lz4" | sudo tee /etc/default/grub.d/enable-zswap.cfg

sudo update-grub2

To make things easier I’ve created a ZSwap Configuration script which can be installed by running the following command…

sudo bash -c "$(curl -sSfL https://raw.githubusercontent.com/alandoyle/helper-scripts/main/installers/zswap-installer)"

This will download and install the new configurable ZSwap configuration for Ubuntu. Please feel free to read the full zswap-installer source to make sure you are happy with what the scripts is doing.

Reboot to enable ZSwap.

Check if ZSwap is enabled

To check if ZSwap has been enabled simply run the following command…

cat /sys/module/zswap/parameters/enabled

If ZSwap is enabled, you should see Y in return.

Or if ZSwap is enabled via my installation script simply run the following command for all the information required…

sudo zswap-stats
ZSwap Configuration

        same_filled_pages_enabled       Y
        enabled                         Y
        max_pool_percent                20
        compressor                      lzo-rle
        zpool                           zsmalloc
        accept_threshold_percent        90

ZSwap Statistics

        same_filled_pages               12
        stored_pages                    623
        pool_total_size                 1597440
        duplicate_entry                 0
        written_back_pages              0
        reject_compress_poor            0
        reject_kmemcache_fail           0
        reject_alloc_fail               147
        reject_reclaim_fail             0
        pool_limit_hit                  0

Edit ZSwap Configuration

If ZSwap is installed via my installation script above then ZSwap can be easily re-configured. Simply edit /etc/default/zswap as root

#
# ZSwap Configuration Options
#
# See https://www.kernel.org/doc/Documentation/vm/zswap.txt
#
################################################################################
#
# Enabled flag 0/1
#
ENABLED=1
#
# Compression method
#   lzo lzo-rle lz4 zstd
#
COMPRESSOR=lz4
#
# If pool utilisation is over this percentage, refuse to take new pages
# (prevents swap thrashing which can kill performance)
#
ACCEPT_THRESHOLD_PERCENT=90
#
# The maximum percentage of RAM that the pool can occupy
#
MAX_POOL_PERCENT=20
#
# Should same-value handling be used to reduce pool storage use where
# possible?
#
SAME_FILLED_PAGES=1
#
# ZSwap makes use of zpool for the managing the compressed memory pool.
#   zbud z3fold zsmalloc
#
ZPOOL=zbud

Once the settings have been changed it’s best to reboot rather than trying to switch settings on-the-fly.


zRAM

RAM

zRAM is a fantastic solution to trade some CPU horsepower to gain more RAM. It is also the most configurable.

Enable zRAM

zRAM is probably the simplest to set up on Ubuntu unlike Swap and ZSwap. Simply run the following command…

sudo apt install zram-config -y

…and zRAM is installed.

NOTE: By default zRAM is set to use half the computer’s actual RAM. This does NOT mean that zRAM is using half the available RAM but that it will expand, if necessary, up to this value if the free memory is available.

Check current zRAM State

Once installed zRAM can be easily checked using the following command…

zramctl
NAME       ALGORITHM DISKSIZE DATA COMPR TOTAL STREAMS MOUNTPOINT
/dev/zram0 lz4           3.9G   4K   64B    4K       4 [SWAP]

However, this method of enabling is very limited as it is not possible to configure easily. To this end I’ve created a much more flexible alternative to the zram-config package provided by Ubuntu in my Helper Scripts Github repository.

My updated zRAM Configuration script can be installed by running the following command…

sudo bash -c "$(curl -sSfL https://raw.githubusercontent.com/alandoyle/helper-scripts/main/installers/zram-installer)"

This will download and install the new configurable zRAM configuration for Ubuntu. Please feel free to read the full zram-installer source to make sure you are happy with what the scripts is doing.

By default zRAM uses the lz4 compression algorithm. This algorithm is fast but at the expense of some compression, a good compromise for most systems.

The supported compression algorithms can be seen using the following command…

cat /sys/block/zram0/comp_algorithm
lzo lzo-rle [lz4] lz4hc 842 zstd

The currently used compression algorithm is enclosed in square brackets, in this case [lz4]

Configuration is simple

As before, once installed zRAM can be easily checked using the following command…

zramctl
NAME       ALGORITHM DISKSIZE DATA COMPR TOTAL STREAMS MOUNTPOINT
/dev/zram0 lz4           3.9G   4K   64B    4K       4 [SWAP]

Edit zRAM Configuration

If zRAM is installed via my installation script above then zRAM can be easily re-configured. Simply edit /etc/default/zram as root

#
# zRAM Configuration Options
#
# See https://www.kernel.org/doc/Documentation/vm/zswap.txt
#
################################################################################
#
# Number of split the zRAM swap into.
#   If set to 0 the CPU Core count will be used to split the zRAM swap.
#
NUM_DEVICES=1
#
# Compression method
#   lzo lzo-rle lz4 lz4hc 842 zstd
#
COMP_MODE=lz4
#
# Fixed memory to allocate
#   If 0 then 1/2 system RAM is used
#   Format sizes like: 100M 250M 1.5G 2G
#
FIXED_MEM=0

Once the settings have been changed it’s best to reboot rather than trying to switch settings on-the-fly.


Let’s talk about swappiness…

Hard disk

Swappiness is a Linux kernel property that defines how often the system will use the swap space. It can have a value between 0 and 100. A low value will make the kernel to try to avoid swapping whenever possible, while a higher value will make the kernel to use the swap space more aggressively.

On Ubuntu 22.04, the default swappiness value is set to 60. You can check the current value by typing the following command…

cat /proc/sys/vm/swappiness
60

While the swappiness value of 60 is OK for most Linux desktop systems, for production servers, you may need to set a lower value.

For example, to set the swappiness value to 10, run:

sudo sysctl vm.swappiness=10

To make this parameter persistent across reboots, append the following line to the /etc/sysctl.d/99-swappiness.conf file:

echo vm.swappiness=10 | sudo tee /etc/sysctl.d/99-swappiness.conf

As with most server tweaks the optimal swappiness value depends entirely on your system workload and how the memory is being used. You should adjust this parameter in small increments to find the optimal value.

What’s my preference?

Which direction?

The answer is very simple: ALL of the above, depending on the scenario.

I use a basic swap file with a low swappiness on my production servers, I use a small basic swap as a backup swapping device for ZSwap on all my systems with more than 8Gb RAM, and for systems with less than 8Gb, especially those with flash storage (SSD, eMMC, etc.) I use a single zRAM device @ 50% of system memory.

Hopefully, you’ll now have a better appreciation and understanding of the 3 main types of swap on Linux systems and while each has strengths and weakness they are all extremely useful and when anyone suggests removing swap altogether you’ll know why having some swap is better than none.

Updates

2023-08-01 - Special thanks to Dawid Młynarczyk for spotting a couple of typo’s and suggesting some fixes. 👍


Alan Doyle