Running the dishwasher feels like a fixed cost: a cycle is a cycle, whenever you do it. In pounds, roughly true. In carbon, not at all. Every unit of electricity you draw is made by whatever happens to be running on the grid at that instant, and that mix lurches around through the day. A blustery small hour might be more than half wind; a still evening leans on gas. The same wash can cost you 90 grams of CO₂ or 300, purely on timing.
The good news is that this is not a secret. The National Grid's Electricity System Operator publishes the carbon intensity of the grid, in grams of CO₂ per kilowatt-hour, updated every half hour and forecast two days ahead, region by region, through a free and open API. No key, no sign-up. This page fetches that forecast live and works out when to run things. Below, the same steps in Python, so you can run it yourself.
01 Ask the grid what it is doing
One HTTP request does it. We ask for the regional forecast from now to 48 hours ahead; back comes a half-hourly figure for every region of Great Britain, each tagged with an index from very low to very high.
Pythonimport requests
from datetime import datetime, timedelta
now = datetime.utcnow()
frm = now.strftime("%Y-%m-%dT%H:%MZ")
to = (now + timedelta(hours=48)).strftime("%Y-%m-%dT%H:%MZ")
url = f"https://api.carbonintensity.org.uk/regional/intensity/{frm}/{to}"
data = requests.get(url, headers={"Accept": "application/json"}).json()
Loading the live forecast…
02 Two days, every region, at a glance
The response is a stack of half-hour intervals, each holding every region. Pivot it into a grid, regions down the side and time along the bottom, and colour each cell by its intensity, and the shape of the next two days jumps out: dark green troughs overnight and on windy afternoons, warmer bands at the evening peak. Scotland, awash with wind, sits green for days; gas-leaning corners of England flare amber.
Pythonimport numpy as np, matplotlib.pyplot as plt
intensity = {}
for interval in data["data"]:
for region in interval["regions"]:
name = region["shortname"]
intensity.setdefault(name, []).append(region["intensity"]["forecast"])
regions = list(intensity)
matrix = np.array([intensity[r] for r in regions]) # region x time
fig, ax = plt.subplots(figsize=(15, len(regions)))
c = ax.pcolor(matrix, cmap="viridis")
fig.colorbar(c, ax=ax, label="Carbon Intensity (gCO2/kWh)")
03 Find the greenest hours
We do not just want the single lowest point; we want a handful of good windows spread across the two days, so there is a realistic option near you. That is a trough-finding problem, and scipy already solves it: flip the signal upside down and run a peak finder. The prominence setting asks how deep a dip must be to count, which filters out the little wobbles and keeps the real lulls.
Pythonfrom scipy.signal import find_peaks
series = np.array(intensity["London"])
troughs, _ = find_peaks(-series, prominence=25) # dips of 25+ gCO2/kWh
for i in troughs:
print(times[i], series[i], "gCO2/kWh")
In practice a two-day regional forecast is smooth enough that a strict trough finder often returns just one dip, so the planner below takes the pragmatic cousin of the same idea: it grabs the cleanest half-hour, blocks out a few hours either side, and repeats, giving a handful of realistic, well-spread windows. Pick your region and what you want to run. It names the single greenest moment and totals the CO₂ you save by waiting for it instead of starting now.
Good windows coming up
04 So, when?
For most of Britain the honest answer is the small hours and the breezy middle of the day, and the honest saving is real but modest: shifting a dishwasher cycle from a dirty evening to a clean night spares a couple of hundred grams of CO₂, about the same as not driving a mile. Do it every day and it adds up; do it with the tumble dryer or an EV, which pull far more power, and a single well-timed session saves as much as a week of careful dishwashing.
Two caveats worth keeping. It is a forecast, so the further-out numbers drift, and it is marginal: you are timing your slice of demand against the grid's, not switching your own supplier. But the data is free, live, and public, and turning it into a decision took about thirty lines of Python. Not bad for a dishwasher.
If you enjoyed watching real code turn an API into a picture, its companion piece, Drawing Rudolph with Maths, runs the same spirit end to end: a photo, some numpy, and a Fast Fourier Transform.
The grid keeps changing under your feet. Now you can see it, and press start at the right moment.