Does your VPS need swap? How to size it
Most cloud images ship with no swap. Here is when a small VPS needs a swap file, how big to make it, what vm.swappiness trades, and when zram wins.
Does your VPS need swap?
Most cloud images ship with no swap, and on a small VPS the answer is usually yes, add a swap file. Swap does not make a 1 GB server behave like a 2 GB server. It gives the kernel somewhere to put cold anonymous pages, which keeps the page cache useful and makes the OOM killer (out of memory killer, the kernel routine that picks a process and kills it to free memory) a last resort instead of a first one.
The short version: on a box that runs a few long lived services, a small swap file is worth the disk it costs. On a box where one process regularly tries to allocate more than the whole machine has, swap will not save you, and it will make the failure slower and harder to see. The rest of this guide is about telling those two apart, and about the two costs that only appear on a VPS.
Every command below needs root on your own server, so run them there rather than copying the output of somebody else's box.
What swap actually does, and what it does not
Linux memory comes in two kinds. File backed pages are copies of things that already exist on disk: your programs and every file you have read recently. That collection is the page cache. Anonymous pages are memory with no file behind them: heap and stack, plus most of what a database allocates at runtime.
When memory runs short the kernel has to reclaim pages. A clean file backed page is cheap to reclaim, because the copy on disk is still there and the page can be read back later. An anonymous page is not, because its only copy is the one in RAM. Without swap the kernel has two choices for anonymous memory: keep it, or kill the process that owns it.
A server with no swap still pages. It just pages the wrong memory. Under pressure the kernel shrinks the page cache, evicting file pages it is about to need again, including the executable text of the programs that are running. Those pages come back as major page faults. You see disk reads in the bi column of vmstat and a climbing pgmajfault counter in /proc/vmstat, while si and so sit at zero the whole time. The box is thrashing and the swap counters report nothing.
What swap does not do is add capacity. If the working set, meaning the pages actually being touched, is larger than RAM, then swap converts an out of memory kill into a very slow server. Sometimes that is the trade you want, because a slow server can be logged into and repaired while a killed database cannot. Sometimes it is worse, because a slow server keeps failing health checks while holding every connection open. Decide which you want before you add it.
Why do cloud images ship without swap?
It is a deliberate choice. One image has to boot on every plan a provider sells, so a fixed swap partition would waste disk on the small plans and be pointless on the large ones. Swap speed also depends on the storage under the guest, which the image cannot know in advance. And image builders optimise for predictable behaviour, because a process that dies immediately is easier to diagnose across a fleet than a machine that stays alive and answers every request seconds late.
Those reasons describe disposable machines. A VPS you keep is a different thing. You repair it instead of replacing it, so a few seconds of paging usually beats a killed service. Treat the missing swap as a default built for somebody else's use case.
Swap file or swap partition on a VPS?
Use a file. A partition means resizing a live root filesystem on a disk that arrived already partitioned, which is real risk for no gain. A file is created and removed with ordinary commands, and you can change the size later without touching the partition table.
Speed is not the tiebreaker. At swapon time the kernel reads the file's extent map once and then submits I/O straight to the block device, so the filesystem is not in the path on each page in and page out. On the same disk, a swap file and a swap partition perform the same.
Two limits are worth knowing. Do not put swap on a network filesystem such as NFS (network file system). And on btrfs the file must have copy on write disabled and compression off, which is why btrfs ships its own helper for creating one.
How to add a swap file on Ubuntu or Debian
Check what you have before you change anything.
swapon --show
free -h
findmnt -no FSTYPE /Empty output from swapon --show means there is no swap at all, which is the normal state of a fresh cloud image. findmnt prints the root filesystem type, and that decides how you create the file. On ext4, which is what most cloud images use, fallocate is safe.
sudo fallocate -l 2G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfileThe chmod comes before mkswap on purpose. Skip it and mkswap tells you so: mkswap: /swapfile: insecure permissions 0644, fix with: chmod 0600 /swapfile. A world readable swap file hands every user on the box the memory that other processes paged out. A healthy mkswap then confirms the size, with a line like Setting up swapspace version 1, size = 2 GiB (2147479552 bytes).
On xfs or btrfs the last command can fail with swapon: /swapfile: swapon failed: Invalid argument. On XFS that happens because fallocate leaves unwritten extents, so write the bytes instead.
sudo dd if=/dev/zero of=/swapfile bs=1M count=2048 status=progressOn btrfs the cause is copy on write, and current btrfs-progs sets the right flags for you.
sudo btrfs filesystem mkswapfile --size 2g /swapfileEither way, finish with chmod 600, mkswap where it applies, and swapon, then confirm the result.
swapon --show
free -hswapon --show should list /swapfile with type file and the size you asked for, and free -h should show a Swap row with almost nothing used. Zero used swap on a fresh setup is correct. The kernel only moves pages there when it has a reason.
Make it survive a reboot, then test the entry straight away.
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab
sudo swapoff /swapfile
sudo swapon -a
swapon --showswapon -a reads /etc/fstab, so a wrong line fails now, in front of you. A typo you never test is a typo you meet during an unplanned reboot, when the box comes back up without the swap you thought it had.
To remove swap later, run sudo swapoff /swapfile, delete the fstab line, then sudo rm /swapfile. swapoff has to read every paged out page back into RAM first, so on a busy box it can fail with swapoff: /swapfile: swapoff failed: Cannot allocate memory. Free some memory and try again.
How big should the swap file be?
The job is holding cold anonymous pages, so the size that matters is how much of your allocated memory is genuinely idle, not how much RAM the plan has. Idle memory does not grow in step with plan size, so the multiplier falls as the plans get bigger. This is the rule this guide uses.
The data behind this chart
[
{
"label": "1 GB plan",
"swap_gb": 2,
"swap_x_ram": 2
},
{
"label": "2 GB plan",
"swap_gb": 2,
"swap_x_ram": 1
},
{
"label": "4 GB plan",
"swap_gb": 2,
"swap_x_ram": 0.5
},
{
"label": "8 GB plan",
"swap_gb": 4,
"swap_x_ram": 0.5
},
{
"label": "16 GB plan",
"swap_gb": 4,
"swap_x_ram": 0.25
}
]On the smallest plan that is 2 GB of swap, which is 2 times RAM, because a 1 GB box has so little headroom that one spike reaches the OOM killer. At the top of the chart the file stops at 4 GB, or 0.25 times RAM, because paging that much data on shared storage takes long enough that the server is effectively down while it happens. Trim these numbers if your disk allowance is tight, since the file costs real disk.
The one classic reason to size swap at or above RAM is hibernation, which writes the entire memory image into swap. A VPS does not hibernate, so that rule does not apply to you.
What does vm.swappiness really change?
vm.swappiness is not a percentage of RAM and it is not a threshold. It is the relative cost the kernel assigns to reclaiming anonymous pages compared with file pages. The default is 60. Lower it and the kernel prefers to drop page cache. Raise it and the kernel prefers to page anonymous memory out to swap.
That is a trade in both directions. At vm.swappiness = 10 a database keeps more of its allocations resident, and pays for it by re-reading files it just dropped from cache. On a box whose real work is serving files, that is the wrong direction, because the page cache is doing the useful work there.
Setting it to 0 does not turn swap off. It tells the kernel to avoid anonymous reclaim until it is nearly out of memory, which brings the OOM killer forward rather than pushing it back. If you want no swap, remove the swap file.
sysctl vm.swappiness
printf 'vm.swappiness = 10\n' | sudo tee /etc/sysctl.d/99-swappiness.conf
sudo sysctl --system
sysctl vm.swappinessA bare sysctl -w lasts until the next reboot and then quietly stops applying, so write the file under /etc/sysctl.d/. Kernels since 5.8 accept values from 0 to 200. Above 100 only makes sense when swap is about as fast as RAM, and that means zram.
zram: swap that costs CPU instead of disk
zram is a compressed block device that lives in RAM. Use it as swap and a page that would have gone to disk gets compressed and stays in memory. No disk I/O, and no disk quota consumed. The cost is CPU time on every page in and page out, plus the RAM that holds the compressed pages, which your applications no longer get.
Compression ratios between 2:1 and 3:1 are the figures usually published for anonymous pages, and your own number is printed by zramctl in its DATA and COMPR columns. Measure rather than plan around the typical figure, because some workloads hold data that barely compresses at all.
sudo apt install zram-toolsSet ALGO=zstd and PERCENT=25 in /etc/default/zramswap, then restart the service and look at the result.
sudo systemctl restart zramswap
zramctl
swapon --showPERCENT is a share of total RAM, so 25 on a 4 GB box reserves up to 1 GB for compressed pages. Start low and raise it only if zramctl shows the device filling. The PRIORITY setting in the same file decides which swap the kernel fills first: higher wins, and a disk swap file added with plain swapon gets a negative priority, so zram is used first and the file catches the overflow. swapon --show prints both in its PRIO column. On distributions that use systemd-zram-generator instead of zram-tools, the same settings live in /etc/systemd/zram-generator.conf.
zram suits a box with CPU headroom and little spare disk. It is the wrong choice when the CPU allowance is the resource you are already short of, because compression work competes with the application for the same slice.
Two swap traps that only bite on a VPS
The first trap is disk. A 2 GB swap file takes 2 GB of your plan's disk the moment you create it, because the space must be allocated up front. df -h / drops by the full amount immediately and does not recover until you delete the file. On a small plan that is a noticeable slice, and a full root filesystem breaks far more than swap ever fixed. The file counts in du output too, which is worth remembering when you are hunting for space and df and du disagree about where the disk went.
The second trap is latency. Your swap I/O goes to storage the host shares with its other guests, and you cannot see their load from inside your guest. You only see the effect: a page in that is normally quick sometimes takes far longer, and the process waiting on it stops until the page arrives. That is the same reasoning as CPU steal time on a shared host, applied to the disk queue instead of the run queue. Measure it on your own box, because any published latency number describes somebody else's neighbours.
How do you know if swapping is hurting you?
Used swap is not a problem. Swap traffic is. A server with several hundred megabytes parked in swap and no paging activity has simply moved memory that nothing has touched in hours, and that is the outcome you wanted.
Watch the rates instead of the totals.
vmstat 1 5si and so are kibibytes per second swapped in and out. On a healthy box they stay at or near zero whatever the swpd column says. Sustained so with si rising at the same time means pages are being written out and pulled straight back, which is thrashing.
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
2 3 1048572 38210 4096 61440 912 1180 2210 1290 1402 2890 9 7 12 72 0That sample shows a box in trouble, and the clearest signal is not in the swap columns. It is wa at 72, meaning the CPU spent most of its time waiting on I/O, and b at 3, meaning three processes are blocked.
PSI (pressure stall information) answers the question more directly.
cat /proc/pressure/memorysome avg10=8.42 avg60=5.11 avg300=2.03 total=1284729
full avg10=3.10 avg60=1.94 avg300=0.71 total=498210some avg10=8.42 means that during the last 10 seconds, at least one task was stalled waiting on memory for 8.42 percent of the time. full counts the time when every non idle task was stalled, so a sustained full value is measurable damage rather than a warning sign. If the file does not exist, your kernel has PSI disabled by default and needs psi=1 on the kernel command line.
To see which processes hold pages in swap:
sudo awk '/^Name:/{n=$2} /^VmSwap:/ && $2+0 > 0 {printf "%10d kB %s\n", $2, n}' /proc/[0-9]*/status | sort -rn | headAnd to find out whether the OOM killer has already visited:
sudo journalctl -k --grep "Out of memory"A hit reads like Out of memory: Killed process 2199 (mysqld) total-vm:1275860kB, anon-rss:129252kB, file-rss:0kB, shmem-rss:0kB, UID:114 pgtables:504kB oom_score_adj:0, and the service log for the same second says Main process exited, code=killed, status=9/KILL. If you have seen those lines on a box with no swap, adding a swap file is the cheapest thing to try next.
When swap is the wrong fix
Swap buys time for memory pressure that is temporary or cold. It does nothing for a process that grows until it dies, and it makes that failure harder to watch, because the machine spends the extra minutes paging instead of failing quickly and restarting.
Cap the process instead. A systemd service accepts MemoryMax= and MemorySwapMax= in a drop in file, which is how you limit memory and CPU for a service with systemd without changing the application. Containers have the same controls one level up, and setting them is how you stop one Compose service from eating the whole box. Both give you a kill with a name attached in a log you can find, instead of letting the kernel choose the victim by score.
Do this while the server is new and quiet. Creating the swap file and setting one memory limit takes a few minutes, and it belongs with the rest of the work in the first ten minutes on a new VPS.
FAQ
Does adding swap make my 1 GB VPS act like a 2 GB VPS?
No. Swap is far slower than RAM, and the kernel only moves pages there that it judges to be cold. What it buys is headroom for spikes and a place to park memory that was allocated and then never touched. If your workload actively reads and writes more memory than the machine has, swap turns an out of memory kill into constant paging, and the server stays up while answering too slowly to use. For that case, add RAM or cap the process that grows.
How much swap does a 1 GB or 2 GB VPS need?
2 GB covers both, and it does not need to keep scaling with RAM after that. Swap holds cold anonymous pages, and the amount of genuinely cold memory on a server does not grow the way total RAM does. The old rule of twice RAM comes from hibernation, which writes the whole memory image to disk, and a VPS never hibernates. Sizing past 4 GB mostly buys a longer and slower failure on storage you share with other guests.
Is setting vm.swappiness to 0 the right way to stop swapping?
No, and it does not do what the name suggests. vm.swappiness = 0 does not disable swap. It tells the kernel to avoid reclaiming anonymous pages until it is close to out of memory, which makes an OOM kill more likely rather than less. It also pushes all reclaim onto the page cache, so file reads go back to disk more often. If you want no swap at all, run sudo swapoff -a and remove the fstab line. If you want less swapping, try vm.swappiness = 10 and compare the si and so columns in vmstat before and after.
Should I use zram instead of a swap file?
Use zram when you have CPU headroom and little spare disk, and a swap file when the opposite is true. zram compresses pages and keeps them in RAM, so it avoids disk I/O completely, at a CPU cost on every page in and page out, and the space it takes is RAM the applications no longer get. On a VPS with a small CPU allowance, that cost lands on the resource you are already short of. Running both is normal: give zram the higher priority with PRIORITY in /etc/default/zramswap and keep a disk swap file underneath it for overflow.
Why did the OOM killer run when free showed memory available?
free reports one moment, and an allocation happens in an instant. A process asking for a large block faster than reclaim can free memory gets killed even though the average looked comfortable. Read the kernel log with sudo journalctl -k --grep "Out of memory", which names the killed process and its resident size at the time. Then check whether the kill came from a cgroup limit rather than the whole machine, because a container or a systemd unit with MemoryMax= set is killed at its own limit while the host still has free memory.