Renting a GPU is no longer the hard part — there are dozens of clouds and the price gap between them is real. The hard part is not marrying one of them. You want to write a job once and run it wherever an H100 is cheapest and available this afternoon, without rewriting anything when that answer changes next week. Two open-source tools own this problem, and they keep coming up together: SkyPilot and dstack.
They're usually pitched as rivals for the same job — "run GPU workloads across any cloud." That framing hides the actual decision. The useful way to tell them apart is what you're managing. SkyPilot manages a job: point it at a resource request and it finds the cheapest cloud that can satisfy it right now. dstack manages a plane: dev environments, tasks, and services for a whole team, across the widest range of hardware. Pick the one whose unit matches yours.
SkyPilot: a price-and-availability optimizer for jobs#
SkyPilot (~10.5k stars, Apache-2.0, out of UC Berkeley's Sky Computing Lab) treats "which cloud" as a solver problem. You declare what the job needs; SkyPilot prices that request across 20+ backends — AWS, GCP, Azure, OCI, CoreWeave, Nebius, Lambda, RunPod, Vast.ai, plus Kubernetes and Slurm — and launches on the cheapest one with capacity.
# train.sky.yaml — one job description, any cloud
resources:
accelerators: H100:8
use_spot: true # managed spot, auto-recovered on preemption
any_of: # let the optimizer pick the cheapest with capacity
- cloud: runpod
- cloud: nebius
- cloud: lambda
workdir: .
run: |
python train.py
sky jobs launch -n train train.sky.yaml
The feature that earns SkyPilot its keep isn't the price search — it's what happens after launch. Managed spot jobs are the point: spot GPUs are the cheapest tokens of compute there are, and normally uselessly fragile, because a preemption kills your run. SkyPilot checkpoints, detects the preemption, and re-provisions the job on another region or cloud automatically — so you get the discount (its docs cite up to ~70%) without watching the job. Add autostop to kill idle clusters and auto-failover when a whole region is dry, and SkyPilot behaves like a cost-aware scheduler that happens to span every cloud you have credentials for. Its April-2026 GPU Compass dashboard makes the price comparison something you can browse before you even launch.
Reach for it when the unit you care about is the job, and the win is chasing the cheapest capacity wherever it lives — especially spot-heavy training, batch inference where a few minutes of latency doesn't matter, or a one-off agent job you want to run and forget.
dstack: a control plane for the whole team#
dstack (~2.2k stars, MPL-2.0) answers a bigger question than "where does this job run." It's a standing orchestration stack, and its four config types are a lifecycle, not a menu:
- Fleets — the compute layer: interconnected clusters or standalone hosts, cloud or on-prem, that everything else reuses.
- Dev environments — a remote IDE on a GPU, provisioned on demand.
- Tasks — batch and distributed jobs.
- Services — deployed models and web apps with replica autoscaling.
# .dstack.yml — a service, with autoscaling, in the same tool as your dev env
type: service
name: serve-llama
replicas: 1..4 # scale on load
resources:
gpu: H100:1
commands:
- python -m vllm.entrypoints.openai.api_server --model my/model
dstack apply -f .dstack.yml
Two things separate it from SkyPilot. First, hardware breadth: dstack treats NVIDIA, AMD, Google TPU, and Tenstorrent as first-class, and Kubernetes and bare metal as native backends — so if your compute isn't all NVIDIA, or lives partly on-prem, dstack speaks it. Second, it's built for a team to live in: the same YAML grammar takes you from a dev environment to a training task to an autoscaling service, so the thing you develop on is the thing you deploy on. It's the closest either tool gets to "Kubernetes for AI without the YAML tax."
Reach for it when the unit you care about is your team's compute plane — you want one durable place to develop, run, and serve, across mixed hardware — rather than the cheapest home for a single job.
The one-line decision#
Same shape as most infra choices: match the tool to the unit you actually manage.
- SkyPilot when the unit is the job: cheapest GPU with capacity right now, managed spot that survives preemption, the widest set of clouds. A cost optimizer that spans clouds.
- dstack when the unit is the plane: dev → task → service under one lifecycle, the broadest hardware neutrality, Kubernetes and bare metal as natives. A control plane that spans hardware.
They're not mutually exclusive, and both are free — you pay only the underlying cloud, so trying one costs a pip install and an afternoon. But don't adopt both to hedge; that's two control surfaces for one problem. Decide whether you're optimizing a job or operating a plane, pick the matching tool, and keep the job description portable — because the cloud you want to be on is a moving target, and the whole reason you're here is to never have to care which one you're on this week.



