← All 123 books memory pressure, one command per page
One command per page

memory pressure, one command per page

Twenty-eight lessons on memory pressure, one command or file per page: free's six columns, what buff/cache borrows and why available beats free; /proc/meminfo from MemAvailable's parts to Active against Inactive and Dirty against Writeback; ps sorted by RSS, what RSS leaves out, RSS against VSZ and the %MEM sum; vmstat's since-boot first line, the si and so swap columns, the cpu tail and bi and bo; swapon's table, SwapCached's saved IO, vm.swappiness on its 0 to 200 scale and sysctl under /proc/sys; slab in meminfo, slabtop's ranked caches, the dentry rows and drop_caches; and the OOM killer's oom_score, oom_score_adj and dmesg record, one real command per page.


Steve Hodgkiss 7 lessons

One command, one file, one real number. That's a page.

memory pressure, one command per page

Twenty-eight lessons on memory pressure, one command or file per page: free's six columns, what buff/cache borrows and why available beats free; /proc/meminfo from MemAvailable's parts to Active against Inactive and Dirty against Writeback; ps sorted by RSS, what RSS leaves out, RSS against VSZ and the %MEM sum; vmstat's since-boot first line, the si and so swap columns, the cpu tail and bi and bo; swapon's table, SwapCached's saved IO, vm.swappiness on its 0 to 200 scale and sysctl under /proc/sys; slab in meminfo, slabtop's ranked caches, the dentry rows and drop_caches; and the OOM killer's oom_score, oom_score_adj and dmesg record, one real command per page.


Set in Space Grotesk, Inter and JetBrains Mono (SIL Open Font License).

Every fact in this book is as the official source states it, fetched and read during this build: the Linux man-pages man7.org pages for free(1), ps(1), vmstat(8), slabtop(1) and sysctl(8) from procps-ng, dmesg(1) and swapon(8) from util-linux, and proc(5); and the kernel's own Documentation admin-guide/sysctl/vm.rst (swappiness, overcommit_memory, drop_caches, oom_dump_tasks) and filesystems/proc.rst (meminfo, oom_score, oom_score_adj) from kernel.org. No facts are sourced from Reddit, Stack Overflow or vendor blogs. Every command and output pair on every page was run on this machine (procps-ng 4.0.4, util-linux 2.39.3) and confirmed before printing; the drop_caches and oom_score pages present the kernel's documented values as written, for you to run on a box you own. An independent guide, not affiliated with or endorsed by the Linux man-pages maintainers, the procps-ng or util-linux projects, or the Linux kernel developers.

Your purchase is for personal use only. You do not have redistribution rights: please do not share, resell, or republish this book or its pages.

© 2026 Steve Hodgkiss. All rights reserved. Personal use only; no redistribution rights.

Edition 1.0 · stevehodgkiss.net

Contents

Contents


Part 1 · free
free's six columns4
Part 2 · /proc/meminfo
cat /proc/meminfo5
Part 3 · ps
ps sorted by RSS6
Part 4 · vmstat
The si and so columns7
Part 5 · Swap and swappiness
vm.swappiness8
Part 6 · Slab and sysctl
slabtop -o9
Part 7 · The OOM killer
oom_score10

Per Linux man-pages free(1) (procps-ng): free displays the total amount of free and used physical and swap memory in the system, as well as the buffers and caches used by the kernel; the information is gathered by parsing /proc/meminfo; total is total usable memory, used is calculated as total minus available, free is unused memory, shared is mostly tmpfs, buff/cache is the sum of buffers and cache, and available estimates memory for starting new applications without swapping.

memory companion · No. 01
free

free's six columns

One command, the whole picture

total, used, free, shared, buff/cache, availabletotaltotal usable memoryusedtotal minus availablefreegenuinely idlesharedmostly tmpfsbuff/cachebuffers plus page cacheavailablefor new apps, no swapping$ free -hMem: 7.8Gi 2.7Gi 4.2Gi 9.3Mi 1.2Gi 5.0GiSwap: 2.0Gi 512Ki 2.0Gitwo rows, six columns, one fileMem is physical RAM, Swap the overflow disk: free parses /proc/meminfo for both

One command, two rows. The Mem row is physical RAM, the Swap row is the overflow disk, and each names six columns: total, used, free, shared, buff/cache, available.

