notes/systems
← index

Notes on cgroup v2 memory accounting

memory.current is not RSS, and reading it as RSS is the source of most cgroup memory confusion.

What is charged

It includes page cache, kernel memory, and socket buffers charged to the cgroup. A process that read a large file has that cache charged to it — which is why a container doing nothing wrong can sit at 90% of its limit and stay there.

memory.current   # everything charged here
memory.stat      # the breakdown - read this one
memory.max       # hard limit; over it means OOM kill
memory.high      # soft limit; over it means throttling

high does not kill, and that is worse

memory.high applies reclaim pressure and stalls the cgroup. There is no kill, no dmesg line, nothing in the logs. It surfaces as latency — requests that used to take 8ms now take 300ms, intermittently, with no error anywhere.

If a workload is mysteriously slow under a limit and dmesg is clean, check whether it is sitting above memory.high. This one costs people days.

Reclaimable is not leaked

Before concluding a leak, read memory.stat and subtract file. Page cache counts toward the limit but will be dropped under pressure. Anonymous memory that keeps climbing is the one worth chasing.