Swap Space on a VPS: When You Need It and How to Add It
Swap Space on a VPS: When You Need It and How to Add It By the end of this guide you will have a working 1 GB swap file on your VPS, tuned so the kernel only reaches for it under real pressure, and persisted so it survives a reboot. You will also know the […]

Swap Space on a VPS: When You Need It and How to Add It
By the end of this guide you will have a working 1 GB swap file on your VPS, tuned so the kernel only reaches for it under real pressure, and persisted so it survives a reboot. You will also know the harder question: whether you should add swap at all, or spend the same money on RAM.
Every command below was run on a clean Ubuntu 24.04 server and the output pasted verbatim. Nothing here is copied from memory.
First, do you even have swap? (Probably not)
A fresh cloud image usually ships with no swap at all. This surprises people who expect a server to behave like their laptop. Here is the very first thing we checked on a brand-new Ubuntu 24.04 VPS:
$ swapon --show
$ free -h
total used free shared buff/cache available
Mem: 1.9Gi 360Mi 1.4Gi 2.7Mi 291Mi 1.5Gi
Swap: 0B 0B 0B
swapon --show printed nothing – there is no swap device. free -h confirms it: Swap: 0B. If your box looks like this, the OOM killer is your only line of defence when memory runs out. That is the gap swap fills.
When you actually need swap (and when you don’t)
Swap is a shock absorber, not a RAM substitute. Get that distinction right and every other decision follows.
Add swap when:
- You run on a small plan (1-2 GB RAM) and occasionally brush the ceiling – a build step, a backup, a traffic spike,
aptunpacking a large upgrade. - You want the OOM killer to have somewhere to spill cold pages before it starts shooting processes. Without swap, the kernel’s only reclaim option for anonymous memory is to kill something.
- You run a database or long-lived service that allocates memory it rarely touches. Those idle pages can sit in swap and free real RAM for the working set.
Don’t rely on swap when:
- Your workload’s active working set is bigger than RAM. Swap will thrash, latency will spike, and even on NVMe you are roughly a thousand times slower than RAM. This is the case where you upgrade RAM, full stop. Swap cannot fix it – it just lets the box limp instead of crashing.
- You need predictable low latency (a payments API, a game server). A request that touches a swapped-out page pays a disk round-trip. Size RAM for the whole footprint instead.
The “swap is obsolete on modern SSDs” claim you see in forums is half right and dangerous. Fast storage makes swap less painful, not unnecessary. A swap file on NVMe is still disk. The value of swap was never speed – it is having a pressure-release valve so a brief spike degrades performance instead of killing your app. Keep it small, keep it for emergencies, and if you are hitting it constantly, that is the signal to size up – not to add more swap.
If you are on a Lineserve S1 (2 GB RAM) and your app keeps flirting with the ceiling, a 1 GB swap file buys you breathing room today; a move to the M1 plan (4 GB) fixes it properly. Swap first, then measure, then decide.
Prerequisites
- A VPS running Ubuntu 24.04 (these steps also apply to Debian and other systemd distros; version strings will differ).
rootor asudouser. Every command below is run as root; prefix withsudootherwise.- A little free disk. Our test root filesystem had 5 GB free – a 1 GB swap file is comfortable. Check with
df -h /first.
Your baseline should match the “no swap” output above. If swapon --show already lists a device, you have swap; skip to the tuning section.
Step 1: Create the swap file
There are two ways to reserve the space. We tested both and the difference is stark.
fallocate allocates the file’s blocks in one metadata operation – effectively instant:
$ time fallocate -l 1G /swapfile
real 0m0.00s
For comparison, the old dd method writes every byte with zeros:
$ time dd if=/dev/zero of=/swapfile bs=1M count=1024 status=none
real 0m5.21s
Five seconds versus nothing, for the same 1 GB file. Use fallocate on ext4 – it is the default filesystem on a Lineserve Linux VPS and it handles fallocate correctly. The one caveat worth knowing: on Btrfs, fallocate can create a file with holes that swapon later rejects, so on Btrfs (and some ZFS setups) you fall back to dd. On ext4, which is what you almost certainly have, fallocate is the right call.
Confirm the file exists at the size you asked for:
$ ls -lh /swapfile
-rw-r--r-- 1 root root 1.0G Jul 12 15:53 /swapfile
Step 2: Lock down the permissions
Look closely at that last output: -rw-r--r--. The file was created world-readable (mode 644). A swap file will hold whatever the kernel pages out – potentially fragments of process memory. Any local user could read it. Fix that before you activate it:
$ chmod 600 /swapfile
$ stat -c %a /swapfile
600
Now only root can read the swap file. This is not optional – do it every time, before mkswap.
Step 3: Format the file as swap
mkswap writes a swap signature and header onto the file:
$ mkswap /swapfile
Setting up swapspace version 1, size = 1024 MiB (1073737728 bytes)
no label, UUID=1840b602-511b-4a8f-908b-f9186872335b
Note the UUID – mkswap generates one for the swap area. You could reference it in /etc/fstab instead of the path, though for a single swap file the path is simpler and just as stable.
Step 4: Turn swap on
$ swapon /swapfile
$ swapon --show
NAME TYPE SIZE USED PRIO
/swapfile file 1024M 0B -2
Swap is live. TYPE file confirms it is a swap file rather than a partition, and PRIO -2 is the default priority the kernel assigns. free -h now shows the pool:
$ free -h
total used free shared buff/cache available
Mem: 1.9Gi 385Mi 1.4Gi 2.7Mi 292Mi 1.5Gi
Swap: 1.0Gi 0B 1.0Gi
Swap: 1.0Gi total, 0B used. The kernel will only start using it when memory gets tight – which we will prove shortly.
Step 5: Make it survive a reboot
swapon only lasts until the next reboot. To bring the swap file back automatically, add one line to /etc/fstab. Back the file up first – /etc/fstab is the file that can leave a server unbootable if you fat-finger it:
$ cp /etc/fstab /etc/fstab.bak
$ echo "/swapfile none swap sw 0 0" | tee -a /etc/fstab
/swapfile none swap sw 0 0
Do not trust it blind – test the entry now, while you can watch it, rather than discovering a typo on the next reboot. Turn swap off, then let swapon -a re-read /etc/fstab:
$ swapoff /swapfile
$ swapon -a
$ swapon --show
NAME TYPE SIZE USED PRIO
/swapfile file 1024M 0B -2
Swap came back purely from the fstab entry. That is your reboot-safety check, done without a reboot.
Step 6: Tune swappiness
By default the kernel is fairly eager to swap. Check the current value:
$ cat /proc/sys/vm/swappiness
60
60 is the desktop-oriented default. On a server you usually want the kernel to hold pages in RAM longer and only swap when it genuinely must. 10 is the widely used server value:
$ sysctl vm.swappiness=10
vm.swappiness = 10
While we are here, vfs_cache_pressure controls how aggressively the kernel reclaims the directory and inode caches. The default is 100; lowering it to 50 keeps filesystem metadata cached a little longer, which helps file-heavy workloads:
$ cat /proc/sys/vm/vfs_cache_pressure
100
$ sysctl vm.vfs_cache_pressure=50
vm.vfs_cache_pressure = 50
sysctl changes are also lost on reboot. Persist both in a drop-in file under /etc/sysctl.d/:
$ printf "vm.swappiness=10\nvm.vfs_cache_pressure=50\n" | tee /etc/sysctl.d/99-swap.conf
vm.swappiness=10
vm.vfs_cache_pressure=50
$ sysctl --system
* Applying /etc/sysctl.d/99-swap.conf ...
vm.swappiness = 10
vm.vfs_cache_pressure = 50
sysctl --system reloads every drop-in and confirms the new values are active. These now apply on every boot.
Verify it works: put the swap under real pressure
Anyone can show a swapon line. Let us prove the swap file actually catches overflow. On this 2 GB box we allocated 1.6 GB of memory with a short Python script and touched every page so it could not be lazily skipped, then read free -h while the script held the memory:
$ free -h
total used free shared buff/cache available
Mem: 1.9Gi 1.8Gi 70Mi 2.6Mi 88Mi 29Mi
Swap: 1.0Gi 46Mi 977Mi
$ swapon --show
NAME TYPE SIZE USED PRIO
/swapfile file 1024M 46.4M -2
There it is. RAM available collapsed to 29Mi, and the kernel pushed 46Mi of cold pages into swap rather than invoking the OOM killer. The box stayed up and responsive. That 46 MB is the whole point of swap: a brief overflow became a small disk write instead of a killed process.
Two things worth noticing. First, with swappiness=10 the kernel swapped only what it had to – 46 MB, not gigabytes – even at 29 MB free. Low swappiness working exactly as intended. Second, after the script exited, swap did not empty itself:
$ free -h
total used free shared buff/cache available
Mem: 1.9Gi 292Mi 1.6Gi 2.5Mi 91Mi 1.6Gi
Swap: 1.0Gi 62Mi 961Mi
RAM freed up, but Swap still held 62Mi. The kernel does not eagerly page data back in – swapped pages stay on disk until something needs them, because pulling them back has a cost too. If you want swap emptied immediately (before a benchmark, say), run swapoff /swapfile && swapon /swapfile to force everything back into RAM. This is normal, not a leak.
Removing swap cleanly
If you sized up your RAM and no longer want the swap file, remove it in the reverse order you added it. Turn it off, delete the fstab line, then delete the file:
$ swapoff /swapfile
$ swapon --show # prints nothing - swap is off
$ sed -i '\#^/swapfile #d' /etc/fstab
$ rm -f /swapfile
$ free -h
total used free shared buff/cache available
Mem: 1.9Gi 336Mi 1.6Gi 2.7Mi 118Mi 1.5Gi
Swap: 0B 0B 0B
Swap: 0B again, and the gigabyte is back on your disk. Order matters: swapoff before rm. Delete the file while swap is still active and you will crash the machine.
Troubleshooting
swapon: /swapfile: swapon failed: Invalid argument. Almost always one of two things: you skipped mkswap, or the file has holes. If you created it with fallocate on Btrfs/ZFS, delete it and recreate with dd instead, then re-run mkswap. On ext4 (the Lineserve VPS default) this does not happen – fallocate produces a fully-allocated file.
swapon: /swapfile: insecure permissions 0644, 0600 suggested. This is the warning you get for skipping Step 2. It still activates, but fix it: swapoff /swapfile, chmod 600 /swapfile, swapon /swapfile.
Swap shows as used but RAM looks free. This is not a problem – it is the behaviour we captured above. The kernel leaves cold pages in swap after pressure passes. If it genuinely bothers you (or you want a clean slate for a test), swapoff -a && swapon -a cycles it. If swap is constantly full and your app is slow, that is the real signal: your working set exceeds RAM and you should upgrade, not enlarge swap.
Server won’t boot after editing /etc/fstab. This is why we backed it up. On the Lineserve console, use the VNC/serial console to boot into recovery, then cp /etc/fstab.bak /etc/fstab or comment out the swap line. A bad swap entry with the nofail-less default can hang boot on some setups; the backup is your undo.
How much swap, and where it fits
A common starting point: match swap to RAM up to about 2 GB, then cap it (2-4 GB is plenty for most single-purpose servers). Past that you are usually solving the wrong problem. On a Lineserve S1 (2 GB RAM) a 1-2 GB swap file is a sensible safety margin. If you find the box swapping during normal operation rather than rare spikes, the honest fix is more RAM – the M1 plan (4 GB) or L1 (8 GB) – not a bigger swap file.
One more note for busy VPS owners: our test root filesystem mounted with discard enabled, so TRIM keeps the SSD healthy as swap pages are written and freed. You do not need to do anything special for swap-file wear on a modern Lineserve VPS – the default mount options already handle it.
If you are setting up a new server from scratch, add swap as part of your initial hardening pass – it slots in right alongside users, SSH, and the firewall. See our Initial Ubuntu 24.04 Server Setup: Users, SSH, Firewall and 8 Essential Security Steps for Every Production VPS guides for the rest of that checklist. If you are deploying a memory-hungry app, our Deploying a Node.js App to Production on a VPS: The Complete Guide walkthrough pairs well with what you just did here.
Get a VPS that gives you room to tune
Swap tuning like this assumes you control the whole machine – the kernel, /etc/fstab, sysctl. A Lineserve Linux VPS gives you exactly that: full root, SSD storage, and a real Ubuntu 24.04 image you can configure the way this guide shows, in a region close to your users in Nairobi, Dar es Salaam, or Lagos. You pay in your local currency – KES, TZS, or NGN, with M-Pesa and mobile money in Kenya and Tanzania – with no forex conversion. Spin one up in minutes at console.lineserve.net, and if you are brand new, the Getting Started with Lineserve Cloud: Launch Your First VPS guide will get you to a running server. Start small on an S1, add the swap file above as your buffer, and size up to more RAM when the numbers tell you to.
