MemSpecLimit, ConstrainRAMSpace, or the cache-dropper sidecar.
Read node memory, not pod metrics
Slurm’s cgroup plugin creates its own cgroup hierarchy on the node, separate from the Kubernetes pod’s cgroup. Training job memory is charged to the Slurm hierarchy, not the pod hierarchy. This separation has two consequences:- cAdvisor and Kubernetes pod metrics show only the
slurmddaemon’s small footprint, not the memory jobs use. - A pod memory limit on the
slurmdcontainer doesn’t constrain the Slurm jobs themselves.
/proc/meminfo or node_memory_* metrics), not pod or container metrics. For the CPU side of the same split and the Slurm metrics the Syncer exports instead, see Why do slurmd Pod metrics show almost no CPU or memory usage?.
The next section shows how to compare Shmem and Cached in /proc/meminfo to distinguish reclaimable page cache from pinned shmem and tmpfs.
Compare Shmem and Cached
In /proc/meminfo, the Shmem field (shared memory and tmpfs, including /dev/shm) is counted inside Cached. The kernel’s MemAvailable estimate treats cached memory as reclaimable. Shmem and tmpfs pages aren’t reclaimable under pressure: unlike file-backed page cache, they have no backing file to evict to.
Don’t compare
Shmem against Unevictable. The kernel’s unevictable list holds ramfs pages, tmpfs mounted with noswap, SHM_LOCKed segments, and mlock()ed memory, so an ordinary /dev/shm leaves Unevictable near zero even when tens of gibibytes of shmem are pinned.Shmem to Cached to tell reclaimable cache from pinned shmem.
-
On the affected node, compare
ShmemandCachedby running the commands below: -
In the output, look for the following node metrics:
-
Compare the two values and find your case in the table:
Ask an administrator
Bring these items to the cluster administrator. Job authors can’t set them.MemSpecLimit reserves memory, in mebibytes, for system use so Slurm doesn’t allocate it to jobs. Leave it unset and Slurm reserves nothing beyond what the node already holds back. It takes effect only when memory is a consumable resource, which the SUNK default SelectTypeParameters=CR_CPU_MEMORY satisfies.
On SUNK, CoreWeave already holds back memory for the operating system, kubelet, and DaemonSets, and Slurm advertises a reduced RealMemory to match. MemSpecLimit covers what that baseline misses: on-node sidecars and shmem peaks. See Avoid stranded GPUs for how RealMemory relates to what a job can request.
The CoreWeave AI Object Storage proxy sidecar, when present, can consume 30 to 50 GiB under heavy object-storage workloads. That usage is invisible to cAdvisor and to Slurm cgroup accounting on cgroup v1. Account for it in MemSpecLimit on nodes that run object-storage-heavy jobs.
ConstrainRAMSpace=yes in cgroup.conf is what makes Slurm enforce per-job memory limits. SUNK sets it by default under slurmConfig.cgroupConfig. Two conditions make it effective:
SelectTypeParametersmust track memory. SUNK defaults toCR_CPU_MEMORY, so check this only when someone has overridden it. Without memory as a consumable resource, cgroup memory enforcement may not work even withConstrainRAMSpace=yes.- On cgroup v1,
ConstrainRAMSpace=yesis the only thing bounding a Slurm job, because pod limits don’t constrain Slurm jobs. On cgroup v2, Slurm still manages its own memory cgroup slice, soConstrainRAMSpace=yesis still required for Slurm-side enforcement.
ConstrainRAMSpace=yes, heavy /dev/shm use can still cause a node-level out-of-memory event, because shmem allocations live in the host-level Slurm cgroup rather than the per-task cgroup that ConstrainRAMSpace bounds. For full cgroup configuration, see Manage resource binding with task plugins.
JobContainerType=job_container/tmpfs scopes /dev/shm and temp directories per job so they’re cleaned up automatically. Set JobContainerType=job_container/tmpfs and add Contain to PrologFlags; Slurm requires PrologFlags=Contain for this plugin. The SUNK default PrologFlags is Alloc,Serial, so this is a change to make, not a default to rely on.
When to file a support ticket
Open a ticket when a node runs out of memory and you’ve confirmed the pressure isn’t reclaimable cache and have accounted for shmem and system overhead inMemSpecLimit. Include /proc/meminfo output, the cgroup version, and the job’s memory pattern (especially /dev/shm use).
Related pages
- Manage memory with cache-dropper: trigger the page cache dropper between jobs.
- Manage resource binding with task plugins: cgroup configuration and constraints.
- Avoid stranded GPUs: how
RealMemoryandDefMemPerCPUbound what a job can request. - Why do slurmd Pod metrics show almost no CPU or memory usage?: the same cgroup split, and which metrics to read instead.
- Share storage across Slurm nodes: shared directory permissions and home directory hygiene.