Swap is disk (or compressed RAM) the Linux kernel uses when physical memory is under pressure. It is not a substitute for RAM, but it changes what happens when a spike exceeds what fits in memory: the system can page out cold anonymous pages instead of calling the OOM killer immediately.
This guide answers whether you need swap, when it helps, what breaks without it, and how to choose vm.swappiness. I ran controlled memory-pressure tests on a Linux host (Ubuntu 25.04 with a /swap.img swapfile, about 5 GiB RAM and 2.4 GiB swap) and kept real terminal output below. The kernel behavior is the same on Debian, RHEL, and other distributions—only defaults and installer layout differ.
Tested on: Ubuntu 25.04 (Plucky Puffin); kernel 7.0.0-27-generic.
swapoff -a on production hosts unless you have console access and accept immediate OOM risk. Re-enable swap with swapon -a after lab tests.
Quick answer: do you need swap?
| Situation | Recommendation |
|---|---|
| Normal daily use, RAM not full | Yes, keep swap—it can sit at 0 B used for months |
| Brief memory spikes (updates, builds, backups) | Yes—swap absorbs pressure; performance may dip, processes often survive |
| Sustained swap I/O under normal load | Fix RAM sizing or leaks—swap is a safety net, not a capacity upgrade |
| Latency-sensitive DB / Redis / real-time | Small swap plus low swappiness (1–10)—OOM only after RAM and swap are exhausted |
| Kubernetes worker nodes | Disable swap per kubelet requirements—see your cluster docs |
You need swap the way you need a spare tire—not on every trip, but you want it when pressure spikes.
Quick command summary
| Task | Command |
|---|---|
| Check swap | swapon --show and free -h |
| Swap detail | `grep -E 'Swap |
| Current swappiness | sysctl vm.swappiness |
| Set swappiness (persistent) | echo 'vm.swappiness=10' | sudo tee /etc/sysctl.d/99-swap.conf then sudo sysctl --system |
| Memory pressure (PSI) | cat /proc/pressure/memory |
| Live paging stats | vmstat 1 (columns si / so) |
| Disable swap (lab) | sudo swapoff -a |
| Re-enable swap | sudo swapon -a |
Why swap shows 0 B even when swap is enabled
On my host, swap had been configured since install but USED stayed 0 B until I deliberately exhausted memory:
swapon --show
free -hNAME TYPE SIZE USED PRIO
/swap.img file 2.4G 0B -1
total used free shared buff/cache available
Mem: 5.2Gi 1.5Gi 1.9Gi 26Mi 2.0Gi 3.7Gi
Swap: 2.4Gi 0B 2.4GiThat matches how most desktops and small servers behave: if your working set fits in RAM, the kernel never touches swap. Unused swap is not wasted space—it is unused reserve.
For deeper background on active vs inactive anonymous memory and when paging is healthy, see Linux memory management overview.
When swap adds value (memory pressure test)
Swap matters when allocated memory exceeds what RAM can hold. I used stress-ng with two 3 GiB VM workers on a host with about 5.2 GiB RAM—roughly 6 GiB demand on 5 GiB RAM (sudo apt install -y stress-ng if the tool is missing).
With swap enabled:
sudo stress-ng --vm 2 --vm-bytes 3G --vm-keep --timeout 45s
# In another terminal during the run:
free -h | grep -E 'Mem:|Swap:'
swapon --showMem: 5.2Gi 4.4Gi 223Mi 36Mi 921Mi 802Mi
Swap: 2.4Gi 221Mi 2.2Gi
NAME TYPE SIZE USED PRIO
/swap.img file 2.4G 221.9M -1After the stressor exited, about 391 MiB remained in swap until the kernel reclaimed it—proof that swap held anonymous pages when RAM filled.
In a second terminal during the same run, vmstat 1 showed pages leaving RAM (so, swap out) while swpd climbed toward the ~221 MiB seen in free -h:
vmstat 1procs -----------memory---------- ---swap-- -----io---- -system-- -------cpu-------
r b swpd free buff cache si so bi bo in cs us sy id wa st gu
8 0 227024 266824 5568 908980 0 230 2616 408 1881 8 6 14 80 1 0 0swpd is in kilobytes (227024 ≈ 221 MiB). Non-zero so means the kernel wrote anonymous pages to /swap.img instead of stopping the workload immediately. si (swap in) stays low here because the test mostly allocated and held memory; si spikes when you read back data that already lives on swap (see the next section).
For a pressure gauge beyond free, PSI reports how long tasks spent stalled on memory in the last window:
cat /proc/pressure/memoryRising avg10 under some or full means memory pressure is real—more useful than a one-off free -h snapshot during a spike.
When this helps in real life:
apt upgradeordo-release-upgradewhile browsers and IDEs are open- Backup jobs (
tar,restic) that spike memory briefly - CI builds that exceed RAM for a few minutes
When it does not help: if the machine continuously swaps under normal load, add RAM or reduce memory hogs—swap only slows the pain.
Is swap a substitute for RAM?
No. Swap is overflow storage on disk (or compressed RAM in zram setups), not extra working memory you can plan around. You can provision a 20 GiB swapfile on a 4 GiB VPS, but if your applications routinely need 8 GiB of resident data, the machine will thrash, stall, or still hit the OOM killer once RAM plus swap are exhausted.
Think of RAM as your desk and swap as a filing cabinet in the next room. The cabinet lets you survive a messy afternoon; it does not let you run a bigger office.
What swap can and cannot do
| Expectation | Reality on Linux |
|---|---|
| 8 GiB RAM + 16 GiB swap ≈ 24 GiB usable memory | False for performance. Only cold or idle pages belong on swap; hot heap and caches must stay in RAM or every access pays disk latency. |
| Swap lets me run the same workload on a cheaper small VM | Only if the workload’s working set still fits in RAM most of the time. Sustained si/so in vmstat means you are under-provisioned. |
| More swap prevents OOM | It delays OOM until RAM + swap are full, then the kernel still kills a process (see below). |
| Swap is useless because it is slow | Slowness is the trade-off: swap buys time, not throughput. |
Proof 1: page access is much slower once data is on swap
I timed a simple workload that walks every 4 KiB page in 1 GiB of anonymous memory—first with plenty of free RAM, then again after filling RAM and pushing older pages to swap under stress-ng pressure:
# Low pressure: allocate 1 GiB and read every page
python3 -c "
import time
chunks = [bytearray(256*1024*1024) for _ in range(4)]
start = time.perf_counter()
s = sum(c[i] for c in chunks for i in range(0, len(c), 4096))
print(f'seconds={time.perf_counter()-start:.3f}')
"seconds=0.094With RAM full and ~540 MiB already in swap, I re-ran the same page walk while stress-ng held memory pressure:
sudo stress-ng --vm 2 --vm-bytes 2800M --vm-keep --timeout 120s &
sleep 6
python3 -c "
import time
chunks = [bytearray(256*1024*1024) for _ in range(4)]
for c in chunks:
for i in range(0, len(c), 4096):
c[i] = 1
extra = [bytearray(200*1024*1024) for _ in range(8)]
start = time.perf_counter()
s = sum(c[i] for c in chunks for i in range(0, len(c), 4096))
print(f'seconds={time.perf_counter()-start:.3f}')
"
vmstat 1 3The same 1 GiB re-touch took 0.422 s—about 4.5× longer for identical code. Under heavier churn (2 GiB re-touch while stress-ng held ~6 GiB allocated), vmstat showed sustained swap traffic:
r b swpd free buff cache si so bi bo in cs us sy id wa st gu
6 0 547196 2599148 19724 599592 1337 2083 4074 2450 2256 11 9 27 61 3 0 0
6 0 546956 2527204 19832 603932 896 0 1336 676 1247 1290 50 31 11 8 0 0si and so in kilobytes per second, double-digit wa (I/O wait), and sy (kernel time) jumping to 27–50% are signs the CPU is waiting on swap I/O—not behavior you want as “normal” capacity.
DRAM bandwidth is orders of magnitude higher than SSD swap (roughly tens of GB/s vs hundreds of MB/s). Swap cannot replace that gap for databases, JVM heaps, or in-memory caches.
Proof 2: swap extends survival, not comfortable capacity
The same host with swap disabled OOM-killed a growing Python allocator at ~3.6 GiB. With swap enabled, the identical script reached ~5.4 GiB before a timeout—swap added headroom, but the machine was already paging heavily and would have kept slowing down until limits were hit.
That is the intended contract: swap is a safety net for spikes, not a license to run an 8 GiB working set on 4 GiB RAM because you added a large swapfile.
Practical caveats if you “solve” low RAM with swap only
- Thrashing — when active memory exceeds RAM, the kernel spends CPU moving pages (
si/sonever idle) and interactive latency collapses. - Unbounded latency — swap-backed faults are milliseconds; RAM faults are nanoseconds. Tail latency breaks SLAs long before OOM.
- Shared disk — swap on the same SSD as your database or logs competes for IOPS during pressure.
- Still finite —
freeshowsSwap: 2.4Gi total; when used swap approaches total, you are back to OOM risk. - Wrong tool for steady state — if
swapon --showreports hundreds of MiB used every day while the box feels slow, add RAM or shrink workloads; do not grow swap to 32 GiB.
What happens without swap (OOM killer)
I disabled swap and ran a Python allocator that grows until the kernel stops it:
sudo swapoff -a
python3 <<'PY'
chunks = []
i = 0
while True:
chunks.append(bytearray(150 * 1024 * 1024))
i += 1
if i % 2 == 0:
print(f"allocated {i*150} MB", flush=True)
PYWith swap off, the process was killed at about 3.6 GiB allocated (exit 137):
allocated 300 MB
...
allocated 3600 MB
KilledOut of memory: Killed process 6736 (python3) total-vm:4013968kB, anon-rss:3936336kB ...With swap on and the same script (45 s timeout), allocation reached about 5.4 GiB before timeout—no OOM in that window—and swap held about 595 MiB:
sudo swapon -a
timeout 45 python3 <<'PY'
chunks = []
i = 0
while True:
chunks.append(bytearray(150 * 1024 * 1024))
i += 1
if i % 2 == 0:
print(f"allocated {i*150} MB", flush=True)
PY
free -h | grep Swap:allocated 5400 MB
Swap: 2.4Gi 594Mi 1.8Gi| Configuration | Result on test host |
|---|---|
| Swap off | OOM killer at ~3.6 GiB allocated |
| Swap on | ~5.4 GiB allocated; ~595 MiB swap used; process survived until timeout |
Without swap, the failure mode is abrupt process death. With swap, the failure mode is slower performance—often preferable for interactive systems so you can save work or kill the right process yourself.
Re-enable swap after lab work:
sudo swapon -aCommand reference: swapon and swapoff.
Swapfile vs swap partition (and why you see /swap.img)
Historically, installers created a dedicated swap partition (/dev/sda2 type 82). You mounted nothing on it—the kernel used the raw slice after mkswap.
Modern Ubuntu and Debian desktop/server installs often create a swap file instead:
grep swap /etc/fstab
file /swap.img
ls -lh /swap.img/swap.img none swap sw 0 0
/swap.img: Linux swap file, 4k page size, little endian, version 1, size 634111 pages, ...
-rw------- 1 root root 2.5G ... /swap.img| Backing store | Pros | Cons |
|---|---|---|
| Swap partition | Simple on MBR layouts; no file overhead | Harder to resize; competes with partition table |
Swap file (/swap.img, /swapfile) |
Resize without repartitioning; easy on LVM/VM disks | Must live on a filesystem that supports swap files |
The kernel treats both the same after mkswap and swapon. The .img name is just Ubuntu’s default filename—not a new swap format and not related to Vim’s .swp recovery files (editor swap files explained).
Across distributions:
| Distribution | Typical default | Notes |
|---|---|---|
| Ubuntu (recent) | /swap.img swapfile in fstab |
Cloud images may ship without swap until you add one |
| Debian | Swap partition or file depending on installer | Same swapon/sysctl tools |
| RHEL / Alma / Rocky | Often LVM swap LV or partition | Red Hat swap guidance recommends modest swap even on large RAM |
| Fedora / openSUSE | Mix of file and partition | vm.swappiness default often 60 |
| Minimal containers / K8s nodes | No swap by design | Kubelet expects swap off unless NodeSwap is configured |
The memory manager is kernel code—vm.swappiness, swapoff, and OOM behavior do not change by distro. Only installer defaults and packaging differ.
What is vm.swappiness and what value should you use?
vm.swappiness (0–100) nudges how eagerly the kernel swaps anonymous pages (heap, stack) versus reclaiming page cache. It does not disable swap by itself on modern kernels.
sysctl vm.swappiness
cat /proc/sys/vm/swappinessvm.swappiness = 60Default 60 suits general-purpose desktops. Servers often lower it so hot application memory stays in RAM until real pressure.
Benchmark: same load at vm.swappiness 1, 10, 60, and 100
vm.swappiness does not turn swap on or off—it changes how eagerly the kernel swaps anonymous pages versus dropping page cache when memory is tight. To show that, I ran the same synthetic pressure on this host four times: reset swap, drop caches, warm ~1.5 GiB of page cache, then run stress-ng --vm 2 --vm-bytes 2500M for 30 seconds while sampling vmstat.
sudo sysctl -w vm.swappiness=10 # repeat for 1, 60, 100
sudo swapoff -a && sudo swapon -a
sync && echo 3 | sudo tee /proc/sys/vm/drop_caches
sudo stress-ng --vm 2 --vm-bytes 2500M --vm-keep --timeout 30s
# second terminal during the run:
vmstat 1
free -h | grep Swap:vm.swappiness |
Swap used after test | Peak so (swap out, KB/s) |
Notes |
|---|---|---|---|
| 1 | ~1.2 GiB | 47280 | Lowest early swap-out burst in the clean rerun; still pages under extreme pressure |
| 10 | ~1.2–1.5 GiB | 5684 | Kernel prefers reclaiming cache before swapping anon memory |
| 60 (Ubuntu default) | ~1.8 GiB | 102360 | Highest sustained swap-out rate in the test window |
| 100 | ~2.1 GiB | 7600 | Pushes anonymous pages to swap aggressively; neared the 2.4 GiB swapfile cap |
At vm.swappiness=10 during pressure:
r b swpd free buff cache si so bi bo in cs us sy id wa st gu
3 1 1248060 143408 3268 1313404 92 5684 2728 5684 1746 440 31 22 47 1 0 0At vm.swappiness=60 with the same workload:
r b swpd free buff cache si so bi bo in cs us sy id wa st gu
3 0 1171856 144092 6228 1477948 732 102360 1464 102392 4554 1524 5 93 0 2 0 0so jumped from ~5.5 MB/s to ~100 MB/s for the same stress-ng profile—same RAM, same swapfile, different sysctl. Higher swappiness also left more data in swap afterward (1.8–2.1 GiB vs ~1.2 GiB at 1–10), which means later access to those pages pays swap-in latency (si) even after the spike ends.
What this means in practice:
- Under real memory pressure, lowering swappiness reduces how fast anonymous memory lands on disk—it does not eliminate swap when RAM is genuinely full.
- The default 60 is reasonable on desktops where brief paging is acceptable; database and application servers usually feel snappier at 1–10 because hot heap stays in RAM longer.
- Tuning swappiness is not a substitute for RAM sizing (see Is swap a substitute for RAM?)—it only changes reclaim preference at the margin.
| Workload | Suggested vm.swappiness |
Rationale |
|---|---|---|
| General Linux server | 10–30 | Keep swap as emergency buffer; avoid casual paging |
| Desktop / laptop (SSD) | 10–60 (60 default is OK) | Slightly lower (10) if you prefer RAM for GUI apps |
| Database / Redis / JVM heap | 1–10 | Minimize latency spikes from disk paging |
| Small VPS (2–4 GiB RAM) | 10–30 plus 1–2 GiB swap | Survive spikes; monitor sustained si/so |
| Kubernetes node | N/A (swap off) | Not a swappiness tuning target |
Set persistently:
echo 'vm.swappiness=10' | sudo tee /etc/sysctl.d/99-swap.conf
sudo sysctl --system
sysctl vm.swappinessBroader sysctl context: sysctl configuration for high performance servers (treat swap-related values as part of a tested profile, not copy-paste defaults).
vm.swappiness=0 as a substitute for “no swap.” On current kernels it changes reclaim behavior; use 1–10 plus a small swapfile if you want swap rare but available. See Red Hat swap on modern systems.
When to disable swap (and when not to)
Reasonable to disable or leave swap off:
- Kubernetes workers (kubelet requirement)
- Carefully sized appliances with hard memory limits (
systemdMemoryMax=, cgroups) and monitored OOM policy - You accept immediate OOM kills on any overrun
Poor reasons to disable:
- “I have lots of RAM” — spikes still happen (Unix.SE consensus)
- “Swap is slow so it is useless” — slowness is the point; it trades latency for survival time
- “Swap on SSD wears the disk” — on modern SSDs, small occasional swap is usually negligible versus capacity planning; size swap modestly (often 1–4 GiB on servers per Red Hat)
Troubleshooting
| Symptom | Likely cause | Action |
|---|---|---|
| Swap always 0 B | Healthy—RAM fits working set | No action unless you expect pressure |
| Swap constantly used, system slow | Under-provisioned RAM or leak | Add RAM; fix leak; do not only grow swap |
swapon: cannot find device |
Missing /swap.img or wrong fstab |
sudo mkswap /swap.img; check /etc/fstab |
| OOM kills with swap present | Demand exceeded RAM plus swap | Increase RAM or reduce workload; swap is not infinite |
| Wrong process killed | OOM score / cgroup limits | Tune oom_score_adj, systemd OOMScoreAdjust, or memory limits |
References
- Linux memory management overview
- swapon and swapoff commands
- Sysctl configuration for high performance servers
- Do we really need swap on modern systems? (Red Hat)
- Do I need swap if I have enough RAM? (Unix & Linux Stack Exchange)
Summary
You need swap on most Linux systems as a safety net, not as daily extra memory or a cheap RAM replacement. When RAM covers your workload, swap correctly stays at 0 B used—that was true on my host until I forced pressure. Under overload, swap held hundreds of megabytes and let allocation continue, but the same pages accessed from swap were several times slower than in RAM; with swap disabled, the OOM killer stopped the same class of workload much earlier.
Set vm.swappiness to 10–30 on servers (lower for databases), keep a modest swapfile or partition, and treat sustained swap I/O as a capacity problem. /swap.img on Ubuntu is a normal swap file, not a new format—functionally equivalent to the swap partitions you remember from older installs.