Our run: 7.8Gi total, 2.7Gi used, 4.2Gi free, 1.2Gi buff/cache, 5.0Gi available. Swap holds a rounding error, 512Ki of 2.0Gi.

Per free(1), every number here is parsed straight out of /proc/meminfo: this row is a view of that file.

RUN IT THIS WEEK

Run free -h, write down your total, buff/cache and available values, and check that used plus free plus buff/cache lands near your total.

Per kernel Documentation filesystems/proc.rst: meminfo provides information about distribution and utilization of memory, varies by architecture and compile options, and some of the counters reported here overlap, so the memory reported by the non overlapping counters may not add up to the overall memory usage. Per Linux man-pages free(1): free gathers its information by parsing /proc/meminfo. This machine's file opens MemTotal: 8131768 kB and reaches Slab: 826244 kB within the first 25 lines.

memory companion · No. 02
meminfo

cat /proc/meminfo

Every counter, one line each

one file, every counter, one kB per line$ head -n 25 /proc/meminfoMemTotal: 8131768 kBMemFree: 4451712 kBMemAvailable: 5251108 kB25 lines in: Slab: 826244 kBmeminfocounters overlap; they do nothave to add up to total usagefree, vmstat and ps are all views onto this file's numbers

One file, every counter: MemTotal, MemFree, MemAvailable, Buffers, Cached and dozens more, one per line, all in kB.

Our head of the file opens MemTotal: 8131768 kB and closes its first screen at Slab: 826244 kB. free, vmstat and ps are all views onto this file.

The docs warn the counters overlap and do not have to add up: read each line as its own claim.

RUN IT THIS WEEK

Run head -n 25 /proc/meminfo, find your MemTotal and MemAvailable lines, and note the kB unit on every line.

Per Linux man-pages ps(1): --sort spec sets the sorting order with the syntax plus or minus followed by a key chosen from the standard format specifiers, and rss is resident set size; the u format displays user-oriented columns including user, pid, pcpu, pmem, vsz, rss and args. This machine's ps aux --sort=-rss run ranks a python3 process first at RSS 943708 kB, a dashboard python second at 930232 and a cron worker third at 344264.

memory companion · No. 03
ps

ps sorted by RSS

Rank the holders, descending

one flag ranks the physical holders, descending$ ps aux --sort=-rssUSER PID %MEM VSZ RSSroot 347475 11.6 3322132 943708root 1902597 11.4 3223044 930232root 2094901 4.2 2168688 344264two interpreters own this box--sort=-rssthe minus sign means descendingrssresident set sizephysical memory held right now,not promised, not virtualthe podium explains the box: sort by rss when the question is who holds memory

One command ranks the eaters: ps aux --sort=-rss. The minus means descending, and the key is rss, resident set size.

Our podium: python3 at 943708 kB, the dashboard python at 930232, a cron worker at 344264. Two interpreters own most of this box's memory.

Sort by RSS, not VSZ, when the question is who is holding physical memory right now.

RUN IT THIS WEEK

Run ps aux --sort=-rss, write down your top three RSS values with their commands, and note what share of your MemTotal they hold.

Per Linux man-pages vmstat(8): si is the amount of memory swapped in from disk per second and so is the amount of memory swapped to disk per second; swpd is the amount of swap memory used, free is idle memory, buff is buffers and cache is cache. In this machine's vmstat 1 5 run every row reports si 0 and so 0 with swpd steady at 512.

memory companion · No. 04
vmstat

The si and so columns

The door to swap, watched

the door to swap: in per second, out per second$ vmstat 1 5swpd free si so 512 4450704 0 0 512 4450704 0 0si 0 so 0: door closedsi: swapped in from disk, /sso: swapped out to disk, /sswpd 512 KiB is residue, not trafficzeros mean swap exists but is not being consulted; sustained nonzeros are thrashing

Two columns watch the door to swap: si, memory swapped in from disk each second, and so, memory swapped out.

Our five rows read si 0, so 0 with swpd steady at 512 KiB: nothing moving. The 512Ki free(1) reported is residue, not traffic.

si and so above zero for rows on end is thrashing's heartbeat; zeros mean swap exists but is not being consulted.

RUN IT THIS WEEK

