Linux memory management: free, vmstat, and /proc
When someone says “my server is out of memory,” the first question is: are you sure? Linux memory reporting is confusing because Linux actually uses almost all available RAM — for caches. That’s normal and good. Understanding the difference between “used” and “available” is the key to reading memory stats correctly.
Reading free correctly
free -h
Output:
total used free shared buff/cache available
Mem: 15Gi 8.2Gi 1.1Gi 256Mi 6.1Gi 6.5Gi
Swap: 2.0Gi 0.0Gi 2.0Gi
The columns that matter:
- total — total installed RAM
- used — memory actively used by processes
- free — completely unused memory
- buff/cache — memory used for buffers and page cache
- available — memory available for new applications (free + reclaimable cache)
The free column looks scary (1.1Gi out of 15Gi), but that’s fine. Linux caches aggressively. The available column (6.5Gi) is what actually matters.
The old “free + buff/cache = available” mental model helps. The kernel can drop caches instantly when an application needs memory.
The page cache
When Linux reads a file, it caches the contents in RAM. Subsequent reads are served from cache (fast) instead of disk (slow). This is why buff/cache is usually large.
Check cache effectiveness:
vmstat -s | grep cache
If the system has been running for a while and cache is large, that’s healthy. The system is reusing memory efficiently.
vmstat: real-time memory and CPU
vmstat 1 5
Output:
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
1 0 24576 452864 234560 6144000 0 0 12 45 234 567 12 3 84 1 0
Memory columns (in KB):
- swpd — swap used
- free — idle memory
- buff — buffer cache
- cache — page cache
Swap columns:
- si — swap in (pages read from swap)
- so — swap out (pages written to swap)
If si and so are consistently non-zero, you’re swapping.
CPU columns:
- us — user time
- sy — system time
- id — idle
- wa — I/O wait
- st — stolen (VM only, time given to hypervisor)
High wa means the system is waiting on disk I/O. High st means the VM host is overcommitted.
/proc/meminfo
The raw data behind free:
cat /proc/meminfo
Key fields:
MemTotal— total usable RAMMemFree— completely unusedMemAvailable— estimated available (whatfreeshows as “available”)Buffers— raw block device cacheCached— page cacheSwapTotal— total swapSwapFree— free swapDirty— memory waiting to be written to diskSlab— kernel data structures cache
per-process memory
Memory usage per process:
ps aux --sort=-%mem | head -10
More detailed:
cat /proc/PID/status | grep -i mem
VmRSS— physical memory usedVmSize— virtual memory size (includes shared libraries, mapped files)
For a human-readable per-process view:
smem -tk
Install with sudo apt install smem.
The OOM killer
When the system runs completely out of memory (including swap), the kernel’s OOM killer terminates processes to free memory. It targets the process using the most memory.
Check OOM events:
dmesg | grep -i "out of memory"
journalctl -k | grep -i "oom"
To protect critical processes from OOM:
echo -1000 > /proc/PID/oom_score_adj
This makes the process very unlikely to be killed. Set it in the service file:
[Service]
OOMScoreAdjust=-1000
To make a process more likely to be killed:
echo 1000 > /proc/PID/oom_score_adj
Memory limits with cgroups
Control memory per service:
[Service]
MemoryLimit=512M
Or with systemd’s newer directives:
[Service]
MemoryMax=512M
MemoryHigh=400M
MemoryHigh throttles the process when it exceeds the limit. MemoryMax is a hard limit — the OOM killer activates if exceeded.
Common mistakes
Panic over low “free” memory. Low free is normal. Linux caches aggressively. Check available instead.
Ignoring swap usage. A little swap is fine. Consistent heavy swapping means you need more RAM.
Not monitoring over time. A snapshot of free shows the current state. Use vmstat 1 to see trends. Memory issues are often gradual.
Killing processes based on VmSize. VmSize includes shared libraries and mapped files. RSS is closer to actual physical memory usage.
Remarks
Linux memory management is designed to use RAM efficiently, which means most of it is always “in use” for caches. Don’t panic at low free numbers. The available column in free -h is your real indicator. For monitoring, vmstat shows trends, ps aux shows per-process usage, and the OOM killer is the last resort when everything else fails. Set up monitoring that alerts on available dropping below a threshold, not on free.
Related Posts
Vim survival guide for Linux admins
The minimum vim knowledge you need to survive on a Linux server. Editing config files without wanting to throw your keyboard.
tmux: terminal multiplexing made simple
Using tmux to manage terminal sessions. Panes, windows, and why your SSH sessions should survive disconnects.
Managing SSL certificates with Let's Encrypt
Getting free SSL certificates with Let's Encrypt and certbot. Installation, renewal, and troubleshooting.