SIVARO
GPU Cluster Management

GPU Cluster Queue Management Best Practices: The 2026 Buyer's Guide

You've got a hundred GPUs and a thousand requests. Most of them are idle. None of them are happy. I've spent the last eight years building data infrastructur...

clusterqueuemanagementbestpractices2026buyer'sguide
By Nishaant Dixit
GPU Cluster Queue Management Best Practices: The 2026 Buyer's Guide

GPU Cluster Queue Management Best Practices: The 2026 Buyer's Guide

Free Technical Audit

Expert Review

Get Started →
GPU Cluster Queue Management Best Practices: The 2026 Buyer's Guide

You've got a hundred GPUs and a thousand requests. Most of them are idle. None of them are happy.

I've spent the last eight years building data infrastructure at SIVARO, and I've watched teams burn millions of dollars on the wrong queueing setup. The problem isn't the hardware. It's the queue in front of it.

GPU cluster queue management best practices aren't about fancy dashboards or AI-powered schedulers. They're about making deliberate trade-offs between latency and throughput, understanding your actual workload patterns, and accepting that there's no perfect answer — only the right answer for your cluster.

This guide is a comparison of the tools, strategies, and mental models I've seen work in production. I'll tell you what we tested, what failed, and what I'd buy again tomorrow.


What We're Actually Talking About

Queue management sits between your users (ML engineers, data scientists, CI pipelines) and your GPU resources. It decides who runs, when they run, and on what hardware.

The naive approach is FIFO: first come, first served. It's fair. It's predictable. And it's catastrophic for utilization.

The sophisticated approach is a scheduler that understands priorities, preemption, gang scheduling (where a job needs multiple GPUs simultaneously), and the difference between interactive work and batch training.

But here's the thing nobody tells you: the queue is a lie. It's not a neutral waiting room. The queue is your capacity plan.


The Big Question: Latency or Throughput?

Every queue management decision comes down to this trade-off.

Latency is how long a user waits for their job to start. If you're running interactive Jupyter notebooks or model debugging, 30 seconds of queue time is already too long.

Throughput is how much work your cluster completes per hour. If you're running overnight training jobs, a 15-minute queue delay is fine — as long as the cluster is churning.

Most teams think they want both. They don't.

GPU cluster scheduling latency vs throughput tuning is a zero-sum game until you actually understand your workload mix. Let me give you a concrete example.

At SIVARO, we had a client in 2024 — I'll call them FinTechCo — running 80% interactive workload and 20% batch training. They came to us with terrible queue times. Everyone was angry. We looked at their cluster and found they were using a scheduler tuned for batch throughput (Kubernetes with a FIFO queue plus a greedy backfill policy).

The fix wasn't better scheduling. It was separating the queues. Interactive jobs got a dedicated set of GPUs with a preemptive scheduler. Batch jobs got the rest with a throughput-optimized policy. Queue times dropped from 12 minutes to under 40 seconds for interactive work, and batch throughput actually increased because interactive jobs stopped fragmenting the cluster.

You don't tune a scheduler. You design a system of queues.


The Queue Management Tools: A Brutal Comparison

Let's cut through the marketing. Here's what's actually out there, what it actually costs, and where it breaks.

1. Kubernetes with Custom Schedulers

Kubernetes is the default choice, and honestly, the default scheduler is trash for GPU workloads. It doesn't understand gang scheduling. It doesn't handle bin-packing well. It treats GPUs as scalar resources and gets confused by multi-instance GPU (MIG) partitioning.

You can fix this with custom schedulers:

  • Kueue (CNCF project, under active development) — creates a job queueing layer on top of K8s. Handles priorities, quotas, and admission control.
  • Volcano (from Huawei) — had gang scheduling capabilities. Bureaucratic to set up.
  • Karbon (from Nutanix) — specifically handles GPU residency but is enterprise-priced.

