The server isn't responding, SSH takes several seconds to open, and dmesg has a line like Out of memory: Killed process 21834 (mysqld) sitting in it. Or the opposite: you run free -h and see that swap is completely full while the CPU is idle and everything is slow. These two situations have the same symptom but not the same solution. The right decision is to first figure out which one you have.
First, see whether you actually have a memory shortage or not
Before making any change, get numbers. These three commands give you the full picture:
free -m
vmstat 1 5
cat /proc/meminfo | grep -E 'MemAvailable|SwapTotal|SwapFree'
In the vmstat output, two columns matter: si and so (swap in/out in kilobytes per second). If these two numbers stay consistently above zero, the system is thrashing between RAM and disk, and every disk operation costs several times more. If si and so are zero and only SwapUsed is high, that swap is dead; pages that were pushed out once and nobody is looking for them. That state isn't a problem.
A point many people miss: the old free shows the buff/cache column separately and you think RAM is full. The correct metric is MemAvailable, not MemFree. The kernel frees disk cache whenever it's needed.
Adding a swap file; the method that works on a VPS
On machines that don't already have a swap partition (most VPSs), a swap file is the fastest way. For a 2 GB server, a 2 GB file is a reasonable starting point:
fallocate -l 2G /swapfile
chmod 600 /swapfile
mkswap /swapfile
swapon /swapfile
echo '/swapfile none swap sw 0 0' >> /etc/fstab
Don't forget the fstab line; otherwise after a reboot everything goes back to how it was and you think the settings didn't work. To check: swapon --show and free -h.
A practical warning: on some filesystems (like old XFS or overlayfs in containers) fallocate creates a file that won't work as swap. If swapon gives the error swapon failed: Invalid argument, create it with dd:
dd if=/dev/zero of=/swapfile bs=1M count=2048 status=progress
If you're working on cloud infrastructure and the system disk is a network type, swap on that same disk is almost useless because its IOPS are shared and low. In this case you either need to use a cloud server with local NVMe disk, or go for servers that have dedicated disks.
swappiness; the number everyone sets wrong
The default value of vm.swappiness in today's kernels is 60. This number isn't a percentage; it's a weight that says how willing the kernel is to push out unused pages versus freeing file cache. A value of zero means "swap as little as possible" and not "never swap".
sysctl vm.swappiness=10
echo 'vm.swappiness=10' >> /etc/sysctl.d/99-swap.conf
On a database server, 10 is reasonable. On a web server with variable traffic, 20 to 30 works better because it lets file cache stay alive. Only set zero when you really know what you're doing; the result is that when RAM runs out, the kernel goes straight to the OOM Killer instead of swapping.
There's another parameter that few people go after: vm.vfs_cache_pressure. If slabtop shows that dentry and inode_cache are taking up a large amount of RAM, lowering this value to 50 helps the kernel free these caches later.
This is where they go wrong
The most common mistake I see is this: the server gets slow, the admin creates an eight-gigabyte swap file, free goes green and the problem is "solved". Two weeks later the same server comes back with a load of 40 and response latency of several seconds, but this time there's no OOM line in the log.
The sign is exactly this: iostat -x 1 shows disk %util near 100, si and so in vmstat keep going up and down, and database response time has gone double-digit. Swap hasn't solved anything here; it has just put a slow disk layer between the application and memory so the problem explodes later. If your memory usage is growing continuously, the problem is a memory leak in the application, not a RAM shortage.
Second mistake: putting swap on the same disk the database is on. Every page that gets swapped creates competing I/O with database queries. If you have to, put swap on a separate disk.
How much swap should there be
| Case | Recommended size | Reason |
|---|---|---|
| Web server with low RAM (1 to 2 GB) | Equal to RAM or double | Prevent OOM at traffic peaks |
| Dedicated database server | 1 to 2 GB, fixed | Only for cold pages; more than this is dangerous |
| Machine with lots of RAM (32 GB and up) | 2 to 4 GB | Large swap on these machines only gives an illusion of safety |
| Container or shared VPS | According to provider limits | Extra swap can fill up the disk quota |
The old rule "double the RAM" comes from the era of 512 MB RAM and is wrong today. On a 64 GB machine, 128 GB of swap is of no use and just eats disk space.
When swap doesn't help
If after all these settings si/so still stay high, the problem is capacity, not settings. You have three options: increase RAM, reduce usage (for example limiting innodb_buffer_pool_size or pm.max_children in PHP-FPM), or move the load to another machine. Before any of these, look at the output of ps aux --sort=-rss | head -20 to know which process is really eating memory.
If you have high load but aren't sure whether its source is memory, I/O, or CPU, the guide diagnosing the cause of high server load shows the correct order of investigation. For servers with heavy and steady load, a dedicated server with enough RAM usually costs less than any swap trick.
One last point about stability: if you're enabling swap on your server, make sure critical services like MySQL and Redis are configured so that under memory pressure they aren't the first to be sacrificed. Setting OOMScoreAdjust in the systemd unit file of the service, or oom_score_adj in /proc/<pid>/, gives you this control. Without this, the kernel might kill your database and keep the web server alive; exactly the opposite of what you want.
Frequently asked questions
Does having swap enabled make the server slow?
Swap itself isn't slow; active use of it is slow. If vmstat shows si and so near zero, swap is only holding unused pages and has no effect on performance. The problem starts when the system is constantly moving back and forth between RAM and disk.
What's a good vm.swappiness value for a database server?
For MySQL or PostgreSQL, 10 is usually a good value. If you set zero, the kernel goes straight to the OOM Killer instead of swapping and you might lose the database process. The default value of 60 is also usually too aggressive on a database server.
How do I know whether I have swap or not?
The swapon --show command lists active swap files and partitions. If the output is empty, you don't have swap. The free -h command also gives the total and used amount on the Swap line.
Can I remove swap without rebooting?
Yes. First run swapoff /swapfile, then remove the relevant line from /etc/fstab and delete the file. Just be careful that if memory usage is near the RAM ceiling, swapoff can cause an immediate OOM. Before that, make sure with free -m that you have enough space.