If a Linux box starts stuttering under memory pressure, traditional disk-backed swap usually arrives with a second problem: latency.
A better middle ground on many systems is zram. It creates a compressed block device in RAM, and you can use it as swap. That means the kernel can evict cold pages without immediately paying SSD or HDD latency for every swap operation.
The key detail is that zram is not preallocated. Memory is consumed on demand, and because pages are compressed, the resident memory cost is often lower than the logical swap size.
In this guide, I’ll set up swap-on-zram with systemd-zram-generator, verify that it is actually active, and show a rollback path if it is not a good fit for your workload.
When zram is a good fit
zram usually helps when:
- you want smoother behavior during short memory spikes
- you run developer tools, browsers, light containers, or modest local AI workloads on limited RAM
- you want swap that is much faster than disk-backed swap
- you do not rely on hibernation via swap-only-on-zram
zram is usually a poor fit when:
- your workload needs heavy, sustained page eviction and large working sets far beyond RAM
- your pages are poorly compressible
- you specifically need a classic hibernation target and only have zram swap configured
In other words, zram is a pressure relief valve, not a magic RAM upgrade.
What the docs actually say
A few facts worth grounding before we touch config:
- The Linux kernel docs describe zram as a compressed RAM-based block device that can be used for swap,
/tmp, and other temporary storage. - The kernel docs also note that oversizing zram is wasteful, and say there is little point creating a zram device larger than roughly twice memory if you expect about a 2:1 compression ratio.
-
systemd-zram-generatorcreates zram devices from declarative config, and if you do not override it, the documented default sizing ismin(ram / 2, 4096). - The
zram-generator.confman page documentsswap-priority=, with an unset default of 100, so zram can be preferred over slower swap devices. - Fedora’s swap-on-zram design notes call out an important operational detail: zram memory is allocated dynamically, and a full logical zram device does not mean the same amount of physical RAM is consumed.
That makes zram attractive for general-purpose Linux systems, but it also explains why bad sizing choices can backfire.
Install the generator
Debian 12+ / Ubuntu versions that package it
sudo apt update
sudo apt install systemd-zram-generator
Fedora
If you want the package plus Fedora’s default config behavior:
sudo dnf install zram-generator-defaults
If you want only the generator and your own config:
sudo dnf install zram-generator
Arch Linux
sudo pacman -S zram-generator
Create an explicit config
Even if your distro ships defaults, I prefer an explicit local config so the system’s behavior is obvious later.
Create /etc/systemd/zram-generator.conf:
[zram0]
zram-size = min(ram / 2, 4096)
compression-algorithm = zstd
swap-priority = 100
What those settings do:
-
zram-size = min(ram / 2, 4096)keeps the logical device conservative: half of RAM, capped at 4 GiB -
compression-algorithm = zstdrequestszstdif the kernel exposes it for zram on your system -
swap-priority = 100makes zram preferred over lower-priority disk swap
A slightly larger example for RAM-rich systems
If you have a machine with more memory and occasional spikes, you might prefer a piecewise rule like this:
[zram0]
zram-size = min(min(ram, 4096) + max(ram - 4096, 0) / 2, 8192)
compression-algorithm = zstd
swap-priority = 100
That means:
- first 4 GiB of RAM maps 1:1 into zram sizing
- RAM above 4 GiB contributes at a 1:2 rate
- the final zram size is capped at 8 GiB
I like this better than blindly setting zram-size = ram, especially on workstations where you want a safety margin, not CPU-heavy swap thrash.
Apply the config
Reload systemd’s generators and start the device:
sudo systemctl daemon-reload
sudo systemctl start /dev/zram0
On the next boot, it should come up automatically.
Verify that it really works
Do not stop at “the package installed”. Verify all the moving parts.
1) Check active swap devices
swapon --show --bytes --output=NAME,TYPE,SIZE,USED,PRIO
Example:
NAME TYPE SIZE USED PRIO
/dev/zram0 partition 4294967296 0 100
/dev/nvme0n1p3 partition 8589934592 0 -2
If both zram and disk swap exist, the higher priority means zram is preferred first.
2) Inspect the zram device
zramctl
Example fields worth watching:
ALGORITHMDISKSIZEDATACOMPRTOTALSTREAMS
3) Read kernel-exported stats
cat /sys/block/zram0/mm_stat
cat /sys/block/zram0/io_stat
The kernel docs define useful values in mm_stat, including:
-
orig_data_size, the uncompressed data stored in zram -
compr_data_size, the compressed size -
mem_used_total, the actual memory consumed including overhead -
huge_pages, incompressible pages
That makes it easy to see whether zram is helping or just burning CPU on data that barely compresses.
A safe way to test under memory pressure
You do not need to crash a host to validate the setup.
First, record the baseline:
free -h
swapon --show
zramctl
Then create a temporary memory load. One simple option is stress-ng:
sudo apt install stress-ng # Debian/Ubuntu
# or: sudo dnf install stress-ng
# or: sudo pacman -S stress-ng
stress-ng --vm 2 --vm-bytes 70% --timeout 60s --metrics-brief
While it runs, watch:
watch -n 1 'free -h; echo; swapon --show; echo; zramctl'
What you want to see:
-
USEDon/dev/zram0increases under pressure -
zramctlshows compressed data smaller than original payload - the machine stays responsive enough to keep working
What you do not want to see:
- severe CPU thrash from compression
- very poor compression ratios on your real workload
- pressure so sustained that zram only delays the inevitable by a few seconds
If you also have disk swap
That can be a good thing.
A practical pattern is:
- keep zram at higher priority for fast first-stage pressure relief
- keep disk swap at lower priority as a slower overflow path
Check priorities with:
swapon --show --output=NAME,PRIO
If needed, you can set a lower priority for disk swap in /etc/fstab, for example:
UUID=xxxx-xxxx none swap defaults,pri=10 0 0
Then keep zram at swap-priority = 100.
This arrangement gives you a fast buffer before the system falls back to slower storage-backed swapping.
When zram is the wrong answer
zram is not a replacement for capacity planning.
If a box routinely runs out of RAM because:
- too many containers are pinned in memory
- a database cache is oversized
- a model server is allowed to grow without limits
- the workload needs true eviction to disk more than compressed in-RAM storage
then the fix is usually one of these:
- reduce memory pressure at the service level
- add real RAM
- keep a lower-priority disk swap path
- use service-level limits and OOM policy
zram helps the most with bursts and moderate overcommit, not chronic memory abuse.
How to disable or roll back
If you want to turn it off cleanly:
sudo swapoff /dev/zram0
sudo systemctl stop /dev/zram0
sudo rm -f /etc/systemd/zram-generator.conf
sudo systemctl daemon-reload
If your distro enables zram through a vendor default package, you may also need to remove that package or mask its config according to distro policy.
After rollback, confirm:
swapon --show
zramctl
A practical baseline I’d use
For a laptop, mini PC, or general-purpose Linux workstation, I’d start here:
[zram0]
zram-size = min(ram / 2, 4096)
compression-algorithm = zstd
swap-priority = 100
Then I would verify three things on the real workload:
- responsiveness during memory spikes
- actual compression ratio from
zramctlandmm_stat - whether disk swap still needs to exist as a lower-priority fallback
That gets you something pragmatic: better behavior under pressure, simple config, and a clean rollback path.
References
- Linux kernel documentation, “Compressed RAM-based block devices (zram)”: https://docs.kernel.org/admin-guide/blockdev/zram.html
-
systemd-zram-generatorREADME: https://github.com/systemd/zram-generator -
zram-generator.conf(5)man page: https://manpages.ubuntu.com/manpages/questing/man5/zram-generator.conf.5.html - Fedora Change proposal, “SwapOnZRAM”: https://fedoraproject.org/wiki/Changes/SwapOnZRAM
Top comments (0)