Running Out of RAM on Linux? Add Zram Before Upgrading!
Over the past few weeks, the RAM (or system memory) usage on my workstation has increased due to a heavier workload across multiple workspaces. Largely due to an increased number of open web browser tabs as well as other applications spread across 8 other workspaces.
With 16 GB of RAM on my system, lately I’ve been having heavy swapping and, at times, the OOM killer would kill the web browser entirely. Of course, I could reopen and restore my tabs, but this disrupts workflow. Sometimes, for as much as 10 seconds, the system would freeze during swapping.
Read: Raspberry Pi Performance: Add ZRAM and these Kernel Parameters
While upgrading to 24 GB or 32 GB of RAM is an option, before taking that route, I remembered how zram significantly improved performance on my Raspberry Pi a few years back. Using this same method, I have set up zram which now has completely solved my low-memory performance related issues.
Zram configuration and sysctl memory tuning for Debian/Ubuntu Linux
This article is for anyone in a similar situation: instead of immediately buying more RAM, try Zram swap first. The guide below also applies to Linux servers where you just need a bit more legroom. However, unlike desktop, workloads on servers typically follow an upward trend, so 9/10 times it’s better to just add more RAM. Especially if we have already optimized application code and queries. Now on to the article.
Table of Contents
What is Zram, and How Does it Work?
With 16 GB RAM, and 8 GB allocated to Zram (Zstd compression, ratio ~3 to 4),
your system can store approximately 32 GB to 40 GB of data in memory before needing to swap to disk!
Put simply, Zram is a compressed swap space stored in RAM that reduces the need for disk-based swap when your Linux system is running low on memory. Unlike traditional swap on SSDs/HDDs, Zram keeps swap data in memory (much faster than disk swap), compressing it to save space and improve speed.
Zram supports multiple compression algorithms, including lzo
, lzo-rle
, lz4
, lz4hc
, and zstd
, each offering a trade-off between speed and compression efficiency.
Algorithm | Time | Data | Compressed | Ratio |
---|---|---|---|---|
lzo | 4.6s | 1.1G | 387.8M | 2.689 |
lzo-rle | 4.5s | 1.1G | 388M | 2.682 |
lz4 | 4.5s | 1.1G | 403.4M | 2.582 |
lz4hc | 14.6s | 1.1G | 362.8M | 2.872 |
zstd | 7.8s | 1.1G | 285.3M | 3.961 |
(Source: linuxreviews.org/Zram)
For modern CPUs (including my not-so-modern Ryzen 7 5700x), Zstd compression is recommended, as it offers the best balance between speed and compression. Allowing Zram to significantly extend usable memory without physical upgrades.
Read: Linux Performance: Almost Always Add Swap Space.
How to install and setup Zram on Debian systems
Some Linux distros like Pop!_OS have Zram installed or enabled by default.
The following instructions apply mainly to Debian 12+, Ubuntu 22.04 LTS+, and their derivatives (such as Linux Mint, Pop!_OS, and others). For Fedora, openSUSE, Arch, and other distributions, the installation steps may differ. On some distros, Zram will already be installed by default. Also, check your distro’s package manager (dnf
, zypper
, pacman
, etc.) for zram-tools
or follow your distribution’s specific documentation for enabling Zram:
- Red Hat/Fedora: SwapOnZRAM | SwapOnZRAM_install_and_enable.
- SUSE/openSUSE: Installation, Configuration and Management of zram.
- Arch Linux: wiki.archlinux.org/title/Zram
Step 1: Installing Zram on Debian/Ubuntu Systems
Since I’m running a Debian-based distro, installing Zram was simple:
sudo apt update sudo apt install zram-tools
This package manages Zram setup automatically.
Step 2: Configuring Zram Swap
My /etc/default/zramswap config file.
Edit the Zram configuration file:
sudo vi /etc/default/zramswap
Modify or add the following settings. These settings tune Zram for compression efficiency, memory allocation and swap priority. ALGO=zstd
for strong compression ratio and good performance on modern CPUs, smaller memory footprint and speed (see compression algorithms table above). PERCENTAGE=20
so only 20% of total RAM is used for Zram swap, to avoid compression overhead, but if you have less than 8 GB RAM you can increase this to 50% for better swap performance when low on memory. PRIORITY=100
to make Zram higher priority than disk swap, so compressed memory is used before slow SSD or HDD swap and makes the system more responsive:
ALGO=zstd PERCENTAGE=20 PRIORITY=100
Save and exit, then restart Zram:
sudo systemctl restart zramswap
To verify Zram is active, run:
zramctl
or
swapon --show
Step 3: Adjust Linux Memory Behavior for Zram Efficiency
By default, Linux might use Zram too aggressively or may still prefer slow disk swap. Check your defaults with:
sudo sysctl -a | grep -E 'vm.vfs_cache_pressure|vm.swappiness|vm.dirty_background_ratio|vm.dirty_ratio'
To tweak this, adjust swappiness and memory caching settings:
sudo vi /etc/sysctl.d/99-zram-tweaks.conf
Add this (tweak based on your preference, see explanations below):
vm.swappiness=50 vm.vfs_cache_pressure=50 vm.dirty_background_ratio=5 vm.dirty_ratio=10
Apply changes:
sudo sysctl --system
How These sysctl
Settings Affect Performance
vm.swappiness=50
– Balances swap usage between RAM and Zram. A mid-range value like 50 ensures that Zram is used more actively without over-prioritizing it. This prevents sudden memory pressure while the most active data remains in RAM. Recommended range of 10-100 depending on your workload, hardware specs (CPU, HDD or SSD, total RAM, etc).
vm.vfs_cache_pressure=50
– Controls how much the kernel reclaims inode and dentry caches. Setting this to 50 keeps a good balance between freeing cached data and keeping frequently used files in memory. If you have less than 8 GB of installed RAM, or exhausting RAM + Zram, then increase this value (e.g., 100-200) to clear saved cache faster. Larger cache = better system performance.
vm.dirty_background_ratio=5
– When the kernel starts writing unsaved (“dirty”) data to disk in the background. A low value like 5% means disk writes happen gradually, not sudden large I/O operations that could slow down or freeze your system.
vm.dirty_ratio=10
– When dirty data reaches 10% of total RAM, the system forces a flush to disk. Keep this low to prevent large untimely writes that could slow down your system. If you have fast NVMe storage, you can increase this to 20 to 30 to reduce frequent small writes.
Why vm.dirty_*
Settings Matter: Even With Zram enabled
Even if you’re using Zram swap, your system will still write data to disk for files, logs, and caches. So vm.dirty_*
settings are useful for controlling disk write behavior, while Zram’s itself affects how swap is handled in memory.
Read: Linux Performance: Almost Always Add Swap Space – Part 2: ZRAM.
Zram Results
100+ tabs in Workspace #1, 200+ more in #8, and many open apps, but NO disk swap. (Larger image)
After enabling Zram and tweaking memory settings, my system handles high tab usage much better. I really put this to the test. I had a tab count of 200+ on iPhone, so opened all (using Chrome history) and loaded them all into memory by using the mouse wheel over each table from left to right. My CPU was at 100% for about 30 seconds and there was a massive exodus of memory to swap (Zram).
I was able to fit a total of perfectly over 300 tabs and 8 workspaces with multiple apps open in memory and Zram without any spill over to Zram.
- No more sudden Chrome crashes due to OOM killer.
- Less reliance on slower NVMe swap.
- More tabs + workspaces without slowing down.
Memory usage and storage: with many apps and 100’s of open browser tabs.
Instead of spending money on extra RAM, Zram effectively increased my usable memory at no cost.
Read: Increase the Performance and lifespan of SSDs & SD Cards.
Conclusion
Should You Use Zram Before Upgrading RAM? Yes! System Responsiveness now remains smooth during swapping.
If you’re running out of RAM due to browser tabs, virtual machines, or other memory-hungry tasks—especially on Linux desktop—Zram is a no-brainer! It’s a lightweight solution that extends memory usage and avoids unnecessary SSD wear.
However, if your workload consistently maxes out RAM and Zram, then upgrading RAM is what you’ll need to do. If you’re on Debian-based distros (Ubuntu, Pop!_OS, etc.), give Zram a try before spending money on more RAM!
Additional reading:
I’d love to hear how Zram works for you, especially if you’re trying it for the first time! For those who’ve already been using it, feel free to share your setup, tweaks, tips, and screenshots.
One thing I didn’t mention in the article was the dual-channel compromise when adding more RAM. My B550 has 4 RAM slots and I have 2×8GB running in dual-channel at, 3600MHz. If I add just 1 more 8 GB, my system will go into mixed dual/single-channel mode where the first 16 GB will be in dual-channel and the extra 8 GB will be in single-channel and potentially lose some performance.
To keep full dual-channel, the best approach would be to add 2 more 8 GB to make 32 GB (4×8GB) and keep the 3600MHz. But when you populate all 4 slots some boards will downclock the RAM to make it more stable, including mine, from reading they will drop to 3200Mhz, then there’s the Infinity Fabric Clock (FCLK) which I have set at 1800MHz.
In any case, before next reboot I will adjust my Zram config to use 25% (4 GB RAM) instead of 50%. I’ve been working on this article for the past week, during which I noticed that 8 GB of Zram was overkill.
So instead, 12 GB RAM will be untouched, and 4 GB will be used for Zram swap.
EDIT (additional thoughts on this topic)
Regarding swappiness
The Arch Wiki recommends vm.swappiness=180 - I understand it, given how much faster Zram is compared to disk-based swap. However, I think a lower setting (< 100) also acknowledges the reality that Zram is still significantly slower than RAM itself.
While Zram offers a major speed advantage over traditional swap, it still introduces compression and decompression and CPU overhead, making it far from a perfect replacement for direct memory access.
I’ve also been experimenting with different values. Setting
vm.swappiness=200
caused swap to Zram to kick in at ~85% memory usage.At
swappiness=10
, swap didn’t start until ~95% memory usage, which closer to the behavior I prefer.This reinforces my preference for a low swappiness (10 - 50), keeping RAM usage prioritized before swapping. That said, I can see higher values (< 100) being useful for systems that struggle with memory pressure. Especially if there’s less than 8 GB of RAM installed.
100+ swappiness still seems a bit aggressive, to me, but it’s worth testing different values based on your workload.
What about Zswap?
swapon
?Zswap is a swap cache, not a swap device.
– It only compresses memory when swap is actually needed.
– Zram always reserves memory upfront, Zswap only uses memory dynamically as swap pages are created.
– For systems with fast SSDs or NVMe, Zswap can reduce disk swap writes while still letting the SSD handle overflow.
Zram on the other hand, creates a compressed swap space in RAM as a compressed block device.
– Some RAM is “reserved” for Zram, so less RAM is available for applications.
– However, because of compression (e.g. Zstd 3:1 or 4:1), you can store more data than the default allocated RAM.
– If you allocate 4GB to Zram, you don’t “lose” 4GB, you get extra up to 12GB extra.
Consider trying out vm.page-cluster=0 too, reference: “new zram tuning benchmarks” on the fedora Reddit, can’t post links here, yet.
Thanks, @stereomato Added that link for you. Also see: Trust Level System (Guide).
This morning, I’ve been benchmarking RAM vs. Zram vs. disk swap (NVMe).
I tried this out. I’m not really sure how well I’ll notice if this improves my machine’s performance but I enjoy learning about ‘tweaking’ and improving performance through configuration and similar methods.
Hopefully this info isn’t too sensitive but this is what I’m working with.
And here are my results. At least here are the outputs of the same commands in the original post!
My disk is a HDD. It can sometimes feel slow, it might take 8-10 seconds to load google chrome when I launch that and I can hear the disk spinning as data is retrieved. But that being said its not horrible. I can run minecraft Java, I tried some shaders and they ran very laggy (the game ran fine but the image was jumpy so maybe lag isn’t correct), I tweaked a lot of the performance video settings very low and It ran very smoothly but at that point, why even try to use shaders.
So after I did that I thought, maybe this has more to do with my GPU than working memory anyways and also I do not know if I would need to allocate more RAM for minecraft after doing the zram/zswap tweaks for those to be able to take affect.
If this topic went way over my head and I’m confusing anyone, apologies! I at least appreciated this post and enjoyed the process of trying it out.
Nice! You probably won’t notice any improvement until you have exhausted memory and started swapping to Zram.
Since you are using a HDD there are some suggested kernel tweaks for your setup:
Change the Zram size to 2 GB instead of 4. (25% instead of 50%) Then make sure
ALGO=zstd
because the higher compression is better. This will mean 6 GB RAM untouched, 2 GB that can store ~ 6 GB of in-memory zram swap. So the net effect will be 12 GB stored in memory before needing to swap to HDD.Then tweak these:
vm.dirty_expire_centisecs
&vm.dirty_writeback_centisecs
Reduces large sudden writes by flushing dirty pages more frequently (15 seconds) in smaller batches, preventing big I/O spikes.vm.page-cluster=0
Ensures that when swap is needed, pages are read in smaller chunks. (default 3, higher means more I/O)These help to reduce large sudden writes by spreading them out more evenly, which is especially useful for HDDs to avoid I/O bottlenecks.
Also apply advice here:
Reduce logs they write frequently, etc. Be careful. Apply all of these at your own risk and responsibility.