how much swap makes sense and what vm.swappiness really controls
Too little swap leads to crashes from the out-of-memory killer during load spikes, too much swap hides a real memory shortage behind agonizing slowness. This article shows how much swap actually makes sense on a modern server, how the vm.swappiness kernel parameter controls swapping behavior, how to safely create a swapfile, and how to tell real memory pressure apart from normal caching.
Table of Contents
- 1. Swap in the context of modern servers
- 2. How much swap makes sense today
- 3. vm.swappiness: what the parameter really controls
- 4. Creating and enabling a swapfile
- 5. Swap partition versus swapfile
- 6. Observing swap usage: free, vmstat, /proc/meminfo
- 7. When swapping is normal and when it is not
- 8. Zram and zswap as a modern complement
- 9. Swap configuration head to head
- 10. Summary
- 11. FAQ
1. Swap in the context of modern servers
Swap is an area on disk or SSD that the Linux kernel uses as an extension of physical memory. When RAM gets tight, the kernel moves rarely used memory pages there, freeing space for active processes. In an era of servers with 64 or 128 GB of RAM and fast NVMe SSDs, that sounds like a relic from the days of expensive memory, but swap actually remains an important safety net on modern systems too.
Without swap, a memory shortage immediately triggers the kernel's out-of-memory killer, which terminates processes hard, often the very one consuming the most memory and therefore the most important service. With enough swap, the system buys valuable seconds to absorb brief load spikes, for example during a backup run, a cache warmup, or a memory leak that has not yet been noticed. Swap is also a prerequisite for hibernation, where the entire contents of memory are written to disk before shutdown. The real skill lies not in whether swap is enabled, but in how much and with what behavior.
2. How much swap makes sense today
The old rule of thumb, twice the RAM size as swap, dates from a time when memory measured in single-digit gigabytes and swapping happened frequently. On a modern server with 32 GB or more of RAM, that rule would demand a 64 GB swapfile that in practice is almost never fully used and just wastes disk space. Distributions like Red Hat and Ubuntu now recommend tiered values instead: double the RAM as swap up to 2 GB of RAM, a swap size equal to RAM between 2 and 8 GB of RAM, and above that 4 to 8 GB is usually enough as a safety net, provided hibernation is not used.
Anyone who needs hibernation must plan swap to be at least as large as RAM plus a buffer for kernel state, since the entire memory contents have to fit inside it. Database servers with heavy page cache needs often benefit from little to no swap combined with a low swappiness value, while application servers with many short-lived processes benefit from a somewhat larger buffer. Sizing is therefore always a function of RAM size, workload type, and whether hibernation is relevant at all.
# cloud-init: automatically create a swapfile on first boot
# Useful for cloud VMs where the base image ships without swap
swap:
filename: /swapfile
size: "4294967296" # 4G in bytes, or "auto" to let cloud-init decide
maxsize: "4294967296"
3. vm.swappiness: what the parameter really controls
The kernel parameter vm.swappiness controls how strongly the kernel favors swapping out anonymous memory pages over reclaiming page cache entries when both are possible. The value historically ranges from 0 to 100 and was extended up to 200 starting with kernel 5.8 to allow even more aggressive swapping. The default is usually 60, a compromise designed for desktop systems, not specialized server workloads.
A common misconception: swappiness is not a percentage threshold at which swapping starts, but a relative weighting between two reclaim strategies of the kernel. A value of 0 does not mean the kernel never swaps, only that it favors page cache for as long as possible and only falls back to swap as a last resort. A value of 100 means anonymous and file-backed pages are treated as equally worth reclaiming. For database servers like MySQL or PostgreSQL, whose performance depends heavily on page cache, a low value between 1 and 10 is recommended. Systems with plenty of free RAM and infrequent load spikes can safely leave the default unchanged.
# /etc/sysctl.d/99-swappiness.conf
# Lower swappiness favours page cache over swapping anonymous pages
vm.swappiness = 10
# Reduce cache pressure so directory/inode caches survive memory pressure longer
vm.vfs_cache_pressure = 50
# Reserve a small watermark so the kernel starts reclaiming before OOM
vm.min_free_kbytes = 65536
After creating the file, the configuration is loaded with sysctl --system, no reboot required. Important: changes made via sysctl vm.swappiness=10 on the command line only last until the next reboot. To make the setting permanent, it must live in a file under /etc/sysctl.d/.
4. Creating and enabling a swapfile
A swapfile can be set up without a reboot and without partitioning, which makes it the preferred method on cloud instances and container hosts. The first step is reserving the space with fallocate, which on most filesystems is considerably faster than dd, because no zeros actually need to be written. On Btrfs, however, fallocate does not work reliably for swapfiles, so dd with bs=1M must be used instead, since copy-on-write and swap files fundamentally do not mix and require their own no-copy-on-write attribute handling.
After reserving the space, file permissions must be set to 600 so no other user can read the potentially sensitive memory contents. Then mkswap formats the file with the swap signature, and swapon enables it immediately for the running session. For the swap file to remain active after a reboot, an entry must be added to /etc/fstab. A final check with swapon --show and free -h confirms that the kernel has actually recognized the new swap area and that it is available.
#!/usr/bin/env bash
# Reserve 4G, prefer fallocate (instant), fall back to dd on Btrfs
sudo fallocate -l 4G /swapfile || sudo dd if=/dev/zero of=/swapfile bs=1M count=4096
# Restrict permissions before the swap signature is written
sudo chmod 600 /swapfile
# Write the swap signature and enable it for the running session
sudo mkswap /swapfile
sudo swapon /swapfile
# Persist across reboots
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab
# Verify the kernel sees the new swap area
swapon --show
free -h
5. Swap partition versus swapfile
The swap partition used to be the only recommended option, because swapfiles on fragmented filesystems could theoretically be slower and older kernels only supported swap files with limitations. Over the last several kernel releases this performance gap has become practically unmeasurable on SSDs and NVMe storage, which is why modern distributions like Ubuntu have created a swapfile instead of a partition by default since version 17.04.
The decisive advantage of a swapfile is flexibility: its size can be changed at any time with swapoff, resizing the file, and swapon again, without touching the partition table or repartitioning the system, which is practically impossible for a partition without moving data around. Cloud images and container base systems typically offer no dedicated swap partition at all for exactly this reason. A swap partition still makes sense when a system runs full-disk encryption and needs reliable suspend-to-disk, since some bootloader configurations require a partition for the resume process. For the vast majority of server scenarios, a swapfile is the more pragmatic choice today.
6. Observing swap usage: free, vmstat, /proc/meminfo
The raw number of how much swap is currently used is, on its own, not very informative. Far more informative are the swap in and swap out rates that vmstat 1 shows in the si (swap in) and so (swap out) columns per second. If these values show sustained activity over multiple seconds, the kernel is actively shuffling pages back and forth, which points to real memory pressure. A one-off spike at boot time or after a large batch job, on the other hand, is unremarkable.
The command free -h gives a quick overview of used, free, and cached memory as well as current swap usage, while /proc/meminfo, with the fields SwapTotal, SwapFree, and SwapCached, provides the raw data for custom monitoring scripts. SwapCached is particularly interesting: it shows pages that exist both in RAM and in swap and can be reclaimed on demand without a disk access. For historical trends, sar -S from the sysstat package is useful, logging swap usage over time and allowing retrospective analysis over days or weeks without needing an external monitoring system.
# Live swap in/out activity, columns si and so (KB per second)
vmstat 1 5
# Quick overview: used, free, cached memory and current swap usage
free -h
# Raw kernel counters for custom monitoring scripts
grep -E 'SwapTotal|SwapFree|SwapCached' /proc/meminfo
# Historical swap usage trend (requires the sysstat package)
sar -S 1 10
7. When swapping is normal and when it is not
A widespread misconception says: swap is being used, so the server must be short on RAM. That is wrong as a blanket statement. The kernel proactively swaps out rarely used anonymous pages to make more room for page cache, which speeds up file access. A moderately filled swap area combined with a low si/so rate in vmstat is normal, healthy behavior and no cause for concern.
A real problem exists when si and so show sustained high values, the load average rises even though CPU utilization itself stays low, and iowait time in top or mpstat increases noticeably. This pattern is called thrashing: the kernel keeps swapping pages out and back in instead of doing productive work, and the system's perceived responsiveness drops noticeably. Since kernel 4.20, Pressure Stall Information under /proc/pressure/memory provides an even more precise signal than vmstat: the full value shows what percentage of the time all tasks were simultaneously waiting on memory, a direct indicator of real memory pressure rather than mere interpretation of raw counters.
{
"check": "swap_pressure",
"interval_seconds": 30,
"thresholds": {
"swap_used_percent_warn": 60,
"swap_used_percent_crit": 90,
"vmstat_si_so_sustained_kb_s": 500,
"pressure_memory_full_percent": 10
},
"action": {
"warn": "log",
"crit": "page_oncall"
}
}
8. Zram and zswap as a modern complement
Zram and zswap address the same underlying problem from two different angles: both use compression to increase the effective capacity of memory before anything is swapped out to slower storage at all. Zram creates a compressed block device directly in RAM that is mounted as a full-fledged swap device. Since compression and decompression are considerably faster than access to a hard disk or even an NVMe SSD, zram is particularly well suited to systems with little RAM, such as small cloud instances or containers with tight memory limits.
Zswap works as a compressed cache in front of the actual swap device: pages are first held compressed in RAM and only written permanently to disk once memory pressure persists. This combines the speed of zram with the practically unlimited capacity of a classic swapfile as a fallback. The trade-off for both approaches is CPU time spent on compression, which has to be weighed against the savings in I/O wait time on systems with scarce CPU resources. On modern multi-core servers, the benefit outweighs the cost in practice almost always, especially for workloads with many small, well-compressible memory pages.
9. Swap configuration head to head
The choice between a swapfile, a swap partition, zram, and a minimal or nonexistent swap configuration depends heavily on the specific use case. There is no single correct answer, only the right combination of workload type, available RAM, and failure tolerance. The following table lays out typical misconfigurations against the recommended settings and shows why each choice makes a practical difference.
| Scenario | Wrong Setting | Recommended Setting |
|---|---|---|
| Database server (MySQL, PostgreSQL) | vm.swappiness = 60 (default) | vm.swappiness = 1 to 10, small swapfile as a safety net |
| Cloud VM with 1 to 2 GB RAM | No swap configured | Zram or a 2 to 4 GB swapfile against OOM kills |
| Full-disk encryption with hibernation | Swapfile without resume support | Encrypted swap partition with matching resume configuration |
| Monitoring and alerting | Alert on SwapUsed greater than 0 | Alert on sustained high si/so rate or PSI full above threshold |
| Container host with many small pods | Generous 32 GB swapfile | Zram per namespace or cgroup memory limits instead of swap |
| Btrfs root filesystem | fallocate for the swapfile | dd + chattr +C (no-copy-on-write) before creating it |
In practice, a short checklist before every deployment provides the most safety: know the workload type, set swappiness deliberately instead of leaving the default, size the swap area to match RAM and hibernation needs, and point monitoring at swap in/out rates rather than raw swap occupancy.
Mironsoft
Server tuning, kernel configuration, and performance monitoring
Servers that don't collapse into thrashing under load?
We analyze memory behavior, size swap to match the workload, set vm.swappiness for production, and set up monitoring that tells real memory pressure apart from normal caching.
Memory audit
Systematically reviewing swap configuration, swappiness, and OOM history
Kernel tuning
Configuring vm.swappiness, zram, and zswap to match each workload
Monitoring setup
Alerting on si/so rates and PSI values instead of raw swap occupancy
10. Summary
Swap is not a relic on modern servers, but a deliberately configurable safety net against the out-of-memory killer and brief load spikes. The right size follows from RAM capacity, workload type, and whether hibernation is needed, not from the blanket doubling rule of past decades. The kernel parameter vm.swappiness controls the relative weighting between page cache and anonymous pages and should be deliberately set to a low value for database servers instead of staying at the default of 60. A swapfile can be set up in a few minutes without a reboot using fallocate, mkswap, and swapon, and on most systems it is now on par with a swap partition.
For diagnosis, what matters is not the absolute swap occupancy but the swap in and out rate in vmstat as well as the PSI signal under /proc/pressure/memory. Moderate swap usage with a low si/so rate is normal kernel caching behavior, while sustained high rates alongside a rising load average signal real thrashing and acute memory pressure. Zram and zswap offer a faster alternative or complement to classic disk-based swap on memory-constrained systems, using compression before anything is ever swapped out to slower storage.
Configuring Swap and Swappiness: the essentials at a glance
Swap size
No longer a blanket double the RAM. Double up to 2 GB RAM, equal size up to 8 GB RAM, above that 4 to 8 GB as a safety net, provided hibernation is not needed.
vm.swappiness
The default of 60 rarely fits server workloads. Database servers benefit from values between 1 and 10 that consistently favor page cache.
Setting up a swapfile
fallocate, chmod 600, mkswap, swapon, and an entry in /etc/fstab are enough for a permanent configuration with no reboot.
Diagnosis over panic
si/so rates in vmstat and PSI under /proc/pressure/memory show real memory pressure, not raw swap occupancy.