Ramblings of an aging IT geek
← Ramblings of an aging IT geek
linux

how much swap, finally answered for my own boxes

After years of cargo-culting swap sizing, I worked out what actually makes sense for my homelab machines and why zram changed the answer.

A Linux terminal showing memory and swap usage

The swap question has a dozen confident answers and most of them are stale. "Twice your RAM" is advice from an era when RAM was measured in megabytes. "None, RAM is cheap now" is the modern overcorrection. After tidying up half a dozen homelab boxes this week I have settled on what I actually do, and the short version is: a little disk swap for safety, zram for the real work.

The insight that resolved it for me is that swap is not one thing doing one job. It is doing two, and they want different answers.

The first job is reclaiming cold pages. There are always anonymous pages that get touched once at boot and then never again. With zero swap they sit in RAM forever, taking up space that the page cache could use. A modest swap lets the kernel evict them and put the memory to work. This is good and you want it. You enable it by allowing a low but non-zero vm.swappiness, not by setting it to 0.

The second job is the emergency cushion when you genuinely run out of memory. Here swap mostly buys you time before the OOM killer fires, and on spinning rust or even a SATA SSD that time is spent thrashing so hard the machine is unusable anyway. Disk swap as an OOM cushion is a way of converting a fast crash into a slow one.

A homelab server humming away on a shelf

So here is the setup I now put on everything. A small zram device sized at roughly half of RAM, giving compressed in-memory swap that is genuinely fast, plus a small fixed disk swap of 2 to 4GB as a last-resort backstop, with zram given priority.

# zram, sized in /etc/systemd/zram-generator.conf
[zram0]
zram-size = ram / 2
compression-algorithm = zstd
# nudge the kernel to actually use swap before reclaiming cache
sysctl vm.swappiness=60
swapon --show

A swappiness of 60 sounds high to anyone trained in the "lower is better" school, but with zram the swap is RAM, just compressed, so swapping to it is cheap. You want the kernel to lean on it. The numbers that come back from zramctl are the satisfying part: I routinely see 3 to 1 compression on the anonymous pages, so half of RAM as zram absorbs more than half of RAM's worth of cold data, for the cost of a little CPU.

The disk swap stays tiny and at lower priority precisely because I never want to use it in anger. It exists so that hibernation works on the laptops and so a runaway process gets a few seconds of grace before the OOM killer does its job, rather than to be a real tier of memory.

That is the whole answer for my homelab. Half-of-RAM zram with zstd, a 2 to 4GB disk backstop, swappiness at 60. It is not the right answer for a database server with a hard latency budget, and it is not the right answer for a 256GB workstation that simply never runs out. But for the general-purpose, memory-is-occasionally-tight boxes that make up a homelab, it has stopped me thinking about swap entirely, which is exactly what good defaults should do.