Systemd Memory Limits Calculator
Services that run directly on a VM or bare-metal host have no scheduler reserving memory for them, but systemd
can still fence them in with two cgroup settings. MemoryHigh is a soft ceiling: above it the
service is slowed down and its memory reclaimed aggressively. MemoryMax is the hard one: cross it
and the kernel OOM-kills the service. This calculator sizes both from real usage and gives you a drop-in file
to install.
01 Usage data
Where do I get these numbers?
If cAdvisor runs on the host, use a range query over a representative period (a week is a good default) for the service's cgroup:
container_memory_working_set_bytes{id="/system.slice/myapp.service"}
Without Prometheus, sample systemd directly and paste the numbers (bytes). MemoryCurrent includes page cache, so it reads a little higher than the working set:
while sleep 60; do systemctl show -P MemoryCurrent myapp.service; done
Enter observed usage directly, in MiB.
02 Workload profile
Advanced: margins and defaults
Values the result relies on that are our own defaults, or vendor defaults your setup may change. Each “?” says how one moves the result; the guide says where it comes from.
03 Sizing gauge
04 systemd drop-in (override.conf)
—
05 How this was derived
How every number is calculated, with sources and assumptions (opens in a new tab) ↗
Result looks wrong? Report it
MemoryHigh and MemoryMax in short
MemoryHigh is the throttling limit: above it the service's processes are heavily slowed down and memory is taken away aggressively. MemoryMax is the absolute limit: if usage can't be kept under it, the OOM killer runs inside the unit, and systemd recommends it as the last line of defense. systemd docs
The calculator sets MemoryHigh just above the observed peak and MemoryMax at 1.25 × MemoryHigh. Neither systemd nor the cgroup v2 documentation gives a ratio, so 1.25 is MemoryLimit's own default; you can change it under Advanced. The average-based figure is shown as expected usage, for reference only.
Both settings control cgroup v2. Since systemd 258, cgroup v1 isn't supported at all; older hosts still on it only have the deprecated MemoryLimit=. systemd NEWS
Common input mistakes
- Reading
MemoryCurrentas the working set: we read it as the unit'smemory.current, which counts page cache too, so it reads a little higher. - Using the wrong cgroup id in a cAdvisor query: a service is
/system.slice/<name>.service. - A window that misses the busiest times:
MemoryHighcomes out too low and the service is throttled early.
Full derivation, warnings and every assumption: how the systemd calculator works. The shared formula and margin tables: the sizing model.
Related calculators: