Back to the map

Module 06 · Memory management · Lesson 4 of 8

Swapping and thrashing

What happens when memory runs short: page replacement, the page cache competing with process memory, swap, and the cliff where a system spends all its time moving pages instead of working.

CoreShould-knowMid 11 min Updated Nov 2026

Why it matters

A server running out of memory rarely fails cleanly. First it slows down, sometimes by orders of magnitude, as the kernel shuffles pages between memory and disk; then something gets killed. Understanding page replacement, the page cache and thrashing explains why a database slows dramatically when its working set grows past RAM, why many server fleets run without swap, and how to read memory pressure before it becomes an outage.

The idea

Physical memory holds two broad kinds of pages: anonymous pages (heap and stack, with no file behind them) and file-backed pages (the page cache: file contents, executables, memory-mapped files). When free memory runs low, the kernel reclaims pages. Clean file-backed pages can simply be dropped, since they can be re-read from the file. Dirty file pages must be written back first. Anonymous pages have nowhere to go unless there is swap, a disk area where they can be written and later read back.

Choosing what to evict

The ideal policy evicts the page that will be used furthest in the future, which is impossible to know. Real kernels approximate least recently used: the hardware sets an accessed bit on use, and the kernel periodically scans and clears those bits. The clock (second-chance) algorithm sweeps pages in a circle, evicting the first whose accessed bit is clear and clearing the bits it passes. Linux keeps active and inactive lists (and newer multi-generational LRU) for anonymous and file pages, promoting pages that are used repeatedly and evicting from the inactive tail. This is the same family of ideas as cache eviction in the System Design track, applied to RAM.

Working sets and thrashing

A process's working set is the set of pages it actively uses over a short window. As long as the working sets of all running processes fit in RAM, page replacement only evicts cold pages and costs little. When they do not fit, every eviction removes a page that will be needed again soon, every access to it is a major fault, and the system spends its time moving pages between RAM and disk rather than computing: thrashing.

total working-set size →fits in RAM: steadythrashingRAM size
Throughput versus memory demand. Below the working-set size of physical RAM, performance is flat; past it, major faults multiply and useful work collapses.

On a disk, a major fault costs milliseconds against a memory access of 100 nanoseconds, a ratio of tens of thousands. Even a small fraction of accesses faulting can multiply latency. NVMe narrows the gap but does not close it.

Swap on servers

ConfigurationBehaviour under memory pressureFits
No swapAnonymous memory cannot be evicted; once the page cache is squeezed, the OOM killer acts quicklyLatency-sensitive fleets that prefer a fast kill and restart over a slow death; many Kubernetes nodes
Small swap, low swappinessCold anonymous pages (startup code, idle data) can move out, freeing RAM for cache; heavy pressure still ends in OOMGeneral servers; gives the kernel room to manage memory well
Large swapThe system degrades gradually and may thrash for a long time before anything is killedDesktops, batch machines where finishing slowly beats being killed
zram / zswapCompressed swap in RAM; much faster than disk, trades CPU for capacityMemory-constrained devices and some servers

Linux's swappiness setting biases reclaim between dropping file pages and swapping anonymous ones. Container platforms add cgroup memory limits, so pressure and OOM kills happen per container before the whole machine is affected.

Seeing pressure early

Free memory alone misleads, because Linux uses spare RAM for the page cache and reports it as used. Better signals: available memory (free plus easily reclaimable cache), the major page fault rate, swap-in and swap-out rates (vmstat's si and so columns), and pressure stall information (PSI): the share of time tasks are stalled waiting on memory, per system and per cgroup, which tools like systemd-oomd and Kubernetes can act on before thrashing sets in.

Trade-offs

Swap lets the kernel move genuinely cold pages out of RAM and absorb short spikes, and it can also turn an out-of-memory crash into hours of thrashing. No swap makes failure fast and visible and wastes RAM on cold pages. The page cache makes file I/O fast by using idle memory and competes with application memory under pressure. The right setting depends on whether you would rather be slow or be killed.

In an interview

Connect memory sizing to the working set: "The database's working set, the hot indexes and rows, must fit in its buffer pool plus page cache; past that, every query hits disk and latency multiplies. We alert on major fault rate and memory PSI, not just used memory, and run without swap on latency-critical nodes so a leak ends in a quick restart rather than a slow brownout."

Check yourself

A server with 64 GB of RAM shows 'used' memory at 62 GB, yet applications are fast, major page faults are near zero and there is no swap activity. Is it in trouble?

Swapping and thrashing · Backplane