---
kind: concept
slug: carbon-aware-scheduling
title: Carbon-aware scheduling
summary: >-
  Choosing where and when to run a GPU job so that it emits less CO2, using the grid's marginal carbon intensity. Three levers: region choice, Flexible Start and Pause and Resume. A 2022 Azure study finds region matters most. Its gains come from simulations on 2020 historical data with perfect foresight, so they are upper bounds.
tags: [sustainability, carbon, cloud, scheduling]
papers: ["2206.05229"]
related: [llm-ethics]
status: draft
updated_at: 2026-11-01
---

## Overview

A cloud GPU job emits CO2 in proportion to the energy it uses and the carbon
intensity of the electricity at the place and time it runs. The same job can
therefore emit different amounts depending on its placement [arxiv:2206.05229
§3.1]. Carbon-aware scheduling means choosing that placement on purpose. The
key quantity is the marginal grid intensity, not the average one, because it
reflects what an extra unit of demand changes [arxiv:2206.05229 §2] [arxiv:2206.05229
§3.1].

The only invariant across the variants is the operational estimate: energy
for a step times the intensity for that step, summed over the run
[arxiv:2206.05229 §3.1]. The variants differ only in which steps the job is
allowed to use.

## Variants

All three variants below are simulations on historical intensity data with
perfect foresight. The paper treats the results as upper bounds, not as
deployed gains [arxiv:2206.05229 §6].

### Region choice

Run the job in the cloud region with the cleanest grid. This is a placement
decision made once, not a schedule. Across 16 Azure regions, the paper reports
an average of 34 to 128 gCO2eq per GPU-hour for the most and least efficient
region, and 200 to 755 gCO2eq per kWh [arxiv:2206.05229 §5.1]. The paper
reports region choice as the largest operational lever of the three
[arxiv:2206.05229 §6.1]. The intensity data covers 2020 only, and regions outside
North America, Europe and Australia are absent [arxiv:2206.05229 §6]. Card: [Measuring the Carbon Intensity of AI in Cloud Instances](/papers/2206.05229).

### Flexible Start

Pick a start time within the next N hours that minimises the job's total
emissions, then run to completion without interruption [arxiv:2206.05229 §6].
In the paper's 24 h window, the average gain over the year and 16 regions is
14.5% for BERT fine-tuning and 26.8% for DenseNet 121, but 0.5% for a 6.1 B
parameter Transformer [arxiv:2206.05229 tab. 4]. The gain is largest for short
jobs and smallest for long ones, which matches the paper's note that the
effect depends on job length [arxiv:2206.05229 §6.1]. Card: [Measuring the Carbon Intensity of AI in Cloud Instances](/papers/2206.05229).

### Pause and Resume

Run the job only in the cleanest intervals inside a window of N hours plus the
job's own duration, and pause in between [arxiv:2206.05229 §6]. The paper
assumes that pausing and resuming is instant and uses no extra energy, which
is an assumption and not a measurement [arxiv:2206.05229 §6]. With a 24 h
window the gain is 19.0% for BERT fine-tuning and 27.7% for DenseNet 121,
but 2.5% for the 6.1 B model [arxiv:2206.05229 tab. 4]. With a window equal to
100% of the job's duration, most workloads gain about 9.5% to 11.4%, while
DenseNet 121 gains only 2.0% [arxiv:2206.05229 tab. 5]. The largest gains in the
paper come from Pause and Resume, but they rely on a long window and a
perfect-foresight oracle. Card: [Measuring the Carbon Intensity of AI in Cloud Instances](/papers/2206.05229).

## When to use which

| Situation | Use | Why |
|---|---|---|
| You can pick the cloud region and the job is latency-insensitive | Region choice first | The paper finds region the largest lever [arxiv:2206.05229 §6.1]; it is a one-time decision. |
| The job has a deadline and must run in one block | Flexible Start | The job is not interrupted, and the paper reports a gain for short jobs [arxiv:2206.05229 tab. 4]. |
| The job can checkpoint and resume cheaply | Pause and Resume | Gains are larger at longer windows [arxiv:2206.05229 tab. 5], but the zero-cost pause is untested [arxiv:2206.05229 §6]. |
| Long training run (the paper's 6.1 B model, 192 h) | Do not rely on the reported gains | That model gains 0.5% to 2.5% at 24 h [arxiv:2206.05229 tab. 4], and its full-run energy is extrapolated from a partial run [arxiv:2206.05229 §4]. |
| Forecast is unavailable or unreliable | Treat results as an upper bound | The study uses historical intensity with perfect foresight; WattTime forecasts cover 24 h [arxiv:2206.05229 §6]. |
| Time of day only, no other freedom | Expect small effects | A single BERT run on three days in one region shows up to about 8% difference, which the paper calls thin evidence [arxiv:2206.05229 §5.2] [arxiv:2206.05229 tab. 3]. |

## Implementation sketch

The paper's Flexible Start and Pause and Resume both reduce to a choice over a
window of per-interval intensities. The sketch below is our own, using
5-minute steps as the paper does [arxiv:2206.05229 §6].

```pseudocode
# Operational emissions of one job  [arxiv:2206.05229 §3.1]
# Input:  energy (T,) kWh per 5-min step; intensity (T,) gCO2eq/kWh
def job_emissions(energy, intensity):
    # Sum of energy times intensity over all steps
    return sum(energy * intensity)

# Flexible Start: one contiguous run, best start in the window  [arxiv:2206.05229 §6]
def best_start(intensity, job_energy):
    best, best_total = None, float("inf")
    for start in range(len(intensity) - len(job_energy) + 1):
        # Replay the job's energy profile from this start step
        total = sum(job_energy[k] * intensity[start + k]
                    for k in range(len(job_energy)))
        if total < best_total:
            best, best_total = start, total
    return best

# Pause and Resume: cleanest steps until the run time is covered  [arxiv:2206.05229 §6]
def cleanest_steps(intensity, duration_steps):
    # Rank steps by marginal intensity and keep the lowest ones
    ranked = sorted(range(len(intensity)), key=lambda i: intensity[i])
    return sorted(ranked[:duration_steps])
```

Where the variants differ: Flexible Start keeps the job contiguous; Pause and
Resume may split it. The paper does not say how a measured energy profile maps
onto non-contiguous steps. The sketch assumes the profile is replayed in order,
which is our inference [arxiv:2206.05229 §6].

## Contradictions

Within the single source so far. No second paper is in the wiki yet.

- **Relative-extension gain.** The caption of a DenseNet/6 B figure says
  doubling the duration can save "up to about 25%" [arxiv:2206.05229 fig. 4].
  The averaged 100% result in the table is 11.4% for the 6.1 B model
  [arxiv:2206.05229 tab. 5]. The caption does not say whether the 25% refers to
  one region or one month.
- **BERT fine-tune energy.** The text gives 3.2 kWh [arxiv:2206.05229 §4]; the
  table gives 3.1 kWh [arxiv:2206.05229 tab. 2].
- **BERT size.** The energy measurement uses BERT-base [arxiv:2206.05229 §3.2];
  the pretraining and finetuning runs are described as BERT-small
  [arxiv:2206.05229 §4]. The paper does not say which size gives the 37.3 kWh
  pretraining energy.

## Papers

- [Measuring the Carbon Intensity of AI in Cloud Instances](/papers/2206.05229):
  defines the operational emissions estimate on Azure GPU jobs and simulates
  region choice, Flexible Start and Pause and Resume over 16 regions.
