When a Linux server runs out of RAM with no swap configured, the kernel OOM killer starts terminating processes — often the wrong ones. This guide covers two ways to configure linux swap management on Ubuntu: a standard file-based swap on ext4/XFS, and a ZFS volume swap for systems already running ZFS. Both are covered with exact commands, expected output, and the specific errors you will actually hit. Tested on Ubuntu 22.04 and 24.04 with OpenZFS 2.1+. Last updated March 2026.

If you are on a standard ext4 or XFS system, go to the file-based swap section. If you are running ZFS (Proxmox, TrueNAS, or a manual ZFS install on Ubuntu), go to the ZFS section. The swappiness and monitoring sections apply to both. If you are also running WSL2 on Windows alongside a Linux server, see the complete WSL2 installation guide — WSL2 manages its own memory limits separately from the host and has different swap behaviour.


How Linux Swap Works

When RAM fills up, the kernel moves pages that haven’t been accessed recently from RAM to swap space on disk. If those pages are needed again, they swap back into RAM. Swap is slower than RAM — an NVMe drive does roughly 3,000 MB/s sequential reads versus ~50,000 MB/s for DDR4. The goal is not to use swap as extra RAM permanently. It is to give the system somewhere to put cold pages so it doesn’t kill your processes when something spikes memory usage.

Two things determine whether swap actually helps or makes things worse: how much swap you configure, and the swappiness value that controls how aggressively the kernel uses it. Both are covered below.

How much swap to configure

The old rule of “swap = 2× RAM” dates from when systems had 256MB RAM. On modern systems:

  • Under 8GB RAM — 4–8GB swap. The system needs room to move pages without thrashing.
  • 8–64GB RAM — 8–16GB swap. Enough for hibernation and memory spikes.
  • Over 64GB RAM — 8–16GB swap is still reasonable. You are not using it as overflow RAM, you are using it as a safety valve.

The one exception: if you use hibernation (suspend-to-disk), swap must be at least as large as your RAM.


Linux Swap File Setup — Standard ext4/XFS Systems

This is the right approach for any Ubuntu, Debian, or RHEL system not running ZFS. A swap file on ext4 or XFS is faster to set up, easier to resize, and has no dependencies beyond a standard Linux install.

Step 1 — Check what swap you currently have

swapon --show

If nothing is configured you will see no output at all — a blank line. That is normal. If swap is already active you will see output like:

NAME      TYPE SIZE USED PRIO
/swapfile file  2G   0B   -2

If you are resizing an existing swap file, disable it first:

sudo swapoff -a

Step 2 — Create the swap file

This creates an 8GB swap file. Adjust count=8 to the size you need in gigabytes:

sudo dd if=/dev/zero of=/swapfile bs=1G count=8 status=progress

Expected output — you will see progress during creation, then:

8589934592 bytes (8.6 GB, 8.0 GiB) copied, 12.4 s, 693 MB/s

The speed depends on your disk. On an NVMe drive expect 500–2000 MB/s. On a spinning disk expect 50–150 MB/s.

Step 3 — Set permissions and format

sudo chmod 600 /swapfile
sudo mkswap /swapfile

Expected output from mkswap:

Setting up swapspace version 1, size = 8 GiB (8589930496 bytes)
no label, UUID=a1b2c3d4-e5f6-7890-abcd-ef1234567890

Common error here: if you skip chmod 600 and run mkswap first, then try to activate it, you will hit:

swapon: /swapfile: insecure permissions 0644, 0600 suggested.

It will still activate with that warning, but fix the permissions anyway:

sudo chmod 600 /swapfile

Step 4 — Activate swap

sudo swapon /swapfile

Verify it is active:

swapon --show
NAME      TYPE  SIZE USED PRIO
/swapfile file    8G   0B   -2

Step 5 — Make swap persist across reboots

Without this step your swap disappears after every reboot:

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

Verify the line was added:

grep swap /etc/fstab
/swapfile none swap sw 0 0

