Quick answer: On Ubuntu 22.04/24.04 with ext4 or XFS, create an 8 GB swap file in 5 commands: dd to allocate, chmod 600, mkswap, swapon, then add one line to /etc/fstab to survive reboots. On ZFS (OpenZFS 2.1+), create a dedicated zvol with primarycache=metadata and logbias=throughput — without these two parameters, heavy swap activity evicts useful data from the ZFS ARC and slows everything else on the system. Set vm.swappiness=10 for servers (default Ubuntu value of 60 is too aggressive). Tested on Ubuntu 22.04 and 24.04, OpenZFS 2.1+, March 2026.

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.


File-based swap vs ZFS swap — which one do I need?

Use a standard swap file on ext4/XFS unless your system is already running ZFS — if it is not ZFS, a swap file is faster to set up, easier to resize, and has nothing that can go wrong at the ZFS layer.

Linux swap method comparison — Ubuntu 22.04/24.04, verified March 2026
FactorFile-based swap (ext4/XFS)ZFS zvol swap (OpenZFS 2.1+)
Setup time~3 minutes, 5 commands~10 minutes, more parameters
Resizeswapoff → new dd → swaponzfs set volsize= (online)
Deadlock riskNoneYes if swap sits on ZFS dataset (not zvol)
ARC eviction riskNoneYes without primarycache=metadata
PerformanceLimited by disk speedSame — limited by disk speed
Recommended whenAny non-ZFS systemSystem already runs ZFS

How does Linux swap work, and what are the performance limits?

When RAM fills up, the kernel moves pages that have not been accessed recently from RAM to swap space on disk. The performance ceiling is always disk speed — an NVMe drive doing ~3,000 MB/s sequential reads versus ~50,000 MB/s for DDR4 means swap is roughly 16× slower than RAM at best. The goal is not to use swap as permanent overflow RAM; it is to prevent the OOM killer from terminating processes during memory spikes.

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 space do I need?

The old rule of “swap = 2× RAM” dates from when systems had 256 MB RAM and is not relevant on modern hardware. Size swap based on what you are protecting against:

  • Under 8 GB RAM — configure 4–8 GB swap. The system needs room to move pages without thrashing.
  • 8–64 GB RAM — configure 8–16 GB swap. Enough to absorb hibernation and memory spikes without touching disk constantly.
  • Over 64 GB RAM — 8–16 GB swap is still appropriate. You are configuring a safety valve, not overflow storage.

One exception: if you use hibernation (suspend-to-disk), swap must be at least as large as your installed RAM — the kernel writes the entire RAM contents to swap before powering off.


How do I set up a swap file on Ubuntu with ext4 or XFS?

Run the five commands below in sequence — the whole process takes about 3 minutes on an NVMe system and produces no surprises if you follow the order exactly.

How do I check if swap is already configured?

swapon --show

No output means no swap is configured — that is normal and expected on a fresh install. If swap is already active you will see:

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

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

sudo swapoff -a

How do I create an 8 GB swap file?

Adjust count=8 to the number of gigabytes you need:

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

Expected output — progress during creation, then a summary line:

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

On NVMe expect 500–2,000 MB/s. On a spinning disk expect 50–150 MB/s. If the command hangs with no progress output, your destination disk is full — check with df -h / before retrying.

How do I set permissions, format, and activate the swap file?

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

Error you will hit if you skip chmod 600:

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

It will still activate with that warning, but fix the permissions anyway with sudo chmod 600 /swapfile — a world-readable swap file exposes process memory to other users on a multi-user system.

Activate swap and verify:

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

How do I make the swap file persist after reboot?

Without this step your swap disappears every time the system restarts:

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

Verify the line was appended correctly:

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

Critical warning: use tee -a (append), never redirect with > into /etc/fstab — that overwrites the entire file, removes your disk mounts, and prevents the system from booting. If you are editing fstab by hand, take a snapshot first. The WSL2 backup guide covers how to export a full snapshot you can restore from if something goes wrong.


How do I configure swap on Ubuntu running ZFS (OpenZFS 2.1+)?

Create a dedicated ZFS volume (zvol) with specific performance parameters — the default zfs create without these parameters will configure a swap device that works, but will degrade the rest of the system by consuming ARC cache with swap data during heavy swap activity.

Full ZFS parameter reference is in the OpenZFS documentation.

How do I find my 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  -

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

