CarbonBench


A public leaderboard and open API ranking AI models, providers and regions by carbon per million tokens, next to cost and speed.

Status

Ran in spring 2026. No longer maintained. The findings are published in five essays.

RoleYearKindTry it
Concept, data design, engineering2026AI, climateThe five essays
85models in the April 2026 dataset
9cloud regions across the US, EU and Asia Pacific
4 vs 50+grams of CO2 per million tokens for the same model in two regions

The problem

The carbon cost of an AI inference call changes by an order of magnitude depending on where and when you make it. Pricing pages do not show this.

What I built

  • A leaderboard. Every model, provider and region ranked by carbon per million tokens, next to cost and speed. Each row opened a 24-hour carbon curve for its region.
  • An open API. One endpoint answered one question: what is the lowest-carbon way to run this model right now? It returned the best option, four alternatives, and the saving against the dirtiest.
  • An hourly pipeline. A scheduled job recalculated every model, provider and region score from live grid data.

How it is structured

Carbon per million tokens is energy per token multiplied by grid carbon intensity.

In the code

Private repository

These are short excerpts from Beach-Bum/CarbonBench, which is private.

calculator.ts
schema.prisma
lib/calculator.ts
export function calculateCarbonPerMTokens(
  whPer1000Tokens: number,
  gco2PerKwh: number
): number {
  const kwhPerMTokens = (whPer1000Tokens / 1000) * 1000
  return kwhPerMTokens * gco2PerKwh
}

export function calculateBlendedCostPerMTokens(
  inputCostPerMToken: number,
  outputCostPerMToken: number,
  inputOutputRatio: number = 0.5
): number {
  return (inputCostPerMToken * inputOutputRatio) +
         (outputCostPerMToken * (1 - inputOutputRatio))
}

Where the numbers come from

InputSourceRefreshed
Energy per tokenThe Hugging Face AI Energy Score results: GPU energy for text generation, measured on an Nvidia A100When the import script is run
Grid carbonElectricity Maps, the latest carbon intensity for each cloud region's grid zoneEvery hour
PriceProvider price lists, entered by scriptBy hand. A weekly job is scheduled but was never built

The calculation is one multiplication: watt-hours per thousand tokens times grams of CO2 per kilowatt-hour gives grams of CO2 per million tokens. The units cancel, so no conversion factor is hiding in it.

The data model

Next.js 14 with Prisma on Postgres. Eight tables. Models, their energy benchmarks, regions, hourly grid readings, daily roll-ups of those readings, provider prices, the combined scores, and email sign-ups. There is exactly one score for each model, region and provider, and it is overwritten in place; that rule is the fix described under "What broke".

Three scheduled jobs were defined: grid readings hourly, the clean-up nightly at 03:00, prices weekly.

What the numbers leave out

  • Only the GPU. Cooling and the rest of the data centre are not counted, so real emissions are higher than these figures.
  • Reference hardware, not the provider's. Energy was measured once per model on an A100. A provider running different chips will differ.
  • The grid's average, not the provider's contract. A region's figure is its grid zone at that hour. Renewable purchase agreements are not reflected.
  • No automated tests. The project was five commits over a few weeks; the findings are only as good as the three inputs above.

These limits change the absolute numbers. They do not change the finding, because every model in a region is affected the same way: where and when a model runs moves its carbon cost more than which model it is.

What the data showed

  • Region beats model. Llama 3.1 8B on Google Cloud in the Netherlands: about 4 grams of CO2 per million tokens. The same model in Virginia at peak: over 50. A 70B model on a clean grid can beat an 8B model on a dirty one.
  • Price and carbon are decoupled. Providers charge the same per token regardless of region. Routing for carbon is close to free.
  • Time matters. Grid intensity swings 30 to 50% over a day. Batch work that can wait can run at the clean hours.
  • It is an indirect emission. Every API call is an emission the customer cannot see. Activity-based accounting needs exactly these conversion factors.

Open questions

More

Project notes on the weblog
Open ↗