Common mistake: editing /etc/fstab directly and accidentally deleting the existing entries. Using tee -a appends rather than overwrites. Always check the file looks correct after editing — a broken fstab will prevent the system from booting. Before making system-level changes like this it is worth having a backup — the WSL2 backup guide covers how to export a full snapshot you can restore from if something goes wrong.


ZFS Swap Volume Setup — Ubuntu with OpenZFS

If your system runs ZFS, configure swap as a ZFS volume rather than a file. ZFS volumes (zvols) are block devices managed by ZFS, and with the right parameters they perform well for swap workloads. The setup is more involved than a swap file, and there are two specific gotchas that will catch you if you don’t know about them. Full ZFS parameter reference is in the OpenZFS documentation.

Step 1 — Find your ZFS pool name

zpool list
NAME    SIZE  ALLOC   FREE  CKPOINT  EXPANDSZ   FRAG    CAP  DEDUP    HEALTH  ALTROOT
rpool  59.5G  12.4G  47.1G        -         -     4%    20%  1.00x    ONLINE  -

In this example the pool name is rpool. On Proxmox this is typically rpool. On a manual Ubuntu ZFS install it is often rpool or named after the disk. Replace rpool in the commands below with your actual pool name.

Step 2 — Create the ZFS swap volume

sudo zfs create \
  -V 8G \
  -b $(getconf PAGESIZE) \
  -o compression=zle \
  -o logbias=throughput \
  -o sync=always \
  -o primarycache=metadata \
  -o secondarycache=none \
  rpool/swap

What each parameter does and why it matters for swap specifically:

  • -b $(getconf PAGESIZE) — sets the block size to match the system memory page size (4096 bytes on x86-64). Mismatched block size causes write amplification on every swap operation.
  • compression=zle — zero-length encoding. Compresses runs of zeros efficiently. Swap data compresses well with zle; using lz4 or zstd here gives minimal benefit and adds CPU overhead.
  • logbias=throughput — tells ZFS to write swap data directly to the main pool rather than routing through the ZIL (ZFS Intent Log). Swap writes do not need the ZIL’s durability guarantees and bypassing it improves throughput.
  • sync=always — ensures swap writes complete before returning. Without this, a power failure could corrupt swap content.
  • primarycache=metadata — prevents swap data from evicting useful file data from the ARC (ZFS RAM cache). Without this, heavy swap activity can trash your ARC and slow down everything else on the system.
  • secondarycache=none — disables L2ARC for swap. Swap data in L2ARC wastes SSD write endurance with no real benefit.

Step 3 — Format and activate

sudo mkswap -f /dev/zvol/rpool/swap
sudo swapon /dev/zvol/rpool/swap

Expected output from mkswap:

Setting up swapspace version 1, size = 8 GiB (8589930496 bytes)
no label, UUID=a1b2c3d4-e5f6-7890-abcd-ef1234567890

Error you will hit if the zvol does not exist yet:

mkswap: error: unable to find a valid signature on /dev/zvol/rpool/swap

This means the device path does not exist. Run ls /dev/zvol/rpool/ to check the zvol was actually created. If it is not there, the zfs create command failed silently — run it again without the backslash line continuation to see any error output.

Step 4 — Make ZFS swap persist across reboots

echo "/dev/zvol/rpool/swap none swap defaults 0 0" | sudo tee -a /etc/fstab

The gotcha with ZFS swap and fstab on Ubuntu: the zvol device /dev/zvol/rpool/swap may not exist yet when systemd processes fstab at boot, because ZFS imports the pool after the early boot stage. This causes swap to silently fail to activate at boot even though fstab looks correct.

Fix by adding a systemd override that delays swap activation until after ZFS pools are imported:

sudo systemctl enable zfs-mount.service
sudo systemctl enable zfs-import-cache.service

Then verify swap is actually active after a reboot with swapon --show. If it shows nothing, your ZFS pool import is happening too late — check journalctl -b | grep swap for the exact error.


Swappiness — The Setting That Actually Matters

Swappiness controls how aggressively the kernel moves pages to swap. The default on Ubuntu is 60. For most server workloads that is too high — the kernel will start swapping while there is still plenty of free RAM, causing unnecessary disk I/O.