How do I create a ZFS swap volume with the correct parameters?

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 omitting any of them causes a specific problem:

  • -b $(getconf PAGESIZE) — sets block size to match the system memory page size (4,096 bytes on x86-64). A mismatched block size causes write amplification on every swap operation — every 4 KB page write becomes a larger ZFS block write.
  • compression=zle — zero-length encoding compresses runs of zeros efficiently. Swap data contains many zero pages. Using lz4 or zstd here adds CPU overhead for negligible additional compression gain on swap content.
  • logbias=throughput — writes swap data directly to the main pool, bypassing the ZIL (ZFS Intent Log). Swap writes do not need ZIL durability guarantees, and bypassing it improves write throughput.
  • sync=always — ensures swap writes complete before returning to the caller. Without this, a power failure during heavy swap activity can corrupt swap content.
  • primarycache=metadata — the most important parameter. Without it, swap data fills the ARC (ZFS RAM cache), evicting file data and metadata that actually benefits from caching. With it, only zvol metadata is cached in ARC, not the swap pages themselves.
  • secondarycache=none — disables L2ARC for the swap zvol. Swap data in L2ARC wastes SSD write endurance with no practical benefit, since swap data access patterns do not benefit from L2ARC caching.

How do I format and activate the ZFS swap volume?

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 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. Check with ls /dev/zvol/rpool/. If the zvol is missing, the zfs create command failed silently — run it again as a single line (remove the backslash continuations) to see the actual error message.

Why does ZFS swap fail to activate after reboot even with a correct fstab entry?

The /dev/zvol/rpool/swap device does not exist when systemd processes /etc/fstab during early boot, because ZFS imports its pools after the early boot stage. The swap entry is processed before the zvol device appears, so it silently fails — swapon --show after boot shows nothing even though fstab looks correct.

Add the fstab entry first:

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

Then enable the ZFS services that need to complete before swap activates:

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

Reboot and verify with swapon --show. If it still shows nothing, check journalctl -b | grep swap for the exact failure — the most common remaining cause is the pool name in the fstab entry not matching exactly what zpool list shows.


What swappiness value should I set for my workload?

Set vm.swappiness=10 for most server workloads — the Ubuntu default of 60 causes the kernel to start swapping while there is still plenty of free RAM, generating unnecessary disk I/O with no memory pressure benefit.

Check your current value first:

cat /proc/sys/vm/swappiness
Recommended swappiness values by workload — Ubuntu 22.04/24.04
WorkloadRecommended valueReason
Desktop / interactive system10Keeps system responsive; only swaps when RAM is nearly full
Web server / application server10–20Application servers benefit from keeping their working set in RAM
PostgreSQL / MySQL database server1–10Databases manage their own caching; kernel should almost never swap
System running ZFS10 maximumHigh swappiness + ZFS ARC causes kernel and ZFS to compete for RAM

Set temporarily to test before making it permanent (takes effect immediately, lost on reboot):

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 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.


How do I monitor swap usage and find which processes are using it?

Check free -h for a snapshot and vmstat 2 for live activity — the si and so columns in vmstat are the most direct indicator of whether the system is actively swapping right now.

How do I check current swap usage?

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. If you consistently see swap usage above 1–2 GB on a server that should have enough RAM, something is leaking memory or the buffer pool for your database is configured larger than available RAM.

How do I 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

The si (swap in) and so (swap out) columns should be 0 or near 0 on a healthy system. Sustained non-zero so means the kernel is actively moving pages to swap right now. Sustained non-zero si means it is pulling pages back — your working set does not fit in RAM and you will see high wa (I/O wait) CPU percentage alongside it.

How do I 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 using swap:

mysqld 524288 kB
php-fpm 131072 kB
python3 65536 kB

If a process you expect to be active — like mysqld — shows high swap usage, that process has been partially evicted from RAM. The most common causes are a buffer pool (innodb_buffer_pool_size) configured larger than available RAM, or a memory leak in a long-running process. Either the buffer pool setting needs reducing or the process needs a restart to reclaim the leaked memory.


Should I use a standard swap file or a ZFS swap volume?

Use a standard swap file on ext4/XFS unless your system is already running ZFS — there is no performance advantage to introducing ZFS complexity just for swap, and the boot-ordering issue with zvols is an additional failure mode you do not need on a non-ZFS system.

Use a ZFS swap volume if you are already on ZFS specifically because mixing a swap file on a ZFS dataset (not a zvol) with a ZFS pool introduces a deadlock risk. If ZFS needs memory to complete a write and swap is simultaneously waiting on ZFS to complete a write, the system can hang indefinitely. A dedicated zvol with the parameters above avoids this failure mode.

The ZFS swap volume with the parameters above does not run faster than a swap file on the same underlying hardware — swap throughput is always capped by the physical disk speed regardless of filesystem. The parameters matter not for speed but for preventing ZFS swap from degrading the rest of the system. On NVMe the difference between swap being used and not used is nearly imperceptible. On a spinning disk at 100–150 MB/s, any sustained swap activity will cause noticeable stalls regardless of filesystem.

Share this post

🏷️ Tags

WSL
L

Written by Logic Encoder

Professional crypto analyst and trading expert

← Previous Post
WSL File Transfer: Move Files Between Windows and WSL2 (Ubuntu 2026)
Next Post →
0xDNX DHIP v2 Richlist — Wrapped Dynex Holder Distribution Monitor