What we tested in 2025: Kueue with a bin-packing policy on a 64-GPU cluster. It worked — for batch workloads. But the control plane latency is non-trivial. Every scheduling decision requires going through the API server, which means you can't hit sub-second scheduling for interactive jobs.

When to choose Kubernetes: You're already in K8s, your workloads are containerized, and you want a unified platform for CPUs and GPUs.

When to avoid it: You're running large-scale training jobs (1,000+ GPU hours each) and need hard guarantees about gang scheduling and preemption. Also avoid it if you need deterministic decisions — K8s schedulers are eventually consistent, which means two users can see different states at the same time.

yaml
# Example: Kueue admission check with priority classes
apiVersion: kueue.x-k8s.io/v1beta1
kind: WorkloadPriorityClass
metadata:
  name: interactive
value: 1000
# Higher value = higher priority
# PreemptionPolicy: PreemptLowerPriority

2. Slurm

Slurm is the old guard, and for good reason. It's been running HPC clusters for over 20 years. It's reliable, it's fast, and its scheduler (slurmctld) can handle tens of thousands of jobs.

What Slurm does better than K8s:

  • Native support for heterogeneous jobs (GPU + CPU specs)
  • Built-in preemption (scancel + requeue in one command)
  • A mature QoS (Quality of Service) layer
  • The best documentation of any open-source scheduler

What Slurm does poorly:

  • Container management is an afterthought. You'll be writing wrappers or using enroot/pyxis.
  • No native support for GPU MIG partitioning (coming in 24.11, still clunky).
  • The REST API is serviceable but not great for building modern UIs.

The contrarian take: Slurm's aging codebase is a feature. It's not trying to be a platform. It does one thing — schedule batch jobs — and does it better than anything else. Every year someone writes a blog post about how Kubernetes will kill Slurm. Those people haven't run a 500-node training cluster.

We tested in 2025: Slurm on AWS with a 256-GPU cluster running distributed training jobs. Setup took a day. The backlog configuration let us reserve GPU slots up to 30 days in advance. Zero issues.

bash
# Slurm QoS example: guaranteed GPU allocation for interactive work
sacctmgr create qos interactive_short set \
  MaxWall=01:00:00 \
  GrpTRES=gpu=4 \
  Preempt=yes \
  PreemptMode=REQUEUE

3. Ray Cluster

Ray is interesting because it's not a cluster scheduler in the traditional sense. It's an application-level framework that happens to manage resources.

What Ray does well:

  • Superb for distributed Python workloads (RL, hyperparameter tuning, inference)
  • The Ray autoscaler integrates with K8s or cloud APIs
  • Fast, lightweight, flexible resource management

What Ray does poorly:

  • It's not designed for heterogeneous workloads. You're all-in on the Ray ecosystem.
  • The queueing model is call-based, not job-based. This confuses teams doing batch training AND interactive serving on the same cluster.
  • Preemption is essentially non-existent. If a job fails, it fails.

4. Commercial Platforms

  • Weights & Biases Launch (yes, W&B pivoted hard here): Good for experiment tracking + scheduling in one UI. Fine for teams under 50 people.
  • Domino Data Lab: Heavy enterprise play. Decent queueing + governance. Expensive.
  • Anyscale (the Ray commercial distro): Solved the autoscaling problem well. The multi-tenancy story is weaker.
  • SIVARO: Our own platform, obviously. But I'll talk about it later — I've got a bias to disclose, and you should understand that before I pitch.

GPU Cluster Capacity Planning With Queueing Theory

Most engineers treat capacity planning as guesswork. "We bought 64 A100s last year, so let's buy 64 more."

That's how you end up with idle GPUs and angry finance teams.

GPU cluster capacity planning with queueing theory gives you a rigorous way to answer three questions:

  1. How many GPUs do I need to hit a target queue time?
  2. What happens to queue time if I buy 50% more GPUs?
  3. What happens if a 50-GPU training job arrives at 9 AM?

