← HashiCorp Nomad memory calculator
How the Nomad calculator works
This page walks through how the Nomad calculator turns your usage data into a task's
memory and memory_max. Both start from the shared sizing model;
this page covers what happens after that. Statements backed by HashiCorp's documentation or Nomad's source end
with a Nomad docs link to it. Choices the documentation doesn't make
for us are explained and marked Assumption, which links to
its row in the table of all of them.
01 What the two settings do
-
memoryis the memory the task requires, in MB. Withoutmemory_maxit is also the hard limit. Nomad docs -
memory_maxis the most the task may use when its client has memory to spare. With it set,memorybecomes the reservation andmemory_maxthe hard limit. Nomad docs
Nomad's own advice matches the shared model: set memory to the task's typical usage and
memory_max to absorb unexpected load spikes.
Nomad docs
So the calculator sizes memory from the average and memory_max from the peak.
In Kubernetes, requests and limits play comparable roles; the Kubernetes guide sizes them the same way, from the average and the peak.
02 memory and memory_max
memory = max(average × (1 + request margin), 10) rounded up to a whole MB
memory_max = max(peak × (1 + limit margin), memory) rounded up to a whole MB
The margins come from the sensitivity, workload type and environment you choose; the sizing model explains them, and they are assumptions too.
- Nomad's MB are mebibytes: it converts them to bytes with 1024 × 1024, so MiB values pass through unchanged. Nomad source
-
Nomad rejects a task with less than 10 MB of
memory, or withmemory_maxbelowmemory, so the result is raised to whichever applies. Nomad source
Worked example
Average 410 MiB, peak 630 MiB, generic workload, medium sensitivity, production, a group count of 3:
| memory | 410 MiB × 1.30 = 533 MiB | 533 MB |
|---|---|---|
| memory_max | 630 MiB × 1.30 = 819 MiB, above memory | 819 MB |
| total reserved | 533 MB × 3 allocations | 1599 MB |
When the peak is close to the average, memory can decide memory_max. Average 1000 MiB and peak 1010 MiB, high sensitivity:
| memory | 1000 MiB × 1.50 = 1500 MiB | 1500 MB |
|---|---|---|
| memory_max | 1010 MiB × 1.40 = 1414 MiB, below memory | 1500 MB |
03 Memory oversubscription
memory_max only works when memory oversubscription is enabled in the scheduler configuration. It's
off by default and enabled once per cluster:
Nomad docs
nomad operator scheduler set-config -memory-oversubscription=true
Without it, memory is the hard limit, so a task sized here would be killed at its average-based value.
The note under the result says to set memory to the memory_max value in that case.
Assumption
Nomad also advises keeping an eye on memory use and leaving enough reserved memory on each client, because oversubscribed tasks can run a client out of memory. Nomad docs
04 Every warning, and why
| Message about | Shown when | Basis |
|---|---|---|
| Peak below average error | The peak you entered is lower than the average | Impossible with real samples; it usually means two different series. See the sizing model. |
05 What to paste
nomad_client_allocs_memory_usage{job="web", task="api"}
-
Nomad publishes allocation metrics when telemetry has
publish_allocation_metricson, and serves them in Prometheus format at/v1/metrics?format=prometheuswithprometheus_metricson. Nomad docs -
nomad.client.allocs.memory.usageis a gauge of the total memory a task uses, in bytes, labelled withjob,task_group,taskandalloc_id, among others. Filtering by both job and task keeps another job's task of the same name out. Nomad docs -
Total usage includes file cache. Nomad also reports
rssandcacheseparately, but RSS leaves out memory the task does need, so the calculator sizes from total usage and errs on the high side. Assumption
06 All assumptions in one place
Besides the margins of the shared sizing model:
Our default: a value we chose. Our reading: how we read documentation that isn't explicit. About your setup: something we take for granted about your data or cluster.
| Assumption | Kind | Why | If it doesn't hold |
|---|---|---|---|
| Size from total usage, cache included ↩ | Our default | RSS alone leaves out memory the task needs | Tasks that read many files get larger values than they strictly need. |
| Without oversubscription, use the memory_max value for memory ↩ | Our default | memory is then the hard limit, and it has to cover the peak | Sizing memory from the average alone would get the task killed at its first peak. |
Values you can change
The calculator’s Advanced: margins and defaults section, closed by default, lets you replace these values when your setup differs. Each field’s “?” says how it moves the result; a value outside the range is used at its nearest end, and “Reset to defaults” puts them all back.
| Value | Default | Range | Where the default comes from |
|---|---|---|---|
| Request margin | from the profile | 0–200% | MemoryLimit’s default, from sensitivity, workload type and environment (sizing model); sizes memory |
| Limit margin | from the profile | 0–200% | MemoryLimit’s default, from sensitivity, workload type and environment (sizing model); sizes memory_max |
07 References
resourcesblock —memory,memory_maxand how to choose them.nomad operator scheduler set-config— enabling memory oversubscription.- Telemetry configuration —
publish_allocation_metricsandprometheus_metrics. - Metrics reference —
nomad.client.allocs.memory.*. - Nomad source: structs.go — MB to bytes, the 10 MB minimum and
memory_max≥memory.