Do You Need Swap on Linux? How to Set vm.swappiness

Do you need swap on Linux? Learn when swap adds value under memory pressure, what happens without it (OOM killer), how vm.swappiness differs for servers and desktops, swapfile vs partition, and how to tune sysctl safely.

Published

Updated

Read time 15 min read

Reviewed byDeepak Prasad

Linux swap and vm.swappiness guide with memory pressure and swapfile diagram

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.

WARNING
Do not run 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:

bash
swapon --show
free -h
text
NAME      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.4Gi

That 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:

bash
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 --show
text
Mem:           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   -1

After 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:

bash
vmstat 1
text
procs -----------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  0

swpd 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:

bash
cat /proc/pressure/memory

Rising 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 upgrade or do-release-upgrade while 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:

bash
# 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}')
"
text
seconds=0.094

With RAM full and ~540 MiB already in swap, I re-ran the same page walk while stress-ng held memory pressure:

bash
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 3

The 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:

text
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  0

si 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

  1. Thrashing — when active memory exceeds RAM, the kernel spends CPU moving pages (si/so never idle) and interactive latency collapses.
  2. Unbounded latency — swap-backed faults are milliseconds; RAM faults are nanoseconds. Tail latency breaks SLAs long before OOM.
  3. Shared disk — swap on the same SSD as your database or logs competes for IOPS during pressure.
  4. Still finitefree shows Swap: 2.4Gi total; when used swap approaches total, you are back to OOM risk.
  5. Wrong tool for steady state — if swapon --show reports hundreds of MiB used every day while the box feels slow, add RAM or shrink workloads; do not grow swap to 32 GiB.
NOTE
Modest swap (often 1–4 GiB on servers, or a swapfile matching installer defaults) plus enough RAM for your baseline workload is the balanced setup. See Red Hat swap on modern systems.

What happens without swap (OOM killer)

I disabled swap and ran a Python allocator that grows until the kernel stops it:

bash
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)
PY

With swap off, the process was killed at about 3.6 GiB allocated (exit 137):

text
allocated 300 MB
...
allocated 3600 MB
Killed
text
Out 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:

bash
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:
text
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:

bash
sudo swapon -a

Command 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:

bash
grep swap /etc/fstab
file /swap.img
ls -lh /swap.img
text
/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.

bash
sysctl vm.swappiness
cat /proc/sys/vm/swappiness
text
vm.swappiness = 60

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

bash
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:

text
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  0

At vm.swappiness=60 with the same workload:

text
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  0

so 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:

bash
echo 'vm.swappiness=10' | sudo tee /etc/sysctl.d/99-swap.conf
sudo sysctl --system
sysctl vm.swappiness

Broader sysctl context: sysctl configuration for high performance servers (treat swap-related values as part of a tested profile, not copy-paste defaults).

NOTE
Avoid 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 (systemd MemoryMax=, 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


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.


Frequently Asked Questions

1. Do I need swap if I have enough RAM?

Keep a modest swapfile or partition anyway. When RAM fits your normal workload, swap stays at 0 B used—that is healthy. Swap pays off during spikes: on my test host it absorbed hundreds of MB and delayed the OOM killer until RAM plus swap were exhausted.

2. What happens if Linux has no swap?

When physical memory fills, the kernel invokes the OOM killer and terminates a process—often the largest consumer. With swap disabled, that happens sooner. With swap enabled, inactive pages move to disk first so short bursts can finish without an immediate kill.

3. What vm.swappiness value should I use on a Linux server?

Start with 10 on general servers, 1–10 on databases and latency-sensitive apps, and 30–60 only on small utility hosts where brief paging is acceptable. Do not use 0 expecting swap to stay off on modern kernels—use 1–10 plus a small swapfile as a safety net.

4. Why is my swap usage always 0 B?

That usually means RAM still covers your working set. Swap is insurance, not extra RAM for daily use. Check swapon --show and free -h; investigate only if swap stays heavily used while the system feels slow.

5. What is the difference between a swap partition and /swap.img?

Both are swap backing store. A partition is a dedicated disk slice; a swapfile is a regular file on an existing filesystem. Modern Ubuntu and Debian installers often create /swap.img and an fstab line—functionally the same to the kernel after mkswap and swapon.

6. Is a file named swap.img the same as Vim .swp files?

No. /swap.img is kernel swap space. Vim .swp files are editor recovery files and have nothing to do with memory—see found a swap file by the name for that warning.

7. Should I disable swap for Kubernetes?

Yes on kubelet nodes unless you explicitly enable the NodeSwap feature gate. For ordinary Linux servers and desktops, keep a small swapfile and tune swappiness instead of disabling swap entirely.

8. How do I set vm.swappiness permanently?

Create /etc/sysctl.d/99-swap.conf with vm.swappiness=10 (or your chosen value), then run sudo sysctl --system or reboot. Verify with sysctl vm.swappiness and cat /proc/sys/vm/swappiness.

9. Can I use a large swapfile instead of buying more RAM?

No for day-to-day capacity. Swap is orders of magnitude slower than RAM, raises latency under pressure, and still ends in OOM once RAM plus swap are full. Keep modest swap as a spike buffer; size RAM for your real working set.

10. Does lowering vm.swappiness stop Linux from using swap?

No—it changes how eagerly anonymous pages are swapped versus reclaiming page cache. On my host, vm.swappiness=10 showed about 5.5 MB/s swap-out under stress-ng while 60 showed about 100 MB/s for the same load. Under extreme pressure the kernel still uses swap; low values just delay and reduce it.
Deepak Prasad

R&D Engineer

Founder of GoLinuxCloud with more than 15 years of expertise in Linux, Python, Go, Laravel, DevOps, Kubernetes, Git, Shell scripting, OpenShift, AWS, Networking, and Security. With extensive …