Skip to content

Swap

Swap is disk space the kernel uses for memory pages that are not in active use, on a partition or in a file. It buys time under memory pressure, but a host that swaps heavily is already short of RAM.

Track: Core · Interview weight: Med


Must-Know Facts

Fact Value Verify with
Show swap swapon --show, free -h, /proc/swaps swapon --show
Prepare mkswap [-L label] <dev or file> blkid shows TYPE="swap"
Enable, disable swapon <dev>, swapoff <dev>; -a for every fstab entry swapon --show
fstab line UUID=... none swap defaults 0 0 (pri=N sets the priority) systemctl list-units -t swap
Swap file Created with dd or fallocate (no holes), mode 0600 ls -l /swapfile
Priority Higher is used first; equal priorities are used in round robin swapon --show
vm.swappiness 0 to 200, kernel default 60; lower values keep more anonymous memory in RAM sysctl vm.swappiness
Per process VmSwap in /proc/<pid>/status grep VmSwap /proc/*/status
Per cgroup MemorySwapMax=, memory.swap.max; MemorySwapCurrent systemctl show -p MemorySwapCurrent <unit>
Sizing Up to the RAM size on small hosts, a few GiB on large ones; RAM plus more for hibernation free -h
Kubernetes The kubelet refuses to start with swap on unless failSwapOn: false is set swapon --show
zram Compressed swap in RAM; the default on Fedora zramctl

Swap on a Partition

Partition 2 of loop0 has MBR type 82 from Partitioning:

swapon --show; free -h | grep Swap
sudo mkswap -L swap1 /dev/loop0p2
sudo swapon /dev/loop0p2
swapon --show

Output:

Swap:             0B          0B          0B
Setting up swapspace version 1, size = 1024 MiB (1073737728 bytes)
LABEL=swap1, UUID=f449f488-566a-4ba6-b829-b19283d0b25c
NAME         TYPE       SIZE USED PRIO
/dev/loop0p2 partition 1024M   0B   -2

The playground had no swap, which is common for cloud images and container hosts. The partition type code is only a hint; mkswap writes the signature that swapon looks for.


Swap in a File

A swap file must have every block allocated, so a sparse file from truncate fails:

sudo truncate -s 512M /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile >/dev/null
sudo swapon /swapfile; echo "rc=$?"
sudo rm /swapfile
sudo dd if=/dev/zero of=/swapfile bs=1M count=512 status=none
sudo mkswap /swapfile
sudo swapon /swapfile
sudo chmod 600 /swapfile
ls -l /swapfile
swapon --show
free -h

Output:

mkswap: /swapfile contains holes or other unsupported extents.
        This swap file can be rejected by kernel on swap activation!
        Use --verbose for more details.

swapon: /swapfile: skipping - it appears to have holes.
rc=255
mkswap: /swapfile: insecure permissions 0644, fix with: chmod 0600 /swapfile
Setting up swapspace version 1, size = 512 MiB (536866816 bytes)
no label, UUID=5be39615-dd49-4411-9468-43c77d1cc113
swapon: /swapfile: insecure permissions 0644, 0600 suggested.
-rw------- 1 root root 536870912 Sep 17 07:39 /swapfile
NAME         TYPE       SIZE USED PRIO
/dev/loop0p2 partition 1024M   0B   -2
/swapfile    file       512M   0B   -3
               total        used        free      shared  buff/cache   available
Mem:           7.8Gi       483Mi       6.7Gi       2.1Mi       878Mi       7.4Gi
Swap:          1.5Gi          0B       1.5Gi

The second file was created with the default mode 0644 and chmod ran late on purpose: both tools only warn, and the file was already active while any user could read it. fallocate -l 512M /swapfile is faster than dd on ext4 and XFS; on Btrfs, btrfs filesystem mkswapfile creates a usable file.

A world-readable swap file leaks memory contents

Swapped pages can hold passwords, keys and session tokens. Set mode 0600 before mkswap, not after swapon.


Making It Permanent

sudo swapoff -a; swapon --show
sudo tee -a /etc/fstab <<'EOF'
LABEL=swap1   none  swap  defaults,pri=10  0 0
/swapfile     none  swap  defaults         0 0
EOF
sudo systemctl daemon-reload
sudo swapon -a
swapon --show
systemctl list-units --type=swap --no-legend

Output:

LABEL=swap1   none  swap  defaults,pri=10  0 0
/swapfile     none  swap  defaults         0 0
NAME         TYPE       SIZE USED PRIO
/dev/loop0p2 partition 1024M   0B   10
/swapfile    file       512M   0B   -2
  dev-disk-by\x2dlabel-swap1.swap loaded active active /dev/disk/by-label/swap1
  swapfile.swap                   loaded active active /swapfile

mount -a ignores swap entries; swapon -a activates them, and at boot systemd creates a .swap unit for each line. With pri=10, the partition fills before the file.


Swappiness and Who Is Swapping

vm.swappiness sets how readily the kernel reclaims anonymous memory (swap) compared with page cache. Rocky shows 30 because of the drop-ins from sysctl; Ubuntu 24.04 runs with the kernel default:

sysctl vm.swappiness
grep -H swappiness /etc/sysctl.d/*.conf

Output:

vm.swappiness = 30
/etc/sysctl.d/90-app.conf:vm.swappiness = 10
/etc/sysctl.d/95-db.conf:vm.swappiness = 30
sysctl vm.swappiness

Output:

vm.swappiness = 60

A service limited to 100 MiB of RAM that allocates 300 MiB is pushed into swap instead of being killed. With swap forbidden for the cgroup, the same allocation ends in the OOM killer:

sudo systemd-run --unit=hog -p MemoryMax=100M python3 -c 'import time; b = bytearray(300 * 1024 * 1024); time.sleep(120)'
sleep 5
grep -E 'VmRSS|VmSwap' /proc/$(systemctl show -p MainPID --value hog)/status
systemctl show -p MemoryCurrent,MemorySwapCurrent hog
free -h | grep Swap
sudo systemd-run --wait --unit=hog2 -p MemoryMax=100M -p MemorySwapMax=0 python3 -c 'b = bytearray(300 * 1024 * 1024)'; echo "rc=$?"

Output:

Running as unit: hog.service; invocation ID: 79e36b96b63045089ebef08c91a6ada6
VmRSS:    102716 kB
VmSwap:   212824 kB
MemoryCurrent=104677376
MemorySwapCurrent=218083328
Swap:          1.5Gi       208Mi       1.3Gi
Running as unit: hog2.service; invocation ID: 11286e5f1614403d8455f4c144eeb30e
Finished with result: oom-kill
Main processes terminated with: code=killed, status=9/KILL
Service runtime: 169ms
CPU time consumed: 150ms
Memory peak: 100M
rc=1

VmSwap in each process's status file shows who holds swapped memory. Sustained non-zero si and so columns in vmstat 1 mean the system is swapping pages in and out now, which hurts far more than a static amount of used swap.

swapoff needs enough free RAM for everything in swap

swapoff reads every swapped page back into memory. On a busy host it can take minutes or trigger the OOM killer; check free -h first.


Common Errors

swapon: /swapfile: skipping - it appears to have holes.

Cause: the file is sparse (created with truncate or copied with cp --sparse), so the kernel cannot map its blocks directly.

Fix: recreate it with dd if=/dev/zero or fallocate, then chmod 600, mkswap and swapon.

swapon: /dev/loop0p1: read swap header failed

Cause: the device has no swap signature: mkswap was never run, or the device holds a filesystem (loop0p1 is ext4).

Fix: confirm the device with blkid, then sudo mkswap it.


Interview Checkpoints

L1: What is swap, and is using swap bad?

Say first: swap holds memory pages the kernel moved out of RAM; some used swap is normal, while constant swapping in and out means the host needs more memory.

Proof: free -h; vmstat 1 shows si and so.

Follow-up: What does vm.swappiness change?

L1: Swap partition or swap file: which is better?

Say first: performance is the same on current kernels; a file is easier to resize, while a partition needs no filesystem and suits hibernation setups.

Proof: swapon --show lists partition or file.

Follow-up: Why must a swap file have no holes?

L2: Add 2 GiB of swap to a running server without a new disk.

Say first: create a fully allocated file with mode 0600, format it, enable it and add it to fstab.

Proof: sudo fallocate -l 2G /swapfile && sudo chmod 600 /swapfile && sudo mkswap /swapfile && sudo swapon /swapfile; echo '/swapfile none swap defaults 0 0' | sudo tee -a /etc/fstab.

Follow-up: How do you check it activates at boot? (sudo swapoff /swapfile; sudo swapon -a; swapon --show.)

L2: Find which processes are using swap.

Say first: read VmSwap from each process's status file.

Proof: grep VmSwap /proc/[0-9]*/status | sort -k2 -n | tail; smem -s swap if installed.

Follow-up: How do you see swap per systemd service? (systemctl show -p MemorySwapCurrent.)

L3: A server is slow, load is high and free shows little free swap. What do you check?

Say first: whether it is actively swapping, which processes grew, and whether the OOM killer has run.

Proof: vmstat 1 (si, so, wa); ps aux --sort=-rss | head; journalctl -k | grep -i 'out of memory'.

Follow-up: Why can adding more swap make this worse?

L2: Why does kubeadm fail with a swap-related preflight error, and what are the options?

Say first: the kubelet requires swap off by default, so disable it or configure swap support explicitly.

Proof: sudo swapoff -a and comment out the fstab swap lines; or set failSwapOn: false and a memorySwap behavior in the kubelet configuration.

Follow-up: Which systemd unit type would still activate swap after the fstab line is removed? (A .swap unit, or zram.)


Captured on Rocky Linux 10.2 and Ubuntu 24.04.4 LTS (iximiuz Labs microVMs, kernel 6.1.167, util-linux 2.40.2), 2026-09.