In this article
A container can slow down substantially while remaining alive and never reporting OOM. In cgroup v2, memory.high applies pressure through reclaim and allocation throttling; memory.max establishes a separate hard boundary. A healthy process count therefore does not rule out a system memory constraint.
A container can slow down substantially while remaining alive and never reporting OOM. In cgroup v2, memory.high applies pressure through reclaim and allocation throttling; memory.max establishes a separate hard boundary. A healthy process count therefore does not rule out a system memory constraint.
Locate the actual process cgroup
Record the host PID of the worker and inspect its entry in /proc/PID/cgroup. Resolve that entry against the unified hierarchy. The path seen inside a container can differ from the host view because a cgroup namespace hides part of the hierarchy. Diagnose the effective configuration rather than an old launch manifest. Keep the kernel version, runtime and observation time alongside the path so that migration or recreation does not mix two different environments.
Compare four files over time
Read memory.current, memory.high, memory.max and memory.events within the same observation window. Event counters are cumulative: a large value alone cannot establish that throttling is happening now. Capture a before and after snapshot around the reproducible slowdown. memory.events includes hierarchical events; memory.events.local helps separate local activity from descendants. Inspect ancestor groups as well, since an ancestor can enforce a constraint even when the child container appears to have available headroom.
Work through a small example
In an illustrative case, a worker has memory.max set to 12 GiB and memory.high set to 8 GiB. While processing a dataset, memory.current stays around 9 GiB, high increases and oom_kill remains unchanged. That pattern is compatible with reclaim pressure at the high boundary. It is an example, not a benchmark from any hosting platform. Correlating memory.pressure and process latency in the same window provides the next piece of evidence.
| Observation | Next investigation |
|---|---|
| high increases | Reclaim and pressure in the effective hierarchy |
| oom_kill increases | Terminated processes and the memory.max boundary |
| Counters stay unchanged | Other causes, including CPU limits and networking |
Change one boundary at a time
Once the mechanism is confirmed, compare the working dataset with the assigned budget. Reduce the amount of concurrent work or adjust memory.high within an agreed host memory allowance. Raising high to max removes an early pressure boundary and changes how neighboring workloads are affected. Cache and reclaimed pages may change gradually, making an immediate snapshot a poor description of steady behavior. Disabling OOM protection is not a substitute for establishing what actually exhausted the budget.
Define recovery evidence
Repeat the same workload with the same inputs and record duration, the increase in high, oom_kill and PSI. Recovery means the identified constraint has stopped causing unacceptable stalls without moving pressure onto the host. Preserve the cgroup path, previous values and rollback procedure. This record helps explain a recurrence after a runtime upgrade, especially if the replacement container was placed beneath a different ancestor group.
Compare the same small operation after an idle period and during confirmed pressure. Use event deltas: an old nonzero high count remains after recovery, so the accumulated counter need not return to zero.
Related operational reading: memory optimized hosting; ram vs vram.