Compression springs by User:Renard~enwiki on Wikimedia Commons licensed under CC BY-SA 3.0
Compression springs by User:Renard~enwiki on Wikimedia Commons licensed under CC BY-SA 3.0

I remember when Apple announced Mac OS X 10.9 Mavericks in 2013, and one of their advertised features was compressed RAM. Their claim was something along the lines of a machine with 4 GB of RAM suddenly having 6 GB of RAM thanks to this new technique.

I’ve been thinking, surely we can have that on Linux.

Now, Apple doesn’t just compress all of the RAM, from what I could find, it starts to compress RAM of idle processes.

Well, what does Linux do when RAM starts to get too full? It will swap it out, assuming a swap device exists.

And, what else can Linux do? It can do zram, which gives you a block device in RAM. That block device can be compressed *and* one can use it as swap… I think that’s our ticket!

Disabling zswap

Linux can compress things before swapping it out; we want to disable this feature. That’s because our zram will already be using compression and it doesn’t make sense to double compress. So the first order of business is to disable zswap. We achieve this by passing zswap.enabled=0 to our kernel cmd. We can achieve this by e.g. editing /etc/default/grub and adding it to GRUB_CMDLINE_LINUX (assuming you’re using GRUB – don’t forget to update-grub). If you’re using another bootloader, check its documentation on how to pass kernel arguments.

Enabling zram

Next thing we want to do, is to create the file /etc/modules-load.d/zram.conf with the following contents:

zram num_devices=4

This will make sure Linux will load the zram kernel module on boot and create 4 zram devices. In theory we can just specify zram and it will only create one, but it can’t hurt to have multiple spares ready in case we want to tinker on a live system!

Generating swap on zram

To generate the zram, we’ll want to use a systemd zram-generator. In the case of Ubuntu you’ll want to install systemd-zram-generator and in case of Arch Linux zram-generator.

sudo apt install systemd-zram-generator

Next we edit the file /etc/systemd/zram-generator.conf and edit the [zram0] block so that it looks like this:

[zram0]
zram-size = ram
compression-algorithm = zstd
swap-priority = 32767

This will make sure that the zram device will be as big as the full physical RAM and compressed with zstd. As the system starts to fill the RAM, it will start to compress the RAM and swap it back into RAM in compressed form. I guess that’s close enough to Apple Magic? :D

Now we simply reboot and we should see our new beautiful swap when running free -h or lsblk or htop or whatever else you like to use. :3

A note on /tmp

In theory, if we don’t already have /tmp set up, we can expand /etc/modules-load.d/zram.conf with another block:

[zram1]
zram-size = ram / 2
compression-algorithm = zstd
mount-point = /tmp

This will make sure we have a /tmp which is half the size of all physical memory (just like with the default behavior of tmpfs) but I actually don’t recommend this.

See, depending on your use-case /tmp should be *fast*, so, compressing and uncompressing everything that’s written/read to /tmp might not be desirable. However, if /tmp was on spinning rust (a HDD) beforehand, then you probably don’t care about such performance impacts, anyway.

However, my recommended way is to set up /tmp through /etc/fstab instead:

tmpfs   /tmp         tmpfs   rw,nodev,nosuid          0  0

Why? Simple: We already have swap on zram, and we want /tmp to be fast by default, and as /tmp – which will be half of all physical RAM by default – starts to get filled up, it will be swapped out, swapped out to our zram device. This way we get a good balance between a fast /tmp and compression to zram as needed. (:

Note: After you made all your changes *reboot* don’t just remount. If you currently have things on /tmp, remounting will make all processes relying on files there to get sad.

Conclusion

We managed to recreate some magic quite easily! Now we have more RAM! Download free RAM today! :D

I run this blog in my free time. If I helped you out, consider donating a cup of coffee. <3 (: