kodebeat / papers / greenops

Measuring Software Carbon Intensity to ISO/IEC 21031

An SCI measurement CLI that prints every term of the formula.

Measures the Software Carbon Intensity of something you can point at, and prints every term of the formula separately with the source each came from, because a number a reviewer cannot argue with is not a disclosure. It takes the specification seriously: SCI is a rate, not a total, so nothing has one until something runs, and nothing is ever inferred from source code alone.

The problem

There is now a standard for this. The Green Software Foundation's Software Carbon Intensity specification is ISO/IEC 21031:2024, and it defines the quantity precisely:

SCI = ((E x I) + M) per R

Energy consumed, times the carbon intensity of the electricity, plus embodied emissions from the hardware, per functional unit. It is a good specification. It resolves the ambiguities that make carbon claims incomparable, in particular by insisting on a rate per functional unit rather than a total, so that "we reduced our footprint" cannot mean "we did less work".

Almost nobody computes it, for the ordinary reason: a specification is a document, and computing a figure from it means sourcing four quantities that live in four different places.

E, energy. Measurable at the socket with hardware most organisations do not have, or partially from the CPU's own counters. Otherwise modelled from CPU time and reserved capacity, which is legitimate and must be labelled as a model.

I, intensity. Depends on where and when the workload ran, which grid, and which of the four intensity definitions you use. Frequently a national annual average is substituted for an hourly regional figure without anyone saying so.

M, embodied. Manufacturing emissions of the hardware, amortised over its lifetime and shared across what runs on it. Requires a manufacturing figure, an assumed lifetime, a time share and a resource share: four assumptions, each of which a reviewer may dispute.

R, the functional unit. "Per what?" Per request, per image resized, per model trained. Choosing it is a modelling decision that determines whether the number means anything.

So SCI figures are produced by consultants for reports, once, with the working in an appendix. Because the working is not reproducible, the figure cannot be compared against next quarter's.

The method

Refuse to infer carbon from source code. The README states the consequence of SCI being a rate: a repository, a file or a function has no SCI until something runs. So every target either runs a workload and measures it, or reads a manifest in which you declare one. Nothing here estimates a codebase's carbon from reading it. The cost is that a repository with no runnable workload gets no number at all; sci-disclose repo says so rather than inventing one.

Print every term with its source. The README's example, quoted verbatim:

$ sci-disclose run --provider aws --region eu-west-1 --vcpus 2 --units 5000 \
      --unit-label "image resized" -- python3 resize-batch.py
sci: 1.732e-06 gCO2e per image resized

  target      python3 resize-batch.py
  ran in      1.66s wall, 1.66s CPU, 50% of 2 reserved vCPU, peak RSS 8 MB

  E  energy        2.223e-06 kWh [model]
  I  intensity     339 gCO2e/kWh
       Carbon Intensity API: Ireland consumption_lifecycle [measured],
       2026-08-21T14:30:00Z to 2026-08-21T15:00:00Z, via ENTSO-E (fetched)
  O  operational   0.000754 gCO2e   (E x I)
  M  embodied      0.007908 gCO2e
       1200 kg over 4 y, time-share 1.318e-08, resource-share 0.500
  C  total         0.008661 gCO2e   (O + M)
  R  per           5,000 x image resized
  ----------------------------------------------
  SCI             1.732e-06 gCO2e per image resized

  ! estimated from CPU time and reserved capacity, not measured at the socket

E is marked [model]. I names the source, the country, which of the four intensity definitions (consumption_lifecycle), the basis (measured), the half-hour window and the upstream provider (ENTSO-E). M shows its inputs (1200 kg over four years, a time share and a resource share) so each can be argued with separately. The closing line states the limitation of the measurement: estimated from CPU time and reserved capacity, not measured at the socket. A disclosure whose terms are hidden cannot be challenged, restated or compared.

Two energy backends, labelled. --energy auto|rapl|model defaults to auto. The rapl backend reads real joules from /sys/class/powercap/intel-rapl* on Intel and recent AMD under Linux; --idle-seconds samples the idle draw first so the report carries the workload's marginal energy. Where the counters are not readable (most cloud VMs, macOS, any host where they are root-owned), the model backend applies the Cloud Carbon Footprint linear model and the caveat line above says so.

Nine verbs, matching how software is actually shaped. Seven targets: a command (run), a script with the interpreter taken from its extension (file), a function called inside its own interpreter with an iteration count (func), a repository's own discovered workload (repo), a declared deployment that runs nothing (estimate), a manifest scaffolded from the repository's Kubernetes and Terraform (init), and a measurement divided by a count learnt afterwards (units). Two further verbs work on disclosures: compare gives the delta between two of them, and coefficients prints every constant the tool uses with its source.

The headline results

  • E, model backend.
  • E, RAPL backend.
  • I.
  • M.
  • What the tests assert.

The full results, with the tables and the reasoning behind each figure, are in the PDF.

What is in the PDF

  • The problem — what goes unanswered without it, and who notices first.
  • Why the obvious alternative falls short — stated plainly, including where it is the better choice.
  • How it works — the method, not a feature list.
  • Concrete use cases — with console output quoted from the repository, never reconstructed.
  • The methodology behind any number it emits — every term shown, so the figure survives a question.
  • What it deliberately does not do — the section most papers leave out.

Part of the GreenOps theme.

Get the PDF

This paper already selected; the download starts when you send the form. No follow-up sequence.

Get the PDF