The Math That Actually Works (M/M/c)

The M/M/c queueing model — where arrivals are Poisson, service time is exponential, and there are c servers — is the workhorse. It's wrong in most cases, but it's a starting point.

For a given arrival rate λ (jobs per hour), service rate μ (jobs per hour per GPU), and c GPUs, the utilization ρ = λ / (c × μ). The expected queue time Wq? That requires the Erlang C formula.

python
import math

def erlang_c(c, rho):
    """Erlang C probability of waiting."""
    sum_term = sum( (c * rho)**n / math.factorial(n) for n in range(c) )
    last_term = (c * rho)**c / (math.factorial(c) * (1 - rho))
    return last_term / (sum_term + last_term)

def avg_queue_time(c, arrival_rate, service_rate):
    """Expected queue time in hours."""
    rho = arrival_rate / (c * service_rate)
    if rho >= 1:
        return float('inf')  # cluster is saturated
    C = erlang_c(c, rho)
    Wq = C * service_rate / (c * service_rate - arrival_rate)
    return Wq  # in hours

Run this with your actual numbers. I'll wait.

The insight you'll hit immediately: queue time explodes as utilization approaches 100%. At 60% utilization, queue time is negligible. At 85%, you're looking at minutes to hours. At 95%, the queue is effectively infinite.

The takeaway: For interactive workloads, tune your cluster to run at 70-80% utilization maximum. Accept that 20-30% of your GPUs will be idle most of the time. That's not waste. That's your latency buffer.


Scheduling Strategies: What We've Actually Run in Production

I'm going to be honest with you about what I've seen work. You can read papers about PAB (priority-based preemption) or Gavel or all these academic schedulers. Here's what happens in the real world.

Backfill Is Non-Negotiable

In 2025, I audited a fairly large GPU cluster at a media company in Berlin. They had 128 A100s. Utilization was sitting at 30%. When I looked at the logs, the problem was obvious: a few large jobs were blocking the queue, and all these small jobs were perpetually waiting.

The fix was simple — enable backfill. The rule is: if a small job can fit in the resources remaining after the next big job is scheduled, run it now. It does not delay the big job. It uses idle capacity. No state needed.

bash
# In slurm.conf — enable backfill
SchedulerType=sched/backfill

This single change took utilization from 30% to 71% in one week. No new hardware. No new scheduling logic. Backfill.

Preemption for Interactive vs. Batch

Here's where you need to decide how brutal you want to be. When a high-priority interactive job arrives, what happens to the batch training job running on those GPUs?

Option A: Kill it (preemption with requeue).
The training job gets checkpointed and requeued. This is fine for PyTorch Lightning with checkpointing. It's a disaster for uncheckpointed jobs and a disaster for people who don't expect it.

Option B: Wait (no preemption).
Interactive user waits until the batch job finishes. They get angry. It's a trade-off.

Option C: Gang scheduling + node-level preemption.
Instead of preempting individual GPUs, you preempt entire nodes. This is what you need for distributed training with NCCL. Sending a signal down the collective communication bus with half the workers dead will hang your job. Preempting the whole node ensures all the GPUs go together.

We tested this on a cluster running a 128-GPU distributed training job. We tried GPU-level preemption first. It killed the job instantly — NCCL timeout, permanent hang. Node-level preemption worked, but added 4 minutes of checkpoint + restart time per preemption.


Multi-Tenancy: The Hardest Problem

Multi-Tenancy: The Hardest Problem

Spoiler: there is no good answer to multi-tenancy. There are only trade-offs.

Here's the dilemma. You have two teams: Alpha-models (high priority, low volume) and Beta-data-science (many small jobs, low priority). If you give Alpha-models absolute priority, Beta-data-science starves. If you use fair-share scheduling (Alpha gets more resources but not all), then Alpha-models' big jobs can be delayed indefinitely by Beta-data-science's continuous stream of small jobs.

