UPDATE: As of Tumbleweed's snapshot 20220914, my request has been merged to the upstream repository. Therefore, people on Tumbleweed can get the ultimate zRAM with the normal
sudo zypper install systemd-zram-service && sudo zramswapon
. However, people on Leap will have to install the new zRAM package from the upstream repository.UPDATE2: After enabled zRAM, it's recommended to change
vm.page-cluster
to0
andvm.swappiness
to180
to make the most out of your zRAM. You can permanently change both values by opening/etc/sysctl.conf
file, then puttingvm.page-cluster=0
andvm.swappiness=180
onto different lines.
Hi readers, the last time we met, I told you why zRAM should be enabled by default. And fortunately, enable zRAM on openSUSE is extremely easy. All you need to do is open the terminal, and enter this command:
sudo zypper install systemd-zram-service && sudo zramswapon
Then, open YaST Services Manager, and make zramswap service to start on boot. Now, you should have a zRAM enabled system.
Well, what's the problem with this setup?
Too many zRAM devices are created
After you enabled zRAM with the above command, if you check your zRAM status with sudo zramctl
, you will notice that there are a lot of zRAM devices created, from /dev/zram0
, /dev/zram1
, /dev/zram2
, and so on, depends on your CPU cores. This is because, in the past (before kernel 3.15), there's no multi stream functionality exist yet. Therefore, this was the only way to parallelize the task at that time.
However, this setup is deprecated and not considered a good practice anymore. Because, since kernel 4.7, zRAM will always allocate multiple compression streams - one per online CPU - thus allowing several concurrent compression operations. Moreover, by having a lot of zRAM devices created and mounted at boot time can slow down the boot considerably, as reported here. Therefore, you should only have one zRAM device at a time, but have multiple compression streams instead. For instance, if you're using AMD Ryzen Threadripper 3990X, you should have 128 compression streams on your /dev/zram0
, not 128 zRAM devices to bombard your lsblk
😂
If you check at systemd-zram-service's package repository, you will see that the script corresponding to create zRAM devices was written over 10 years ago!
The compression algorithm is outdated
The default zRAM compression algorithm is lzo-rle
, which has high compressed swap allocations, but has low compression ratio, thus prone to OOM. While zstd
, which is an open source compression algorithm backed by Facebook, may has a lower compressed swap allocations rate, but it has a much higher compression ratio. Therefore, at the end of the day, not only zstd
is the most efficient compression algorithm to use, but it will also finish the compression task faster than lzo-rle
due to its compression ratio advantage. You can see more about zRAM's compression algorithm benchmarks here.
I recommend everyone who uses zRAM to switch over to zstd
.
Let's go faster and better, fix the issues to get our hands on the ultimate zRAM!
You have to nautilus admin:///
and search for zramswapon
script to make our change. This is the current systemd-zram-service
's zramswapon
script:
#!/bin/bash
# get the number of CPUs
num_cpus=$(grep -c processor /proc/cpuinfo)
# if something goes wrong, assume we have 1
[ "$num_cpus" != 0 ] || num_cpus=1
# set decremented number of CPUs
decr_num_cpus=$((num_cpus - 1))
# get the amount of memory in the machine
mem_total_kb=$(grep MemTotal /proc/meminfo | grep -E --only-matching '[[:digit:]]+')
mem_total=$((mem_total_kb * 1024))
# load dependency modules
#modprobe zram zram_num_devices=$num_cpus
# Determine module parm
mod_parm=$(modinfo zram |grep parm |tr -s " " |cut -f2 -d ":")
modprobe zram $mod_parm=$num_cpus
# initialize the devices
for i in $(seq 0 $decr_num_cpus); do
echo $((mem_total / num_cpus)) > /sys/block/zram$i/disksize
done
# Creating swap filesystems
for i in $(seq 0 $decr_num_cpus); do
mkswap /dev/zram$i
done
# Switch the swaps on
for i in $(seq 0 $decr_num_cpus); do
swapon -p 100 /dev/zram$i
done
It tries to get the number of CPU cores first before initializing zRAM devices. We don't want that since we only need one zRAM device. Therefore, here's my zramswapon
script, nice and simple:
#!/bin/bash
# get the amount of memory in the machine
mem_total_kb=$(grep MemTotal /proc/meminfo | grep -E --only-matching '[[:digit:]]+')
mem_total=$((mem_total_kb * 1024))
# load the dependency module
modprobe zram
# initialize the device with zstd compression algorithm
echo $mem_total > /sys/block/zram0/disksize
# Creating the swap filesystem
mkswap /dev/zram0
# Switch the swaps on
swapon -p 100 /dev/zram0
Lastly, we want to use zstd
as our compression algorithm. However, once the device is initialised, there is no way to change compression algorithm. See more about this here. Therefore, we will also have to choose the compression algorithm when we initializing zRAM device:
#!/bin/bash
# get the amount of memory in the machine
mem_total_kb=$(grep MemTotal /proc/meminfo | grep -E --only-matching '[[:digit:]]+')
mem_total=$((mem_total_kb * 1024))
# load the dependency module
modprobe zram
# initialize the device with zstd compression algorithm
echo zstd > /sys/block/zram0/comp_algorithm;
echo $mem_total > /sys/block/zram0/disksize
# Creating the swap filesystem
mkswap /dev/zram0
# Switch the swaps on
swapon -p 100 /dev/zram0
With our new zramswapon
script, we will have a single zRAM device (/dev/zram0
) equal to the size of our physical RAM with zstd
compression algorithm. You will either have to reboot your PC to see this change since the script only run on boot time, or you can just call sudo zramswapoff
and sudo zramswapon
again to see the effect with sudo zramctl
.
However, I recommend you to fork the official systemd-zram-service repository on OBS (Open Build Service), so your script won't get overwritten when you update the package, especially, if you're on Tumbleweed that a new snapshot usually overwrites system files. You can see how to use OBS here.
Well, you can also use systemd-zram-service package on my repository by:
sudo zypper remove systemd-zram-service && sudo zramswapoff
Then, go to my repository's download page > right-click at the download button corresponding to your OS > save link as... > double-click the file to install in YaST. And don't forget to enable zramswap service to start on boot.
I have created a request to make this change upstream, so you won't have to add my repository. Let's hope it will be accepted soon.
I think this's it for today. I hope this is a good read. If you have any comment, please let me know down below. See you later, bye 💨
Cover photo by Ralfs Blumbergs on Unsplash
Urban Building photo by Meriç Dağlı on Unsplash
Old Computers photo by Alex Motoc on Unsplash
The Man Playing Tennis photo by Moises Alex on Unsplash
Top comments (2)
Hi, I've just installed the zram service on my freshly installed opensuse tumbleweed. Your change request has been merged, and the zramswapon script is as you have updated. As a user hating to see zram devices on my lsblk, I thank you for your contribution.
Thanks. I'm glad it helped 🔌