GPUs are annoying. Shopify uses SkyPilot to make them less so: one YAML file, multiple clouds, clean development ergonomics.
Overview
Shopify uses SkyPilot, an open-source framework, to manage GPU-intensive ML training workloads across multiple cloud providers (Nebius and GCP). The article details their architecture including a custom SkyPilot plugin for intelligent routing, Kueue-based fair scheduling, automated InfiniBand configuration for H200 GPUs, cost tracking via labels, and developer-friendly environments — all while keeping engineers close to the metal with declarative YAML configs.
What You'll Learn
How to use SkyPilot to abstract multi-cloud GPU scheduling with a declarative YAML interface
How to build a SkyPilot plugin that routes workloads to different cloud providers based on GPU type
How to implement fair-share GPU scheduling across teams using Kueue on Kubernetes
How to automatically configure InfiniBand networking for H200 GPU workloads on Nebius
Why declarative YAML configs with policy plugins are preferable to elaborate platform UIs for ML infrastructure
Prerequisites & Requirements
- Understanding of Kubernetes clusters, pods, and job scheduling
- Familiarity with GPU types (H200, L4) and their use cases in ML training
- Experience running ML training workloads at scale
- Familiarity with YAML configuration files and declarative infrastructure
- Understanding of multi-cloud architecture concepts(optional)
- Basic understanding of InfiniBand and RDMA for GPU-to-GPU communication(optional)
Key Questions Answered
How does Shopify use SkyPilot for multi-cloud GPU workload management?
How does SkyPilot route GPU workloads to different cloud providers automatically?
How does Shopify handle GPU cost tracking and accountability across ML teams?
How does Kueue provide fair GPU scheduling across multiple teams on Kubernetes?
How does Shopify configure InfiniBand for H200 GPU workloads on Nebius?
What are SkyPilot development environments and how do they work at Shopify?
What is Shopify's GPU reaper and how does it optimize resource utilization?
Why does Shopify prefer YAML-based declarative configs over platform UIs for ML infrastructure?
Key Statistics & Figures
Technologies & Tools
Some links below are affiliate links. We may earn a commission if you make a purchase.
Key Actionable Insights
1Use a policy plugin architecture to inject organizational logic into your ML job scheduling system. By intercepting requests before they reach a cluster, you can validate labels, route to different providers, and inject configurations — all without changing the user-facing interface. This keeps the abstraction in the routing layer rather than the interface layer.Shopify's SkyPilot plugin handles routing, cost tracking, and configuration injection transparently, so engineers just write YAML and run sky launch without worrying about cloud-specific details.
2Enforce cost attribution at the platform level by requiring a cost-owner label on every job submission. Making cost tracking mandatory (rejecting jobs without it) ensures complete visibility into GPU spend without relying on manual processes or after-the-fact audits.Shopify requires showback_cost_owner_ref on every job. Teams see their costs in dashboards and self-correct usage patterns, eliminating the need for finance teams to chase down cost attribution.
3Implement shared caches for model weights and package dependencies across GPU jobs. The first download of a large model like llama-70b gets cached on shared storage, and subsequent jobs start instantly without re-downloading, which saves significant time at scale.Shopify mounts /mnt/uv-cache for Python packages and /mnt/huggingface-cache for model weights automatically, which adds up when running hundreds of jobs that share common dependencies.
4Deploy a GPU utilization reaper service that automatically terminates jobs running below a utilization threshold (e.g., 20%) for extended periods. This recovers wasted GPU resources from stuck or runaway training jobs, but make sure to exempt interactive development environments from this enforcement.Shopify's GPU reaper catches runaway training jobs while exempting dev environments, since low utilization during active debugging is expected and normal behavior.
5Use Kueue for Kubernetes-native fair-share GPU scheduling with a priority class hierarchy. Define priority tiers (emergency, interactive, automated-low-priority, lowest) that allow emergency jobs to preempt batch work and interactive sessions to schedule faster than automated pipelines.Kueue solved Shopify's fair scheduling problem better than anything they could have built in-house, handling quota-based scheduling and preemption across teams automatically.
6When designing multi-cloud GPU infrastructure, keep training data replicated across cloud providers so jobs run where the data already exists. This eliminates cross-cloud data transfer latency and keeps data under your control regardless of which provider runs the workload.Shopify replicates training datasets across clouds — when training on Nebius, data comes from local volumes; same for GCP — so the routing decision doesn't create a data movement problem.