The /proc/pid/smaps PSS Field: The Only Honest Answer to "How Much Memory Is My Process Using?"

2026-09-06

Ask top how much memory a process uses and you get four numbers, all wrong. VSZ counts address space you'll never touch. RSS counts pages you share with 200 other processes as if they were yours alone. Neither is what you actually want, which is: if this process died right now, how much RAM would the kernel reclaim?

PSS (Proportional Set Size) is that number. For every physical page a process maps, the kernel divides it by the number of processes sharing it and gives each process its fair share. A page mapped by 4 processes contributes 1 KB of PSS to each, not 4 KB of RSS to each. Sum the PSS of every process on the system and you get, almost exactly, the physical RAM in use.

It lives in /proc/<pid>/smaps, one block per VMA:

Concrete example. Fork a process that has mapped 100 MB of glibc code. Right after fork, RSS on the parent still shows 100 MB, RSS on the child shows 100 MB — total 200 MB reported, but the kernel only has 100 MB of physical pages allocated (copy-on-write). PSS correctly shows 50 MB on each. Now spawn 40 workers of a Python service, each importing 300 MB of shared libraries and .pyc pages: RSS suggests 12 GB used, PSS says 300 MB shared + ~50 MB private each ≈ 2.3 GB total. That's the difference between "buy a bigger box" and "you're fine."

Rule of thumb. For capacity planning use PSS. For "will this one process OOM by itself" use RSS (that's what the OOM killer scores against, ignoring shared pages it can't reclaim by killing you). For "how much can I actually get back" use Private_Dirty — clean pages can be dropped and re-read, but dirty private pages must be swapped or kept.

The catch. Reading smaps is expensive: the kernel walks every page table entry in every VMA and takes mmap_lock for read. On a 100 GB process this can take hundreds of milliseconds and stall page faults in that process. Use /proc/<pid>/smaps_rollup instead — same numbers, aggregated in-kernel, ~50× faster. Since Linux 4.14, this is what any sane monitoring agent should be reading.

Key Takeaway: RSS double-counts shared pages across processes; PSS divides each page by its sharer count, making it the only per-process memory number that sums to the truth — read it cheaply from smaps_rollup.

All newsletters