Back to tutorials
Tutorial

Linux VPS swap tuning: set up zram and swappiness to prevent OOM (2026 tutorial)

Linux VPS swap tuning tutorial: configure zram and swappiness to prevent OOM kills and stabilize workloads in 2026.

By Anurag Singh
Updated on Apr 25, 2026
Category: Tutorial
Share article
Linux VPS swap tuning: set up zram and swappiness to prevent OOM (2026 tutorial)

Your VPS can look “fine” until the kernel’s OOM killer terminates PHP-FPM, MySQL, or a WordPress cron. The usual culprit is memory pressure. Page cache gets squeezed, traffic spikes hit, and there’s no buffer.

Linux VPS swap tuning fixes that by making pressure predictable. It adds headroom without turning your SSD into a swap furnace.

This tutorial walks through a practical 2026 setup for small-to-mid VPS plans. You’ll enable zram (compressed RAM swap), choose sensible swappiness, and add a few guardrails. You’ll verify each change with quick checks and keep a clean rollback path.

What you’ll build (and when it’s the right fix)

  • zram-based swap to absorb short spikes without hammering disk I/O
  • Conservative swappiness so the kernel prefers keeping working sets in RAM
  • Optional small disk swap as a “last resort” safety net (only if you need it)
  • Verification steps to confirm it’s working under load

This approach fits common hosting stacks. That includes Nginx/Apache + PHP-FPM, MySQL/MariaDB, Redis, and control panels.

If your server is already out of RAM at idle, tuning won’t rescue it. You need more memory, fewer services, or both.

In that case, a right-sized HostMyCode VPS (or stepping up to managed help) is the straightforward fix.

Prerequisites and baseline checks

The commands below target Ubuntu 24.04 LTS and Debian 12/13. Notes for AlmaLinux/Rocky Linux 9 are included where behavior differs.

1) Confirm current memory and swap behavior

uname -r
free -h
swapon --show
cat /proc/sys/vm/swappiness
cat /proc/sys/vm/vfs_cache_pressure

Interpretation:

  • Swap: 0B is common on new VPS builds. It’s also why sudden spikes can go straight to OOM kills.
  • swappiness defaults are often too high for web workloads (commonly 60).

2) Check whether you’re actually hitting OOM

journalctl -k --grep="Out of memory" --since "7 days ago"
dmesg -T | grep -i "killed process" | tail -n 20

If you see PHP-FPM, mysqld, or nginx workers getting killed, treat that as a clear signal. Add a buffer (zram) and reduce memory thrash.

If you’re also seeing 502/504 errors during spikes, pair this tutorial with the practical diagnostics in VPS hosting troubleshooting checklist: fix slow sites, 502 errors, and random downtime in 2026.

Step 1 — Install and enable zram (compressed swap in RAM)

zram creates a swap device backed by compressed RAM. The trade-off is simple: swap becomes more CPU-bound and far less dependent on disk I/O.

For bursty traffic, that usually keeps the server responsive. It also helps prevent a spiral into timeouts.

Ubuntu/Debian: install zram-tools

sudo apt update
sudo apt install -y zram-tools

On many Ubuntu/Debian builds, zram-tools config lives at /etc/default/zramswap. If that file doesn’t exist, the package may rely on systemd defaults.

Either way, confirm the final state with the verification commands below.

Configure zram size and algorithm

Edit:

sudo nano /etc/default/zramswap

Recommended starting values for typical hosting:

# /etc/default/zramswap

# Choose a fast, widely-supported algorithm.
# lz4 is a good default for VPS hosting.
ALGO=lz4

# Size guidance:
# - 1GB RAM VPS: 512M–1G zram
# - 2GB RAM VPS: 1G zram
# - 4GB RAM VPS: 2G zram
# - 8GB+ RAM VPS: 2G–4G zram

# zram-tools accepts absolute sizes (e.g., 1024M) on most builds.
# If your distro expects a percentage, use PERCENT=... instead.
SIZE=1024M

Rule of thumb: aim for ~25–50% of RAM for web servers. If you oversize zram, you can crowd out the very processes you’re trying to protect.

Start conservative. Then adjust based on what you measure.

Enable/restart the service

sudo systemctl enable --now zramswap
sudo systemctl restart zramswap

Verify zram is active

swapon --show
lsblk | grep -E "zram|NAME"
cat /proc/swaps

You should see something like /dev/zram0 with a size close to what you configured.