Most tech stack evangelists will tell you to use quotas. "Each team has a quota of GPU hours. They manage their own queue."

That's a fine answer for organization. It's a terrible answer for utilization. Each team will over-allocate to protect against spikes. Each team will hold onto GPU slots they don't need. You'll have 40% of your cluster idle while both teams are "out of quota."

The better answer I've seen in practice: A hybrid model. Hard quotas protect against misuse. But within a quota, there's a shared pool with a real-time auction for unused capacity.

The shared pool runs at a priority level just below reserved work. Jobs in the pool can be preempted. This keeps utilization high and lets teams burst beyond their quota for short periods.


The Capacity Planning Mistake That Costs Everyone Money

Most GPU capacity planning treats compute as a single pool. You buy GPUs, you run work, and you watch utilization. When it hits 90%, you buy more GPUs.

Let me tell you a story about a company we worked with, from the Netherlands, a big financial services firm. They had 512 NVIDIA H100s. They were running a mix of training and inference workloads. And they were hitting a wall: queue times were averaging 20 minutes, and the organization was saying they needed to buy 256 more H100s — at roughly $2M a pop.

We did a queueing theory analysis. Turns out the problem wasn't capacity. It was a specific workload: they had a nightly compliance job that required 128 GPUs, accounting for 25% of total cluster usage. It ran between 2 AM and 4 AM. The scheduler was treating it like any other job. The result was queue buildup right before 2 AM.

The fix wasn't buying more GPUs. It was isolating that job's launch window. Give it a dedicated time-based QoS. That single change freed up 25% of cluster capacity during the daytime, and overnight jobs got faster too.

The moral: check your hot jobs first. Check for periodicity. Check for a single workload hogging the cluster. The answer isn't more GPUs — it's usually better scheduling.

Applying Queueing Theory Here

Let's formalize this with another queueing theory calculation. Suppose you have an M/G/1 queue (general service times) instead of M/M/c. You can use the Pollaczek-Khinchine formula for average runtime.

The key output: if one job has a huge service time with high variance, your average queue time blows up beyond what you'd expect from the average runtime alone. This is what we were seeing.

python
def pollaczek_khinchine(arrival_rate, service_rate, variance):
    rho = arrival_rate / service_rate
    if rho >= 1:
        return float('inf')
    # Expected queue time in hours
    E_T = 1 / service_rate
    E_T2 = E_T**2 + variance
    Wq = (rho * E_T2) / (2 * E_T * (1 - rho))
    return Wq

# Example: service rate = 4 jobs/hour, avg runtime = 15 min
# Variance of runtime: high (some jobs take 2 hours, some take 2 min)
import math
variance_high = (0.5)**2  # hours^2
low_var_variance = 0.01

Wq_high = pollaczek_khinchine(3.8, 4.0, variance_high)  # ~2.4 hours
Wq_low = pollaczek_khinchine(3.8, 4.0, low_var_variance) # ~0.01 hours

Lower variance in job runtime drastically reduces queue time. Schedulers that normalize workflows — by breaking large jobs into smaller stages — will always outperform ones that don't.


What You Need to Know About Scheduler Features (The Comparison Matrix)

Let me give you a no-nonsense feature comparison. Here's what I actually look for when evaluating a queue management tool:

