Skip to main content
When a SUNK compute node exhausts its memory, the kernel terminates the largest offending process to reclaim it. This is an out-of-memory (OOM) kill, and Slurm reports the job as failed. The metrics afterward may appear contradictory: the node’s Kubernetes Pod metrics show modest memory use, and the node’s Grafana panel shows ample available memory in the moments before the OOM event. This page explains how to diagnose the source of memory pressure on a node by checking node-level memory instead of pod metrics. Checking the right metrics helps you determine whether memory pressure comes from reclaimable page cache or pinned shmem and tmpfs. If necessary, cluster administrators can change 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 slurmd daemon’s small footprint, not the memory jobs use.
  • A pod memory limit on the slurmd container doesn’t constrain the Slurm jobs themselves.
To diagnose the source of memory pressure, read node-level memory (/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.
Use the ratio of Shmem to Cached to tell reclaimable cache from pinned shmem.
  1. On the affected node, compare Shmem and Cached by running the commands below:
  2. In the output, look for the following node metrics:
  3. 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.
Don’t put MemSpecLimit in slurmConfig. That block renders into global slurm.conf scope, where Slurm rejects the key with _parse_next_key: Parsing error at unrecognized key: MemSpecLimit. On SUNK that parse failure restarts every Slurm pod and disrupts running jobs. MemSpecLimit is a per-node parameter and belongs on the node configuration. The same applies to CoreSpecCount and other per-node keys.
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:
  • SelectTypeParameters must track memory. SUNK defaults to CR_CPU_MEMORY, so check this only when someone has overridden it. Without memory as a consumable resource, cgroup memory enforcement may not work even with ConstrainRAMSpace=yes.
  • On cgroup v1, ConstrainRAMSpace=yes is 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, so ConstrainRAMSpace=yes is still required for Slurm-side enforcement.
Even with 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 in MemSpecLimit. Include /proc/meminfo output, the cgroup version, and the job’s memory pattern (especially /dev/shm use).
Last modified on September 16, 2026