We've written a lot here about carbon-aware scheduling: the signal debate, the mental models that don't transfer cleanly from software to electric grids and a three-part series of real training runs. But, what we hadn't done is put the whole thing in one place, start to finish. So we made a video.
The premise, in one example
Take a job that needs about 1/2 kWh on whatever hardware you've already got, running on the California ISO grid. At 1 AM, grid carbon intensity often sits near 330 gCO₂eq/kWh, so the job emits roughly 157 grams. At 1 PM, when solar is carrying much of the mix, intensity can drop below 110 gCO₂eq/kWh and the same job emits about 52 grams.
Same infrastructure, same job, same energy consumed even. About a third of the carbon. The only variable is when it ran.
What can actually move
The honest caveat comes early in the video, because it determines how useful this tooling may be to you. Plenty of work cannot wait: customer-facing APIs, most inference, 24/7 high-availability services. Those keep the default scheduler and nothing about them changes.
But a lot of what fills a cluster does have some slack: ML training and fine-tuning, batch pipelines, ETL and analysis, CI/CD, scheduled experiments. Those pods set schedulerName: compute-gardener-scheduler and we take it from there. In our experience that deferrable slice is usually a bigger share of total work than teams expect before they dig in.
How the decision loop works
Compute Gardener is an open-source secondary scheduler, deployed alongside the default rather than replacing it. Pods that don't ask for it don't even know it exists and it doesn't affect them in any way.
It implements the Kubernetes scheduler-plugins pattern across two stages. The PreFilter stage asks whether conditions are good enough right now, comparing live carbon intensity from the Electricity Maps API and your configured time-of-use price schedule against your thresholds. If the answer is no, the pod is re-enqueued through the ordinary Kubernetes mechanism and rechecked on the next cycle, typically a couple of times per minute. Once the grid gets cleaner or power gets cheaper, the pod moves to the Filter stage, where node hardware is assessed for suitability and capacity as usual. On binding, the grid intensity at that moment is recorded to the pod.
If conditions never improve, a maximum delay (24 hours by default) releases the pod anyway. Nothing waits forever.
What we measured
The video walks through the three experiments from the ML training series, none of which required application or training code changes:
| Experiment | Setup | Result |
|---|---|---|
| ResNet-50 | A week of training runs on one GPU, shifting dirtier-hour jobs to cleaner ones | Average intensity 231 → 165 gCO₂eq/kWh, ~30% less carbon |
| LoRA sweep | 21-job hyperparameter sweep fine-tuning Qwen2.5-Coder-7B on KubeRay, using three threshold tiers | ~40% less carbon |
| Spatial routing | The same 21 jobs routed across Ohio, Quebec and Norway | ~90% less carbon than the Ohio counterfactual |
That third one shifted where rather than when, and used routing strategies we're prototyping for the API rather than the scheduler itself. The Nordic grid won for every job at every hour.
Getting started
Installation is two commands: add the Helm repo, then install the scheduler into its own namespace with your Electricity Maps API key. The free tier covers a single grid region, which is enough to begin. After that nothing happens until a pod asks for the scheduler, so the blast radius is exactly the set of pods you opt-in.
Everything is configurable and nothing is required. You can run price-aware scheduling only, carbon-aware only or in dry-run mode, where nothing is shifted but the savings you would have captured are recorded. Dry-run is the honest way to size the opportunity before committing anything.
Beyond the defaults there are carbon and energy thresholds set globally, per namespace or per pod; several power modeling options including measured GPU power via NVIDIA DCGM, CPU profiles and a Green Software Foundation SCI-based model; Prometheus metrics and Grafana dashboards for both live and dry-run operation.
The Almanac API
The last section previews where this goes next. Our Almanac API extends the scheduler to blended cost and carbon optimization across both time and location, synthesizing grid intensity, cloud spot prices and forecasting signals into a single score. You set the weighting between cost and carbon, and change it whenever you like, which we've taken to calling the green-to-cheap knob.
The Almanac also produces a SHA-256 attested audit trail for multi-party verification of emissions mitigations, usable for carbon credit issuance, demand response participation or simply defensible internal numbers. As the video puts it: "savings you can't prove are just vibes."
Take a look
The full video runs under nine minutes. If it's relevant to your team, the getting started guide is the next step, and the scheduler is open-sourced on our GitHub page.
Your compute is ready to flex. It just needs permission.