AlmaLinux/Rocky Linux 9 notes

RHEL-family systems often use zram-generator rather than zram-tools.

sudo dnf install -y zram-generator

Create:

sudo nano /etc/systemd/zram-generator.conf
[zram0]
zram-size = 1024M
compression-algorithm = lz4

Then:

sudo systemctl daemon-reload
sudo systemctl restart systemd-zram-setup@zram0.service
swapon --show

Step 2 — Tune swappiness and cache pressure for hosting workloads

Once zram is in place, lower swappiness so the kernel is less eager to swap. The goal is to keep PHP-FPM workers and MySQL buffers resident during normal load.

You still want an escape valve for short spikes. That’s what zram provides.

Set runtime values (safe to test)

sudo sysctl -w vm.swappiness=10
sudo sysctl -w vm.vfs_cache_pressure=100

Guidance:

  • vm.swappiness=10 is a solid baseline for WordPress/LAMP/LEMP VPS hosts.
  • vfs_cache_pressure=100 keeps default reclaim behavior. Lower values can retain inode/dentry cache longer, which may help file-heavy WordPress installs. Don’t guess, though—change one thing and measure.

Make it persistent

Create a dedicated sysctl drop-in:

sudo nano /etc/sysctl.d/99-hosting-swap-tuning.conf
vm.swappiness = 10
vm.vfs_cache_pressure = 100

Apply:

sudo sysctl --system

Quick verification

sysctl vm.swappiness vm.vfs_cache_pressure

Step 3 — Decide whether you still need disk swap (often: no)

On modern VPS hosting with NVMe, a little disk swap can be tolerable. Under sustained pressure, it still tends to hurt latency and amplify load problems.

zram handles bursts well. Disk swap is mainly for “everything went sideways” moments.

Recommended policy

  • 1–2GB RAM VPS: consider a small disk swap (512MB–1GB) only if you still see OOM events even with zram.
  • 2–8GB RAM VPS: start with zram only. Add disk swap only if you have evidence you need it.
  • Database-heavy VPS: buy RAM before you buy swap. Swapping database pages destroys latency.

If you choose disk swap: create a small swapfile

Example for a 1GB swapfile:

sudo fallocate -l 1G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile

Persist it:

echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab

Verify:

swapon --show

Prefer zram over disk swap (priority)

Linux swap priority controls what gets used first. In most setups, you want zram to have higher priority than disk swap.

Check priorities:

swapon --show --output=NAME,TYPE,SIZE,USED,PRIO

If your disk swap has equal or higher priority than zram, fix it. With swapfiles in /etc/fstab, you can set priority like:

/swapfile none swap sw,pri=10 0 0

zram often shows a higher priority automatically. Don’t assume it. Verify on your distro.

Step 4 — Protect MySQL/MariaDB and PHP-FPM from memory death spirals

Swap tuning won’t compensate for services that grow without bounds. Two failures often get blamed on “swap,” but they start elsewhere:

  • PHP-FPM spawns too many workers under load and drains RAM.
  • MySQL buffer sizes are too large for the VPS.

PHP-FPM: cap concurrency to match RAM

On Ubuntu, pool configs often live at:

  • /etc/php/8.3/fpm/pool.d/www.conf (Ubuntu 24.04 commonly ships PHP 8.3)
  • /etc/php/8.2/fpm/pool.d/www.conf on older stacks

Check current settings:

sudo grep -E "^pm\.|^user\s*=|^group\s*=" /etc/php/8.3/fpm/pool.d/www.conf

A safe baseline for a 2GB RAM VPS running WordPress might be:

pm = dynamic
pm.max_children = 12
pm.start_servers = 4
pm.min_spare_servers = 4
pm.max_spare_servers = 8

Reload:

sudo systemctl reload php8.3-fpm

If you’re unsure what fits your box, use data. Watch RSS per PHP-FPM child during a load test.

Then set pm.max_children so the total stays inside your RAM budget.

MySQL/MariaDB: stop allocating “internet defaults”

MySQL configs are usually in /etc/mysql/mysql.conf.d/mysqld.cnf (Ubuntu/Debian) or /etc/my.cnf (RHEL family).

On small VPS plans, the most common mistake is an InnoDB buffer pool sized like the server has nothing else to do.

Check effective values:

sudo mysql -e "SHOW VARIABLES LIKE 'innodb_buffer_pool_size';"
sudo mysql -e "SHOW VARIABLES LIKE 'max_connections';"

