Linux ZRAM Guide: Optimize Memory and Speed Up Your System with Compressed Swap

Linux tutorial - IT technology blog
Linux tutorial - IT technology blog

At 2 AM, my phone buzzed incessantly with a PagerDuty alert: the node cluster running PostgreSQL and Redis was flashing red. The load average had skyrocketed from 1.8 to 28.5, and the API was returning continuous 504 timeouts. After SSHing in and quickly running dmesg -T, a familiar sight appeared: the Out of Memory (OOM) Killer had ruthlessly terminated worker processes. The 8GB of RAM was completely exhausted. Disk I/O hit 100% capacity with %iowait spiking to 85% as the kernel struggled to swap memory pages back and forth with the on-disk swapfile.

Three Approaches to Memory Relief on Linux

When a server runs out of RAM, we generally face three technical choices:

1. Expanding the Swap File or Swap Partition on Disk

This is the classic approach. You allocate a 4GB–8GB file on disk using fallocate, format it as swap, and enable it with swapon:

fallocate -l 4G /swapfile
chmod 600 /swapfile
mkswap /swapfile
swapon /swapfile

2. Zswap (Compressed Cache for Swap)

Zswap acts as a write-back cache between RAM and disk. When the kernel attempts to swap out a memory page, zswap compresses the page and retains it in a pool in RAM. Only when this pool becomes full is compressed data evicted to the physical swapfile on disk.

3. ZRAM (Compressed RAM Block Device)

ZRAM creates a virtual block device directly in RAM (such as /dev/zram0). Any data written to it is compressed on the fly using ultra-fast algorithms like zstd or lz4. The kernel treats it as a standard swap partition, but access latencies are measured in microseconds (µs) rather than milliseconds (ms) typical of disks.

Weighing the Options: Pros and Cons

Each solution is tailored to solve a different problem:

Traditional Disk Swap

  • Pros: Takes 30 seconds to set up. Easily expandable depending on available disk space without consuming an extra megabyte of RAM.
  • Cons: Read/write speeds are thousands of times slower than RAM. When RAM is exhausted, the system descends into disastrous disk thrashing: I/O locks up, CPU gets stuck in iowait, and the server becomes unresponsive. On budget SSDs, sustained swap writes of tens of gigabytes daily will wear down the drive’s TBW (Total Bytes Written) very rapidly.

Zswap

  • Pros: Reduces disk writes by roughly 60–80%. Ideal when you must maintain a large disk swapfile as a final safety net.
  • Cons: Requires an existing disk swapfile or swap partition to operate. Furthermore, evicting pages from RAM to disk during sudden traffic spikes can cause micro-stuttering.

ZRAM

  • Pros: Speeds are nearly on par with physical RAM. Real-world compression ratios hit 2:1 to 3.5:1 for text, code, JSON payloads, or in-memory caches. This means 4GB of physical RAM can store the equivalent of 8GB–14GB of uncompressed data. Everything happens entirely in memory, sparing SSDs from write endurance wear.
  • Cons: Consumes an additional 2–5% of CPU cycles for compression and decompression. If your server is already pinned at 95–100% CPU utilization, you should favor lz4 over zstd.

Why ZRAM Is a Premier Lifesaver

I once managed a 2-Core / 4GB RAM VPS running Magento 2 and MySQL. During midnight flash sales, traffic would surge fourfold, draining RAM in minutes. A 4GB swapfile on NVMe SSD would kick in, driving iowait past 40% until MySQL crashed due to the OOM Killer.

After switching to a 4GB ZRAM setup using zstd, the situation reversed completely: under the same traffic spike, the system absorbed over 2.5GB of compressed swap into RAM with only a ~3% increase in CPU usage. Best of all, load average stayed below 2.5, and not a single process was killed.

For smaller VPS instances (1GB–4GB RAM) or Docker/K8s nodes packed with sidecars, ZRAM is the most cost-effective lifeline available: it stops the OOM Killer in its tracks before you need to upgrade your server plan.

Step-by-Step ZRAM Configuration Guide

Method 1: Quick Setup with zram-tools (Ubuntu / Debian)

On Debian-based distributions, the zram-tools package ships with a convenient systemd service:

sudo apt update
sudo apt install -y zram-tools

Open the configuration file:

sudo nano /etc/default/zramswap

Set the following values:

# Compression algorithm: zstd (best compression ratio) or lz4 (fastest, lowest CPU overhead)
ALGO=zstd

# Allocate 50% of total physical RAM to ZRAM
PERCENT=50

# Set higher priority than on-disk swap (which is typically -2)
PRIORITY=100

Restart the service to apply changes:

sudo systemctl restart zramswap
sudo systemctl status zramswap

Method 2: Manual Setup via Kernel Module (Any Distro: CentOS, RHEL, AlmaLinux, Arch)

If your distribution lacks a management package, you can load the kernel module directly with a few commands:

# 1. Load the zram kernel module
sudo modprobe zram num_devices=1

# 2. Select the zstd compression algorithm for the virtual device /dev/zram0
echo zstd | sudo tee /sys/block/zram0/comp_algorithm

# 3. Allocate a 4GB virtual swap size (uncompressed size)
echo 4G | sudo tee /sys/block/zram0/disksize

# 4. Format the block device as swap
sudo mkswap -U clear /dev/zram0

# 5. Enable with high priority (priority 100)
sudo swapon -p 100 /dev/zram0

Verifying and Monitoring ZRAM Status

Once ZRAM is active, the zramctl command offers the clearest breakdown:

zramctl

Example terminal output:

NAME       ALGORITHM DISKSIZE  DATA  COMPR  TOTAL STREAMS MOUNTPOINT
/dev/zram0 zstd            4G  1.2G 420.5M 460.8M       4 [SWAP]

Column breakdown: DATA reflects 1.2GB of original data, compressed down to 420.5M. Factoring in memory management overhead, ZRAM only consumes 460.8M of actual RAM (the TOTAL column) — yielding an impressive ~2.8:1 compression ratio. Next, check overall swap distribution using standard utilities:

swapon --show
free -h

Fine-Tuning Swappiness via sysctl

However, because ZRAM lives in RAM with microsecond access times, an optimal strategy is to swap inactive pages proactively to free up RAM for Page Cache:

# Check current value
cat /proc/sys/vm/swappiness

# Increase swappiness to 100 so the kernel actively leverages ZRAM
sudo sysctl vm.swappiness=100

To persist this configuration across reboots, append the following two lines to /etc/sysctl.conf:

vm.swappiness=100
vm.page-cluster=0

The vm.page-cluster=0 setting tells the kernel to read and compress individual memory pages (4KB) rather than grouping clusters of $2^3 = 8$ pages (32KB). This small adjustment eliminates unnecessary read/write latency on compressed swap.

Share: