1. Introduction
Swap is a virtual memory subsystem mechanism for allocating and maintaining a special part of secondary storage as swap space. Swap space acts similarly to a main memory (RAM) extension. In short, the kernel moves or swaps out chunks of data called pages from RAM to secondary storage when not in use for a long time and swaps them back in when requested, resulting in a kind of cache. While swap can be a partition or file, its main setting is the so-called swappiness.
In this tutorial, we’ll talk about swappiness and its current default value in the Linux kernel. First, we go over the general swap strategy of the Linux kernel. After that, we turn to swappiness, what it means, and how to set it. Finally, we explore steps to test the performance of the swappiness setting for a given system.
We tested the code in this tutorial on Debian 11 (Bullseye) with GNU Bash 5.1.4. It should work in most POSIX-compliant environments unless otherwise specified.
2. Swap Strategy
In general, we can split page types into two:
- filesystem pages in the file cache – program contents, program data, shared libraries, and similar
- anonymous pages in anonymous memory – dynamic runtime data like program stack and heap, as well as mmap() allocations
Since it’s already on secondary storage, the filesystem page type doesn’t require swap space. Conversely, anonymous pages are part of volatile memory, so swapping is necessary to preserve this type in certain cases:
+-------------------+ +------------------------------+
| Main Memory (RAM) | Swap Out | Secondary Storage (HDD, SSD) |
+-------------------+ >>>>>>>>> +------------------------------+
| FP1, FP2, ... FPn | (SLRU) | Swap | AP - Anonymous Pages |
| AP1, AP2, ... APn | |------------------------------|
| | Swap In | FP - Filesystem-backed Pages |
+-------------------+ <<<<<<<<< +------------------------------+
Although it isn’t mandatory, having swap increases the choices the kernel has for freeing RAM. Without the feature, we can only free main memory from filesystem-backed pages. On the other hand, having swap space doesn’t mean it will be used.
Still, when there is no swap space, the Linux kernel may need to overcommit memory. In these cases, there is a higher chance of running out of physical memory and having no ability to swap to secondary storage. As a result, the out-of-memory-killer (OOM-killer) mechanism kicks in and kills rogue processes.
Thus, it’s often good to have even a small amount of swap and reduce swapping rather than none at all.
3. Swappiness
According to the official kernel virtual memory subsystem documentation, the swappiness setting is a value between 0-200 that determines how often the kernel swaps memory pages:
- high swappiness = more frequent swaps
- low swappiness = less frequent swaps
In other words, the setting decides whether the kernel will swap out more filesystem-backed (lower swappiness) or more anonymous (higher swappiness) pages. So, configuring the minimum swappiness of 0 means the kernel would wait until it has no choice but to swap, which may result in thrashing or the aforementioned OOM-killer activation. The maximum swappiness value is 200.
3.1. Swappiness Settings
Apart from the swap statistics in /proc/meminfo, like huge pages and others, we can check and set a number of general configuration options in /proc.
For instance, /proc/sys/vm/swappiness shows us the current swappiness value:
$ cat /proc/sys/vm/swappiness
60
Here, we see the default swappiness value of 60.
Of course, we can change the swappiness setting directly in the swappiness file or via sysctl:
$ sysctl vm.swappiness=10
vm.swappiness = 10
In this case, we changed the swappiness to 10.
3.2. Filesystem-Backed and Anonymous Page Priority
In the context of swap, anonymous page priority coincides with the default swappiness of 60, while file-cached pages have a default priority of 200 minus the swappiness value:
+------------------------------------------------------------------+
| Swappiness | Anonymous Page Priority | File-Cached Page Priority |
|------------+-------------------------+---------------------------|
| 60 | = Swappiness = 60 | = 200 - Swappiness = 140 |
+------------------------------------------------------------------+
This means both priorities added together make up the maximum value of swappiness 200, with anonymous pages getting swapped less often by default.
Thus, vm.swappiness = 100 makes both page type priorities equal, adequate for systems with a high amount of secondary storage usage. Conversely, vm.swappiness = 0 usually relies on software that does its own caching, like database servers.
Indeed, it’s always a tradeoff since less swapping means more interactivity but worse input-output performance and vice-versa.
3.3. Choosing Swappiness
The value choice for vm.swappiness depends on many factors, mainly having to do with the type of system and its usage:
- virtual machine
- desktop
- web server
- database server
- secondary storage usage
- main memory usage
- amount of RAM
In a way, swappiness decides how much we fill the cache versus the number of swap-outs we perform. The default swappiness value aims to unburden the system from constant swapping while still enabling the feature to aid our activities.
In any case, we need hard data to support our choice for vm.swappiness.
4. Test Swappiness Settings
While swappiness values should stem from the intended use of a given system, we could perform a general test:
- use malloc() to take up around 90-95% of main memory and hold it
- start writing about 60% of the data to secondary storage in parallel by, e.g., using dd to dump from /dev/zero
- once ready with the previous step, note down swap usage, page cache usage, and run times
- reset by killing malloc(), removing the dd dumps, and clearing the swap
- repeat for several trials
By switching up the swappiness value and performing the steps above, we can get an idea of the raw system performance with regard to swap. On the other hand, by changing the test procedures from a pure dump to a complex set of operations, we can gain some insight into our particular system’s behavior in relation to vm.swappiness.
5. Summary
In this article, we discussed one of the main swap settings – swappiness.
In conclusion, although there is a sane default and we can change it easily, the value of swappiness should be chosen carefully on a per-system basis to avoid adverse effects.