On a 2GB RAM VPS hosting a couple of sites, an InnoDB buffer pool of 512MB–768MB is often more realistic than 1.5GB. Keep max_connections realistic as well.

If your database is already sluggish, the slow query log will usually pay off faster than more memory tweaking. Follow: Linux VPS MySQL Slow Query Log Tutorial (2026): Enable, Analyze, and Fix Database Bottlenecks.

Step 5 — Validate that zram is doing its job (without guessing)

Don’t wait for the next production spike. Confirm the behavior in a controlled way.

Watch memory and swap live

free -h
vmstat 1

In vmstat, watch:

  • si/so (swap in/out): brief bursts are normal; sustained high values usually mean you’re under-provisioned.
  • wa (I/O wait): if this climbs during swap, disk swap is likely hurting you.

Inspect zram compression ratio

Check how well zram compresses on your workload:

sudo apt install -y util-linux
zramctl

If you see a healthy compression ratio (often around 2:1 for typical web workloads), zram is giving you real breathing room during spikes.

Optional: synthetic pressure test (use carefully)

During a maintenance window (not on a production peak), you can use stress-ng to force memory pressure. This lets you confirm the server stays usable:

sudo apt install -y stress-ng
stress-ng --vm 2 --vm-bytes 70% --timeout 60s --metrics-brief

While it runs, keep another SSH session open and monitor:

vmstat 1
swapon --show

If the box becomes unresponsive, the test is too aggressive for your current limits. Disk swap may also be thrashing.

Stop the run. Then scale back disk swap reliance (or upgrade RAM).

Common pitfalls (the stuff that causes “swap tuning didn’t work”)

  • Oversizing zram: If you set zram to 100% of RAM, you can starve applications. Start at 25–50%.
  • Using disk swap as a crutch: If you regularly see heavy disk swap, you need more RAM or lower concurrency.
  • Ignoring log growth: Low memory incidents often coincide with disk-full outages from logs. Set up rotation. See Linux VPS log rotation setup: prevent disk full outages with logrotate + systemd (2026 tutorial).
  • Misreading “cached” memory: Linux uses RAM for page cache. That’s normal. Look at “available” memory, not just “free”.

Rollback plan (so you can change safely)

If you need to revert quickly:

Disable zram-tools (Ubuntu/Debian)

sudo systemctl stop zramswap
sudo systemctl disable zramswap
swapon --show

Remove disk swapfile (if created)

sudo swapoff /swapfile
sudo sed -i '\|^/swapfile\s|d' /etc/fstab
sudo rm -f /swapfile

Reset sysctl values

sudo rm -f /etc/sysctl.d/99-hosting-swap-tuning.conf
sudo sysctl --system

Operational checklist: keep it stable after the tuning

Swap tuning helps, but stability still comes from the basics. This short list prevents most “mystery” outages on hosting servers:

If you’re tuning swap because you’re consistently tight on RAM, you’ve probably outgrown the plan you’re on. A right-sized HostMyCode VPS gives you predictable headroom, and managed VPS hosting covers the routine hardening, monitoring, and update work.

FAQ

Should I use zram on a VPS with NVMe storage?

Yes for most hosting stacks. zram absorbs bursty memory pressure without adding disk I/O latency. NVMe helps, but disk swap still increases tail latency under load.

What swappiness value is best for WordPress hosting?

Start at 10. If you still see OOM kills, add or adjust zram before raising swappiness. If swap activity stays high, reduce PHP-FPM concurrency or add RAM.

Can swap tuning fix 502 Bad Gateway errors?

Sometimes. If PHP-FPM workers are being killed or starved, reducing memory pressure can help. But 502s also come from upstream timeouts, CPU saturation, and database stalls—use a checklist like this VPS troubleshooting checklist to narrow it down.

Is it safe to run without disk swap entirely?

For many web VPS setups, yes—especially with zram enabled. If you host large databases or memory-heavy jobs, keep a small disk swap as a last-resort safety net, then watch I/O wait.

Summary

Linux VPS swap tuning prevents sudden OOM events and keeps the server responsive during bursty load. In 2026, zram plus conservative swappiness is usually the best trade-off for hosting. You get a buffer without punishing storage.

If you’re leaning on swap day after day even after tuning, don’t fight physics. Move to a larger HostMyCode VPS or a dedicated server for high-traffic sites that need consistent RAM headroom.