Slurm is easiest to mistake for the command that makes a program wait. Submit a script, see PENDING in squeue, and it looks like a queue with unusually elaborate syntax. Its real product is more useful: a promise that a particular bundle of CPUs, memory, GPUs, and nodes belongs to one job for a bounded amount of time. Slurm then separates that promise from the programs launched inside it.
That separation is why the project works as both a cluster resource manager and a job scheduler. It allocates resources, provides a framework for starting and monitoring work on them, and arbitrates conflicting requests. The cleanest introduction is therefore not a tour of commands. It is four nouns—node, partition, job, and job step—followed by the machinery that keeps their meanings distinct.[1]
The photograph above shows Frontier at Oak Ridge National Laboratory, whose user guide identifies Slurm as its batch scheduling system.[7] The image is not generic data-center scenery. A row of cabinets can supply enormous compute capacity and still be unusable as a shared scientific service. Someone must decide which resources form a valid request, who may claim them, when the claim begins, how work enters the claimed machines, and what evidence remains after it ends. Slurm is the open-source control plane that makes those decisions inspectable.
Four nouns turn hardware into a shared service
A node is Slurm's basic compute resource: usually one Linux machine with a declared inventory. Nodes may differ in processor count, memory, accelerators, local storage, or features. Slurm does not erase those differences. It gives administrators and users a vocabulary for requesting them.
A partition groups nodes into a logical set. Partitions can overlap, so they are not simply physical aisles with separate labels. Each can carry policy such as permitted users, default and maximum wall times, or job-size limits. A GPU node might appear in a general partition and a restricted project partition at the same time. Calling a partition a queue is convenient, but incomplete: it joins a pool of eligible hardware to an admission policy.[1][5]
A job is the allocation itself—the time-bounded claim on resources. A job step is a set of tasks launched within that claim. One job can contain a single step that fills every allocated node, several sequential steps that reuse the allocation, or concurrent steps that divide it. NERSC's operating documentation makes the distinction concrete: sbatch submits a script for later execution, while srun can create real-time steps inside the resources obtained by sbatch or salloc.[6]
These nouns explain why a pending job is not merely “next in line.” It asks for a shape: perhaps four nodes, eight GPUs per node, 40 minutes, a particular feature, an account, and a partition whose rules admit the request. A smaller later job may fit before it without stealing the earlier job's predicted start. A high-priority request may still wait because no currently free nodes satisfy its whole shape.
The controller grants; the nodes launch
Slurm's daemon boundary mirrors that conceptual split. A central slurmctld owns authoritative state about jobs, nodes, and partitions and decides which resources to allocate. A backup controller can take over using shared saved state. Every compute node runs slurmd, which accepts authorized work and manages tasks locally.[1][5]
Launching a step does not require the controller to fork every process on every node. srun asks slurmctld for the step; the controller returns a signed credential describing the granted resources; srun forwards the launch request and credential to slurmd; and each participating node starts a slurmstepd for that step. The step daemon prepares the environment, I/O, process tracking, and any MPI or network plugin work before executing tasks. Keeping node-local launch out of the central controller's hot path protects the service that must continue admitting and scheduling the rest of the cluster.[2]
The boundary also gives failures more precise names. A job can be pending because the controller cannot place its request. An allocated node can fail during execution. One step can have a task-layout error while the allocation remains valid. Accounting can lag even though task launch succeeds. “The cluster is broken” becomes a less useful diagnosis than “the node is drained,” “the step credential was rejected,” or “the request cannot fit in this partition.”
The script asks for a promise; srun spends it
A small GPU batch script exposes the two levels:
#!/bin/bash
#SBATCH --job-name=solver
#SBATCH --nodes=2
#SBATCH --time=00:20:00
#SBATCH --partition=gpu
#SBATCH --gpus-per-node=4
srun --ntasks=8 --gpus-per-task=1 ./solver input.dat
The #SBATCH lines describe the allocation: two eligible nodes, a 20-minute ceiling, a site-defined partition, and four GPUs on each node. sbatch sends that request and returns a job ID. Only after the allocation begins does the final line create a step containing eight tasks. The example is deliberately not portable as written—partition names, account requirements, GPU options, and defaults belong to the site—but the allocation/step distinction travels across installations.[6]
salloc obtains an allocation for interactive work. srun outside an existing allocation can request resources and launch work in one motion; inside an allocation, it launches a step. squeue is the live view of pending and running work. sacct is the retrospective view when accounting is configured. These tools are different windows onto the same state machine, not independent ways to bypass it.
This model prevents two common misunderstandings. First, receiving an allocation does not mean every desired parallel process has been placed; the step still needs a task layout. Second, an srun inside a job normally consumes some or all of an existing promise—it does not automatically acquire a second set of nodes. When multiple steps share an allocation, their CPU, memory, and GPU requests must fit together just as the original job had to fit the cluster.
TRES gives unlike resources one accounting grammar
CPU counts are not enough for a mixed cluster. Slurm calls the broader accounting units Trackable RESources, or TRES. Current TRES types include CPU, memory, nodes, energy, licenses, filesystems, and GRES, the category used for generic resources such as GPUs. Administrators can add resources to AccountingStorageTRES, assign requested resources priority weights with PriorityWeightTRES, and convert heterogeneous consumption into a billing measure through partition-specific TRESBillingWeights.[3]
That vocabulary connects three questions that are often split across systems:
- Can the job be placed? The selection plugin must find nodes whose consumable resources satisfy the request. For sharing processors, memory, and other resources within nodes, the administrator guide recommends
select/cons_tres.[5] - What did the job use or reserve? Accounting records can retain CPU, memory, GPU, and other declared resource dimensions rather than reducing the run to elapsed time alone.[3]
- How should use affect policy? A site can apply resource limits, fair-share calculations, or priority weights to the same resource vocabulary.[3]
TRES does not make every accelerator interchangeable. A job can still require a GPU type, feature, topology, or site-specific constraint, and the inventory must match the actual node. The abstraction is valuable because it keeps the request, placement decision, and accounting record connected—not because it turns heterogeneous hardware into identical tokens.
Priority chooses an order; backfill finds a fit
Scheduling is another pair of contracts. Priority ranks eligible jobs. Depending on configuration, factors can include age, size, association, fair share, partition, quality of service, and requested resources.[5] The scheduler then tries to place jobs against the real availability and topology of the cluster.
The current scheduling guide documents two scheduler plugins. sched/builtin attempts strict priority order. The default backfill plugin may start a lower-priority job only when doing so will not delay the expected start of a higher-priority one. That is why an honest wall-time request is operational data, not paperwork: backfill needs an end-time estimate to identify safe holes in the plan.[4]
The same guide shows how much work can sit behind an apparently static queue. Event-triggered scheduling considers a default depth of 100 jobs; the main loop's documented default interval is 60 seconds; and backfill's documented default interval is 30 seconds. Those are tunable defaults, not performance promises. On a busy installation, request volume, array size, topology checks, controller RPC traffic, and site policy determine whether they are sensible.[4]
For users, the practical lesson is simple. Requesting a dramatically inflated wall time can reduce opportunities for the job to backfill. Requesting too little invites termination before useful output is safely checkpointed. Queue position alone cannot express that tradeoff; the pending reason, requested shape, predicted start, and application's checkpoint behavior are better evidence.
The hard part is operating the promise
Slurm is self-hostable, but “open source” does not make the control plane self-operating. The administrator guide requires a uniform user and group namespace across the cluster, authenticated communication between components, consistent configuration, writable runtime paths, and durable controller state. With MUNGE authentication, nodes need the same key and synchronized clocks. Slurm also does not create the parent directories for its logs, PID files, spool, and state on an operator's behalf.[5]
StateSaveLocation is especially consequential. It preserves queued, running, and recently completed job state across a controller restart or failover. SchedMD recommends low-latency storage and, for backup controllers, a shared filesystem; the guide warns that a controller starting without access to that state can cancel queued and running jobs.[5] High availability is therefore not achieved by adding a second hostname. Both controllers must see a trustworthy state path, and the recovery procedure must be tested.
Containment is another explicit boundary. Slurm authenticates its own messages and tracks the work it launches, but it does not by itself prevent a user from logging directly into an allocated compute node. Sites that require strict access isolation must add the PAM module or equivalent controls and decide how to clean up processes launched outside Slurm's supervision.[5] Accounting through slurmdbd, database retention, cgroup enforcement, prolog and epilog hooks, monitoring, and upgrade rehearsal are operating choices, not automatic consequences of installing slurmctld.
Who should adopt it
Slurm fits when several users or services contend for a Linux compute pool and the organization needs explicit answers to four questions: what was requested, what was granted, what ran inside the grant, and how use should affect future access. That can describe a small research cluster as well as Frontier. It is especially compelling when work is batch-shaped, runtimes can be bounded, parallel launch matters, and CPUs, GPUs, memory, or licenses must be scheduled together.
A single workstation with one trusted user usually does not need this control plane. Nor is Slurm a substitute for storage architecture, reproducible software environments, workflow retries, application checkpointing, or observability. It can launch a container without deciding whether the image is scientifically valid; reserve a GPU without making the program use it efficiently; and terminate at the wall-time boundary without inventing a checkpoint the application never wrote.
The conservative pilot is small: one controller, a backup plan for its state, a few compute nodes, one partition, consistent identities and authentication, and a known srun -N1 /bin/hostname test. Add accounting before using fair share as policy. Add GPU inventory only after CPU and memory placement are trustworthy. Exercise node drain, controller restart, job cancellation, time-limit signals, and completed-job reporting before offering the cluster as a dependable service.[5]
Slurm's achievement is not that it can keep a long queue. It is that it turns shared hardware into reviewable promises, then keeps each promise separate from the work performed inside it. Once node, partition, job, and step stop sounding interchangeable, the commands become easier—and the failure modes become possible to operate.
Sources
- SchedMD, “Slurm Workload Manager — Quick Start User Guide” — project purpose, daemon overview, and definitions of nodes, partitions, jobs, and job steps.
- SchedMD, “Job Launch Design Guide” — allocation, signed step credentials,
slurmdfan-out,slurmstepd, task launch, and termination flow. - SchedMD, “Trackable RESources (TRES)” — resource types, accounting configuration, priority weights, and billing weights.
- SchedMD, “Scheduling Configuration Guide” — event scheduling, scheduler plugins, backfill behavior, timing defaults, and wall-time dependency.
- SchedMD, “Quick Start Administrator Guide” — controller and node roles, authentication, high availability, saved state, configuration, selection, accounting, and access-control boundaries.
- National Energy Research Scientific Computing Center, “Basics of Running Jobs” — an independent production-site explanation of
sbatch,salloc,srun, allocations, and job steps. - Oak Ridge Leadership Computing Facility, “Frontier User Guide” — production-system documentation identifying Slurm as Frontier's scheduler and showing its allocation and launch workflow.
- Oak Ridge Leadership Computing Facility, “Frontier Supercomputer (1)” — source page for the real ORNL photograph used as the article image, via Wikimedia Commons.