Check your current value:

cat /proc/sys/vm/swappiness

Recommended values by workload:

  • Desktop or interactive system — set to 10. Keeps the system responsive, only swaps when RAM is nearly full.
  • Web server or application server — set to 10–20. Application servers benefit from keeping their working set in RAM.
  • Database server (PostgreSQL, MySQL) — set to 1–10. Databases manage their own caching. The kernel should almost never swap on a database server — if it is, you need more RAM or a smaller database buffer pool.
  • System with ZFS — set to 10 maximum. ZFS uses its own ARC for caching. A high swappiness value combined with ZFS ARC means the kernel and ZFS compete for RAM in ways that are hard to diagnose.

Set temporarily (lost on reboot) to test before making it permanent:

sudo sysctl vm.swappiness=10

Make it permanent:

echo 'vm.swappiness=10' | sudo tee -a /etc/sysctl.conf
sudo sysctl -p

Full list of VM kernel parameters and what each one does is in the Linux kernel vm sysctl documentation. If you need to move config files between a Windows host and your Linux environment, the WSL file transfer guide covers the fastest methods.


Monitoring Swap Usage

The two things worth monitoring regularly: how much swap is being used, and which processes are using it.

Current usage at a glance

free -h
               total        used        free      shared  buff/cache   available
Mem:            15Gi       4.2Gi       8.1Gi       312Mi       2.8Gi        10Gi
Swap:          8.0Gi          0B       8.0Gi

Swap used at 0B is normal and expected on a healthy system. You want swap available, not in use. If you consistently see swap usage above 1–2GB on a server that should have enough RAM, something is leaking memory or you need to increase RAM.

Watch swap activity in real time

vmstat 2
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 1  0      0 8234512  12428 2893456    0    0     1    12   45  123  2  1 97  0  0

Watch the si (swap in) and so (swap out) columns. Both should be 0 or near 0 on a healthy system. Sustained non-zero values in so means the kernel is actively moving pages to swap right now. Sustained non-zero si means it is pulling pages back from swap — your working set does not fit in RAM.

Find which processes are using swap

for file in /proc/*/status; do
  awk '/VmSwap|Name/{printf $2 " " $3}END{print ""}' $file
done | sort -k 2 -n -r | head -10

Example output when a process is actually using swap:

mysqld 524288 kB
php-fpm 131072 kB
python3 65536 kB

If a process you expect to be active (like mysqld) is showing high swap usage, that process has been partially evicted from RAM. Either your buffer pool settings are too large for available RAM or something else is competing for memory.


Standard Swap vs ZFS Swap — Which to Use

Use a standard swap file unless your system is already running ZFS. There is no reason to introduce ZFS complexity just for swap. On a non-ZFS system a standard swap file on ext4 or XFS is faster to set up, easier to resize, and has less to go wrong.

Use a ZFS swap volume if you are already on ZFS. Mixing a swap file on a ZFS dataset with a ZFS pool introduces deadlock risk — if ZFS needs memory to complete a write and swap is also waiting on ZFS, the system can hang. A dedicated zvol with the parameters above avoids this.

The ZFS swap volume is not meaningfully faster than a swap file on the same underlying hardware. The performance parameters in the setup above are about preventing ZFS swap from making the rest of the system slower (by consuming ARC), not about making swap itself faster. Swap is always limited by disk speed regardless of filesystem.

For either setup, the most impactful thing you can do for swap performance in 2026 is ensure swap is on an SSD or NVMe. A swap file on a spinning disk with 100–150 MB/s throughput will cause noticeable system stalls the moment it gets used. On NVMe the same swap activity is nearly imperceptible.

🔗 Share This Post

🏷️ Tags

WSL
L

Written by Logic Encoder

Professional crypto analyst and trading expert

← Previous Post
The Ultimate Guide to File Transfer Between Windows and WSL in 2025
Next Post →
Wrapped Dynex Richlist (0xDNX) DHIP v.2

Leave a Reply

Your email address will not be published. Required fields are marked *