For years my answer to "how much swap" was whatever the installer suggested, which is to say I had no answer, just a habit. On my homelab boxes that meant a grab-bag of sizes, some with twice RAM because that's the rule someone taught me in 2004, some with none because a blog post once told me swap was obsolete, and at least one with a 16GB swap partition on an SSD I was actively trying not to wear out. Time to actually decide.
The "no swap" crowd and the "lots of swap" crowd are both half right, and they're arguing about different machines. So here's where I landed, machine by machine, after measuring rather than believing.
what swap is actually for
The useful framing, for me, was to stop thinking of swap as "extra RAM" and start thinking of it as a release valve for cold pages. Linux would much rather evict a page that hasn't been touched in an hour, an idle daemon, the unused half of some service's heap, than drop a hot file cache page it's about to need again. Without swap it can't do that. The anonymous page has nowhere to go, so the kernel keeps it resident and throws away cache instead. That's often the wrong trade.
vm.swappiness controls how eagerly it makes that trade. The default of 60 is tuned for desktops. On a server with real working sets I want it low but not zero, so the kernel will lean on swap for genuinely cold pages under pressure but won't pre-emptively shuffle warm ones to disk.
the settings I actually use
After a few weeks of watching vmstat, si/so columns, and how the boxes behaved under their real workloads, I settled on this:
# /etc/sysctl.d/10-swap.conf
vm.swappiness = 10
vm.vfs_cache_pressure = 50
swappiness = 10 means: only swap when you really need to, but you are allowed to. vfs_cache_pressure = 50 tells the kernel to hold onto inode and dentry caches a bit harder, which on my file-heavy boxes noticeably cut down on metadata stalls.
For sizing, I stopped using ratios entirely and used roles:
- The Postgres box: a small swap, 2GB, on its own. Not because Postgres should swap, it shouldn't, but because a small swap plus a low swappiness lets the kernel evict the genuinely idle pages around it and keep more RAM for the page cache that actually makes the database fast. If it ever swaps heavily I want that to show up as a loud alert, not silently.
- The general dogsbody box running a dozen small containers: 4GB swap, swappiness 10. These have lumpy, bursty memory and a release valve here has saved me from the OOM killer picking a victim at the worst possible moment more than once.
- The router-ish box with predictable, tiny memory use: no swap. It never needs it, and a swapless box fails fast and obvious when something goes wrong, which is exactly what I want from infrastructure.
zram, the thing that actually changed my mind
The piece that settled the argument for me wasn't a partition at all, it was zram. A compressed swap device in RAM. It sounds like nonsense, swapping memory into memory, but for boxes where cold anonymous pages compress well, it's brilliant: you get the kernel's "release valve" behaviour without touching the SSD at all, and compressed cold pages take a fraction of the space.
On the container dogsbody I now run a zram device sized at half of RAM, with a tiny disk swap behind it as a true emergency overflow. The SSD wear problem evaporated. The OOM-killer dramas stopped. And I no longer have to have the swap argument, because the answer is now boring, written down in a sysctl file, and justified by numbers rather than by something I half-remember from a forum. That's the whole win, really: not the optimum, just a default I can defend.