Preemptable Jobs
How to run long jobs on idle HPC Partner hardware with the scavenger (CPU) and scavenger_gpu (GPU) QOS, what happens when a partner needs those nodes back, and how to write a job that survives being interrupted.
What This Is For
Partner projects buy dedicated nodes, and some nodes are not busy all the time. Anyone can already use the idle capacity through the short (CPU) and short_gpu (GPU) QOS, which are capped at 2 hours to meet the partner service level agreement to have access to their resources within 2 hours.
The scavenger QOS remove the 2 hour cap with the tradeoff that:
- jobs never outrank anyone: the QOS carries no priority bonus, so on partner hardware partner work always wins.
- when a partner needs their nodes, jobs are stopped and put back in the queue to start again from the beginning.
Which One To Use
There is one for each kind of partner hardware. Everything on this page applies to both — only the QOS name and the partition change:
| QOS | Partition | For | Non-preemptable alternative |
|---|---|---|---|
| scavenger | compute_partners | CPU jobs on idle partner compute nodes. | short |
| scavenger_gpu | gpu_partners | GPU jobs on idle partner GPU nodes. | short_gpu |
Choosing Between the Short and Scavenger QOS
Both run on partner hardware — short / scavenger in the compute_partners partition, short_gpu / scavenger_gpu in gpu_partners. They have the following differences:
| short / short_gpu | scavenger / scavenger_gpu | |
|---|---|---|
| Maximum wall clock | 2 hours | Much longer (see sqos for the current pilot value) |
| Can be interrupted? | No. Once it starts, it runs to completion. | Yes. Stopped and requeued when a partner needs the node. |
| Good for | Quick tests, short production runs, anything you need to finish predictably. | Long runs that checkpoint, or work you can afford to have restarted. |
| Who has it | Everyone. | Pilot participants only, on request. |
If your job fits in two hours, use short or short_gpu. You get a guarantee that the scavenger QOS do not offer.
Submitting a Job to a Scavenger QOS
Neither is anyone's default QOS, so you have to request it specifically. On CPU partner nodes:
#!/bin/bash #SBATCH --job-name=long_run #SBATCH --partition=compute_partners #SBATCH --qos=scavenger #SBATCH --time=3-00:00:00 #SBATCH --nodes=1 #SBATCH --ntasks=16 #SBATCH --mem=32G #SBATCH --output=long_run_%j.out ./my_program --checkpoint-dir=/share/$GROUP/$USER/ckpt/$SLURM_JOB_ID
And on GPU partner nodes:
#!/bin/bash #SBATCH --job-name=long_train #SBATCH --partition=gpu_partners #SBATCH --qos=scavenger_gpu #SBATCH --time=3-00:00:00 #SBATCH --nodes=1 #SBATCH --ntasks=8 #SBATCH --gres=gpu:l40s:1 #SBATCH --mem=64G #SBATCH --output=long_train_%j.out ./my_program --checkpoint-dir=/share/$GROUP/$USER/ckpt/$SLURM_JOB_ID
Submitting to compute_partners or gpu_partners without --qos still gets you short / short_gpu (or your partner QOS, if you are in a partner project), exactly as before. Nothing about your existing jobs changes.
To confirm you have access and see the current limits:
sqos
What Happens When You Are Preempted
- A partner job needs nodes your job is holding.
- Slurm signals your job and gives it a grace period of 5 minutes.
- At the end of the grace period the job is stopped and requeued — it goes back into the pending queue with the same job ID.
- It starts again from the beginning when resources are next free. Your batch script is re-run from its first line.
Two rules decide which job gets preempted, and both are meant to protect long-running work:
- A job is not preemptable during its first 30 minutes. Every attempt gets at least that much uninterrupted time, so a job cannot be requeued over and over without ever making progress.
- After that, the job that started most recently is preempted first. If several jobs could free the needed nodes, the one that has been running the shortest time loses the least work, so it is the one chosen. A job that has been running for days is the last to be touched.
Writing a Job That Survives Preemption
Checkpoint, and restart from the checkpoint
This is the whole game. Your script is re-run from the top, so it needs to notice that a previous attempt got partway and resume from there. Many scientific codes have this built in (GROMACS -cpi, LAMMPS read_restart, NAMD reinitatomsics, PyTorch checkpoint files); if yours does, use it.
CKPT=/share/$GROUP/$USER/ckpt/$SLURM_JOB_ID
mkdir -p $CKPT
if [ -f $CKPT/state.rst ]; then
./my_program --restart-from $CKPT/state.rst
else
./my_program --checkpoint-to $CKPT/state.rst
fi
The job ID stays the same across a requeue, so naming the checkpoint directory after $SLURM_JOB_ID gives each job a stable place to resume from.
Write output so a rerun is safe
A restarted job re-runs everything, including any output your first attempt already wrote. Append-mode logs will contain the partial first attempt; files written with > will be overwritten, which is usually what you want. Be careful with anything that has a side effect outside the job — submitting follow-on work, sending mail, updating a database — because it will happen again.
Catch the grace-period signal (optional)
If your program can save state on demand, trap the signal Slurm sends at the start of the grace period and use the 5 minutes:
cleanup() {
echo "Preempted at $(date) -- saving state"
kill -USR1 $PID # whatever your program uses to checkpoint on demand
wait $PID
}
trap cleanup SIGTERM
./my_program &
PID=$!
wait $PID
Do not use --no-requeue
Batch jobs only
The scavenger QOS are for sbatch. An interactive session (salloc, or srun run directly from a login node) cannot meaningfully be requeued — your shell would simply vanish. For interactive work on partner hardware use --qos=short or --qos=short_gpu, which are not preemptable. See Interactive jobs.
Checking Whether Your Job Was Preempted
A requeued job keeps its job ID, so its history has more than one entry. Ask sacct for all of them:
sacct -j jobid --duplicates --format=JobID,State,Start,End,Elapsed
An attempt that was preempted shows a state of PREEMPTED or REQUEUED, followed by a later attempt that ran again. While the job is waiting to restart, squeue shows it pending with a reason of JobHeldUser or Resources.
The job monitoring guide covers reading these in more detail.
Common Questions
| Question | Answer |
|---|---|
| Will I be charged for the work that was thrown away? | Preempted attempts still consume the resources they used, and they appear in your usage. Checkpointing keeps that waste small. |
| How often will this actually happen? | It depends entirely on how busy the partner nodes are, which is what the pilot is measuring. Assume it can happen at any time and write the job accordingly. |
| Can a partner's job preempt another partner's job? | No. Only scavenger and scavenger_gpu jobs are preemptable. Partner jobs, and jobs on compute, gpu and xfer, are never interrupted. |
| Is there a GPU equivalent? | Yes — scavenger_gpu, on gpu_partners. It works exactly the same way, and is granted on request like the CPU one. Every partner GPU model is reachable, each with its own ceiling shared across all scavenger jobs; run sqos to see your limits. |
| My job keeps getting preempted early on. | It should not — nothing is preemptable in its first 30 minutes. If you see otherwise, please report it; that is exactly the kind of thing the pilot is for. |
Related Pages
- Running Partner Jobs — how partner projects reach their own hardware.
- Partitions and Resources — the full partition list.
- GPU Jobs — requesting GPUs, models and CUDA.
- Priority and Fair Share — where the scavenger QOS sit against the others.
- Monitoring Jobs — reading sacct and squeue output.