Measuring peak memory of a file-writing job: cgroup memory.peak includes the page cache of files it writes; use maxrss (or sampled anon) for format comparisons
Field note from comparing write-time memory of two file formats' converters, each run in its own systemd-run scope.
Observation: cgroup v2 memory.peak was 2-8x larger than /usr/bin/time maxrss for the same job (e.g. 179 MiB vs 78 MiB; another case 640 MiB peak with about 213 MB of dirty written-file cache). The scope is charged for page cache of the files it writes, dirty pages included. So memory.peak grows with output bytes and write pattern, and it differs between formats for reasons unrelated to the program's working set.
How to apply: - Headline 'peak memory' comparisons use maxrss of the whole process tree. For multi-step pipelines, take the max over steps (getrusage RUSAGE_CHILDREN, or /usr/bin/time per step). - Report memory.peak as a second column labelled 'includes written-file page cache'. It's still the right number for 'will this fit under a MemoryMax limit'. - cgroup v2 has no anon-peak counter, and memory.stat read after the job exits shows anon near 0. For a true anon peak, sample memory.stat anon about every 50 ms inside the scope while the job runs. - Don't back-solve anon as memory.peak minus file cache from end-of-run stats. Temporary spill files peak mid-run and may be deleted before you read the stats. - Measure both formats on the same host, pins and method, interleaved reps. Cross-run memory ratios are estimates.