Run vmstat 1 5, read the si and so columns across all five rows, and say whether your swap door is moving.

Per kernel Documentation admin-guide/sysctl/vm.rst: swappiness defines the rough relative IO cost of swapping and filesystem paging, as a value between 0 and 200; at 100 the VM assumes equal IO cost and will apply memory pressure to the page cache and swap-backed pages equally; lower values signify more expensive swap IO; the default value is 60; at 0 the kernel will not initiate swap until the amount of free and file-backed pages is less than the high watermark in a zone. This machine reports 60, read from /proc/sys/vm/swappiness.

memory companion · No. 05
swap

vm.swappiness

The price of the two ways out

0 to 200: the relative IO cost of the two escapes$ cat /proc/sys/vm/swappiness60the documented defaultread as a file, tunable livethis machine votes 60010020060, this boxequal costlower values: swap IO dearer;0 waits for the high watermarkat 100 the kernel charges swap and page cache the same; 60 is the default vote

swappiness prices the two escapes from pressure. At 100 the kernel treats swap and page cache as equally costly; lower says swap IO is dearer; above 100 says swap is cheaper than the filesystem.

Our value: 60, read straight from /proc/sys/vm/swappiness, and it is the documented default.

At 0 the kernel will not initiate swap until free and file-backed pages fall below a zone's high watermark.

RUN IT THIS WEEK

Run cat /proc/sys/vm/swappiness, place your value on the 0 to 200 scale, and say which side of equal cost it votes for.

Per Linux man-pages slabtop(1): slabtop displays detailed kernel slab cache information in real time, a listing of the top caches sorted by one of the listed sort criteria, with a statistics header filled with slab layer information; -o displays the output once and then exits; the default sort criteria is the number of objects; the information comes from /proc/slabinfo. This machine's slabtop -o run reports Active / Total Objects 2469715 / 2539100, 97.3 percent.

memory companion · No. 06
slab

slabtop -o

Print once, then exit

the slab, ranked: header totals then top caches$ slabtop -oActive / Total Objects (% used)2469715 / 2539100 (97.3%)Active / Total Size (98.5%)nearly every object alive-odisplay once, then exit-s Ssort by criterion Sdefault sort: number of objectsdata from /proc/slabinfo,ranked and totedslabtop is /proc/slabinfo ranked and toted; -o prints the table once and exits

slabtop -o prints once and exits: the header totals, then the top caches ranked by object count.

Our header: 2469715 active of 2539100 objects, 97.3% in use; nearly every allocated slab object is alive.

The same numbers live in /proc/slabinfo; slabtop is that file, ranked and toted.

RUN IT THIS WEEK

Run slabtop -o, write down your Active / Total Objects line, and find which cache holds the most objects on your list.

Per kernel Documentation filesystems/proc.rst, chapter 3: /proc/pid/oom_score displays the current score used by the oom-killer for any given task; the badness heuristic assigns each candidate task a value ranging from 0, never kill, to 1000, always kill, roughly a proportion of the allowed memory the process may allocate from based on an estimate of its current memory and swap use; a task using all allowed memory scores 1000, one using half scores 500; the exported value includes oom_score_adj so it is effectively in range 0 to 2000.

memory companion · No. 07
oom

oom_score

The kill ranking, public

badness: 0 never kill, 1000 always kill05001000neverhalf of allowedalwaysscore is roughly the share of itsallowed memory a task is using/proc/pid/oom_scoreshows the current score, and itincludes oom_score_adj, so itcan read as high as 2000read it before the kernel doesthe ranking is public: check who would die first before the box gets hungry

Every task carries a kill ranking. The badness heuristic scores 0, never kill, to 1000, always kill: roughly the share of its allowed memory a process is using.

Using everything scores 1000; using half scores 500. /proc/pid/oom_score shows the number, and it includes oom_score_adj, so it can reach 2000.

Read oom_score before the kernel enforces it: the ranking is public, per process, all the time.

RUN IT THIS WEEK

Run cat /proc/self/oom_score, then read the same file for your biggest process from ps aux --sort=-rss, and compare the two rankings.

Index

Index


cat /proc/meminfo5
free's six columns4
oom_score10
ps sorted by RSS6
slabtop -o9
The si and so columns7
vm.swappiness8