Conjuring RAM Out of Thin Air: My Fleet-Wide zram Optimization Journey

Estimated reading time: 6 minutes

Table of contents

My baseline requirement for any infrastructure project is simple: maximize hardware efficiency without introducing unnecessary wear and tear. Maintaining everything from a MacBook Pro M4 to a Lenovo Yoga Pro 9, a Proxmox hypervisor, a MicroOS container host, and an AlmaLinux VPS means dealing with varying RAM/memory constraints and architectures.

While Apple Silicon handles memory compression natively in hardware, my Linux fleet relies on the CPU. I decided to standardize on zram memory optimization across the board to compress inactive memory pages, effectively creating “phantom RAM” and drastically reducing disk I/O.

Prerequisites

  • A Linux system with a modern kernel (5.x, 6.x or 7.x).
  • Root or sudo access (always use a non-root user with SSH keys).
  • Sufficient CPU overhead (even a few E-cores are plenty for zstd compression).

The Checklist

Before diving in, I defined the following requirements:

  • Standardize on systemd-zram-generator for declarative configuration.
  • Allocate exactly 50% of physical RAM to zram, with sensible hard caps per machine.
  • Use zstd for the best balance of compression ratio and speed.
  • Eliminate disk swap where possible, or use a tiered approach if necessary.
  • Tune sysctl specifically for RAM-based swap.

The Motivation: The “AI Tax” and Sipping, Not Guzzling RAM

We are currently navigating a perfect storm in the memory market. What I call the “AI Tax” has drastically increased the cost of RAM over the past months. Manufacturers are pivoting their fabrication plants to produce High Bandwidth Memory (HBM) for AI accelerators, leaving standard DDR4 and DDR5 capacity constrained. According to market analysts like TrendForce, this has led to massive contract price hikes, making memory an increasingly expensive commodity.

Instead of throwing more expensive physical RAM at the problem, I decided to optimize. For a Manager of DevOps & ICT, my primary desktop “RAM killer” is often hundreds of open browser tabs. On the server side, it is container tmpfs allocations (like Backrest needing 2GB of /dev/shm) and high-density VM workloads.

Here is a bit of the hardware landscape I am working with across my home lab “fleet”:

  • Lenovo Yoga Pro 9: Intel Core Ultra 9 185H with 32GB RAM (Arch Linux)
  • Proxmox VE Host: HP EliteDesk 800 G5 DM, Intel Core i5-9500 with 24GB RAM (Debian)
  • MicroOS Container Host: HP ProDesk 400 G3 DM, Intel Core i5-7500T with 16GB RAM (OpenSUSE)
  • InterWorx VPS: Virtualized CPU with 3.5GB RAM (AlmaLinux)

I wanted to avoid traditional disk-based swap on my NVMe drives across these nodes. While NVMe is fast, swapping to disk still introduces micro-stutters and wears out the flash memory. By utilizing zram memory optimization, the kernel compresses less-active memory pages directly in RAM. Since text, web DOM structures, and configuration files compress easily at 3:1 or 4:1 ratios, I can effectively expand my functional multitasking capacity out of thin air. Because zram relies on available CPU cycles rather than expensive physical memory modules, it is essentially a free upgrade.

The Journey: Intel Xeon vs. Intel Core Ultra

The initial symptom was a creeping memory pressure on my Lenovo Yoga Pro 9 (i9-185H, 32GB RAM). I wondered if I could rely on hardware offloading like Intel’s IAA (In-Memory Analytics Accelerator). The cause of my disappointment was realizing IAA is strictly an Enterprise Xeon feature. The solution, however, was simple: standard Linux zram via the crypto API is highly optimized. The Zen kernel on Arch Linux easily handles the software compression on the i9’s E-cores in microseconds, providing a fluid KDE Plasma experience even under heavy load.

The Solution: A Fleet-Wide zram Rollout

While the core concept is identical, the exact implementation varies slightly across different Linux distributions. I will break down the exact steps and configurations for each.

1. Package Installation

First, install the generator package based on your distribution.

Arch Linux (Laptop):

sudo pacman -S zram-generator

OpenSUSE MicroOS (Container Host):

sudo transactional-update pkg install zram-generator

Proxmox VE 9.x (Debian Trixie):

sudo apt update
sudo apt install systemd-zram-generator

AlmaLinux 9.x (InterWorx VPS):

sudo dnf install -y zram-generator

2. The Configuration Files (zram-generator.conf)

Next, configure the generator. I use a modern ratio-based configuration utilizing the min() function. This prevents scaling issues on systems with massive amounts of RAM.

Arch Linux (32GB RAM – Capped at 16GB):

sudo tee /etc/systemd/zram-generator.conf > /dev/null << 'EOF'
[zram0]
# Allocate zram equal to half of total RAM, capped at 16GiB (16384 MiB)
# Reference: man zram-generator.conf(5)
zram-size = min(ram / 2, 16384)
# Uses zstd for the best balance of ratio and speed on the i9
# zstd is recommended for high-performance multi-core CPUs
compression-algorithm = zstd
# Priority kept at 100 for best practice (default is Systemd priority)
swap-priority = 100
EOF

Proxmox (24GB RAM – Capped at 12GB):

sudo tee /etc/systemd/zram-generator.conf > /dev/null << 'EOF'
[zram0]
# Allocate 50% of RAM as ZRAM swap
# 24GB RAM -> 12GB ZRAM
zram-size = min(ram / 2, 12288)
compression-algorithm = zstd
swap-priority = 100
EOF