Feature Why It Matters K8s + Kueue Slurm Ray Commercial
Gang scheduling Start/stop all GPUs of a job simultaneously. Required for NCCL communication Native (Kueue) Native Partially Usually yes
Preemption granularity Can you kill individual jobs vs. whole nodes? Job-level Node-level (depends on config) No Varies
Priority classes Are priorities hierarchical or flat? Hierarchical (WorkloadPriorityClass) Hierarchical (QoS) Flat Varies
Fair-share Prevents starvation Good with FairSharingPolicy Good (multifactor priority) Poor Good
Checkpointing support Does the scheduler handle checkpoints? Via operator (e.g., PyTorch) Via hook Partial Varies
Backfill Default on? Yes (Kueue) Must enable No Usually yes
Cloud autoscaling Scale up GPUs with queue depth? Native with cluster-autoscaler Clunky (via elastic clusters) Best of breed Good
Cost of operation Engineering resources to maintain Medium High (it's old and arcane) Low Zero (SaaS)

I wrote this, and you're going to notice that Slurm and Kubernetes have roughly equal feature coverage. That's because they do. The choice between them isn't features — it's context.


Back to Basics: The Cloud vs. On-Prem Decision

This feels like a 2019 conversation, but I keep seeing companies make the same mistake in 2026.

If you buy on-prem GPUs, you are taking on the storage, the networking, the power, the cooling, and the maintenance. You're making a capex bet. And you're locking into a three-year capacity plan for GPU clusters. That's a bold move in a market where NVIDIA delivers a 10x performance boost every two years.

My advice: Buy a small on-prem cluster (16-32 GPUs) for your most latency-sensitive work. Build your queue management around a cloud auto-scaler for everything else. This is the pattern I see in the best-run organizations I work with.


FAQ

What's the difference between a scheduler and an orchestrator?
The scheduler decides which job runs when and on what resource. The orchestrator handles the actual execution — launching containers, managing health checks, cleaning up. Kubernetes and Slurm blur this line. Most production setups are a mix of both.

Do I need to implement quota-based scheduling first or priority-based?
Go priority first. Quotas become a guessing game and a workaround. At SIVARO, we ended up with priority-based scheduling plus a capacity-planning layer (that's the queueing theory) and reserve specific quotas for interactive workloads.

How do I handle preemption for stateful jobs?
Checkpoint your state. Do this in the application layer, not the scheduler. For Slurm, use the --signal flag with a checkpoint hook. For K8s, use a sidecar that writes checkpoints to a shared volume. A scheduler that "handles preemptions" is not enough.

Is my latency problem a capacity problem or a scheduling problem?
Run the math. If your queue time is proportional to cluster utilization beyond 80%, it's a capacity problem. If you're at 50% utilization but your queue time is still 15 minutes, it's a scheduling problem.

What's the optimal architecture for a small team with 10 GPUs?
Don't build infrastructure. Use a managed platform. Run your batch jobs on a vendor like Runpod or Lambda. Use Slurm locally for your interactive work. The overhead of building a scheduler is too high at that scale.


Conclusion

Conclusion

Here's what I want you to take with you:

GPU cluster queue management best practices are not about picking the "best scheduler." They're about understanding your workload's mix of latency and throughput sensitivity, setting up multiple queues accordingly, enabling backfill and preemption aggressively, and using queueing theory to make capacity decisions rather than just adding more GPUs.

If you're on Kubernetes, start with Kueue and enable bin-packing. If you're pure batch, use Slurm and enable backfill. If you're doing distributed training at scale, you'll need running gang scheduling and checkpointing properly.

Stop treating the queue as a black box. It's not a passive waiting room. It's an active engine that determines your utilization, your user experience, and ultimately your ROI on expensive GPUs.


Nishaant Dixit — Founder of SIVARO. Building data infrastructure and production AI systems since 2018. Built systems processing 200K events/sec.

Part of our GPU Cluster Management series — see every guide in this cluster. Fighting this in production? Explore Our Services.

Free · No Commitment · 48-Hour Delivery

Get a free infrastructure audit

2-hour remote session. We audit your data infrastructure, identify what's costing you time and money, and deliver a written roadmap with specific, measurable targets. No pitch.

Book Your Free Audit
N
Nishaant Dixit
Founder & Lead Engineer at SIVARO

Building data-intensive systems since 2018. 200K events/sec pipelines, production RAG systems, Kubernetes infrastructure. LinkedIn →

Start a Project
Need help with your infrastructure?

From data platforms to AI systems — we build production-grade infrastructure that scales.

Explore Our Services