MicroOS (16GB RAM – Capped at 8GB):

sudo tee /etc/systemd/zram-generator.conf > /dev/null << 'EOF'
[zram0]
# Allocate 50% of RAM as ZRAM swap
# 16GB RAM -> 8GB ZRAM
zram-size = min(ram / 2, 8192)
compression-algorithm = zstd
swap-priority = 100
EOF

InterWorx VPS (Tiered Setup, ~1.75GB ZRAM):

My VPS has limited RAM (3.5GB) and requires a disk swap as a fallback for MariaDB. Here, zram-size is simply ram / 2. The priority of 100 ensures ZRAM is used BEFORE the disk swap (which defaults to -2).

sudo tee /etc/systemd/zram-generator.conf > /dev/null << 'EOF'
[zram0]
# Allocate 50% of RAM as ZRAM swap (~1.75GB)
zram-size = ram / 2
compression-algorithm = zstd
# Priority 100 ensures ZRAM is used BEFORE the disk swap (Priority -2)
swap-priority = 100
EOF

3. zram Kernel Tuning (Critical Step)

This is where the magic happens. Without sysctl tuning, the kernel will not utilize zram effectively. Since zram is extremely fast (zero seek time), we want to encourage the system to swap to it aggressively rather than dropping our filesystem caches.

Notice that for my pure-RAM setup on Arch Linux, I push vm.swappiness to an aggressive 180 (out of 200). Because the laptop relies entirely on RAM with zero disk fallback, I want the kernel to proactively compress inactive desktop applications (like background browser tabs) as early as possible to keep physical memory pristine for active foreground tasks. Conversely, on the servers (Proxmox, MicroOS, and InterWorx), a value of 150 provides a better balance. Server workloads often require more consistent access to filesystem metadata caches, so scaling swappiness back slightly ensures the kernel doesn’t unnecessarily compress active database or container data.

For Arch Linux (Desktop):

sudo tee /etc/sysctl.d/99-zram-tuning.conf > /dev/null << 'EOF'
# Aggressively move inactive pages to zram (max 200)
# High swappiness is beneficial for zram-only setups to keep physical RAM "fresh"
vm.swappiness = 180
# Balance filesystem cache (important for DevOps build tools)
vm.vfs_cache_pressure = 50
# Optimized for RAM-based swap (0 = disable swap read-ahead)
# This prevents the kernel from reading extra pages into RAM unnecessarily
vm.page-cluster = 0
EOF

For Proxmox, MicroOS, and InterWorx Servers:

sudo tee /etc/sysctl.d/99-zram-tuning.conf > /dev/null << 'EOF'
vm.swappiness = 150
vm.vfs_cache_pressure = 50
vm.page-cluster = 0
EOF

Apply the kernel parameters:

sudo sysctl --system

4. Activation and Verification

Finally, reload the systemd daemon and start the zram devices. If you are on an immutable OS like MicroOS, you will need to reboot instead.

For standard distributions:

sudo systemctl daemon-reload
# Drain any old swap if adjusting live: sudo swapoff /dev/zram0 || true
sudo systemctl start /dev/zram0

Verify the setup:

zramctl
swapon --show
sysctl vm.swappiness vm.vfs_cache_pressure vm.page-cluster
zram on Lenovo Yoga Pro 9 16IMH9
zramctl, swapon and sysctl on the Lenovo Yoga Pro 9 16IMH9

You should see /dev/zram0 listed with your configured size and a high priority (100). The DATA and COMPR columns in zramctl will eventually show you exactly how much space you are saving.

htop on the Lenovo Yoga Pro 9 16IMH9

Final Thoughts

By standardizing on a dynamically sized zram configuration, I have significantly improved the stability and responsiveness of my entire infrastructure. The Lenovo Yoga Pro 9 now acts as if it has 48GB of RAM (or even 80GB if that 16GB of zram can be compressed at a 4:1 ratio) when handling hundreds of browser tabs. My Proxmox and MicroOS nodes have a robust safety net against container memory spikes, and my AlmaLinux VPS serves PHP applications faster by deferring disk I/O.

It is a straightforward, logical architectural decision: trade a tiny fraction of CPU time for a massive reduction in latency, disk wear, and more “phantom” RAM.


Buy me a coffee 🙂
If you found this post helpful, informative, or if it saved or made you some money, consider buying me a coffee. Your support means a lot and motivates me to keep writing.
You can do so via bunq.me (bunq, iDeal, Bankcontact and Credit- or Debit cards) or PayPal (PayPal and Credit- or Debit cards). Thank you!

Disclaimer
The blog posts, guides, and scripts provided on this website are for informational and educational purposes only. They are provided “as is” and without any warranty of any kind, either express or implied, including, but not limited to, the implied warranties of merchantability, fitness for a particular purpose, or non-infringement.
By using the information or scripts from this blog, you agree that I am not liable for any direct, indirect, incidental, consequential, or any other damages or losses arising from the use of or inability to use the information, scripts, or instructions contained herein. You assume full responsibility for any and all risks associated with the use of this content.
The blog posts, guides, and pages may contain referral/affiliate links. If you make a purchase through these links, I may receive a commission at no additional cost to you.

 
Posted in AlmaLinux, Arch Linux, Debian, Hardware, Home Lab, Linux, Linux Tutorials, OpenSUSE, Proxmox, System AdministrationTags:
Write a comment