Back to the post

Methodology & data provenance

Every datum traces to (a) recorded observation in our database, (b) reproducible computation from a public script, or (c) a primary source cited inline.

1. Measured inputs

These are recorded, not estimated. Re-runnable from the scripts in the source repository.

Gemini pipeline (real billed totals)

API calls8,032,886
Input tokens23,644,100,054
Output tokens6,921,374,368
Pages processed22,599,950 (page-credits; backfilled May 2026)
Real billed cost$19,588.33
Tracking window2026-01-02 → 2026-05-25 (144 days)
Project window2025-12-12 → 2026-05-25 (165 days, +15% scale-up)

Source: gemini_usage_daily MongoDB collection. Aggregated by scripts/gemini-usage-aggregate.mjs.

Claude Code (sampled)

Output tokens (extrapolated)138,702,028
Cache-read input tokens43,515,829,041
Cache-create input tokens1,602,566,493
Fresh input tokens10,540,005
Session files / total bytes4,811 / 1.55 GB
Sample fraction11.9% by bytes (±20% extrapolation)

Source: ~/.claude/projects/-Users-dereklomas-sourcelibrary/ JSONL session logs. Each contains assistant message usage blocks emitted by the Anthropic API.

2. Bottom-up energy model

Roofline analysis of transformer inference. Output tokens are memory-bandwidth-bound; input tokens are compute-bound; cache reads use ~10% of fresh input.[6][7]

Validated against MLPerf Inference v5.1 (Llama 3.1-70B on 8×H200 = 31,391 tok/s at ~5.6 kW = 0.178 J/output-tok).[5] Our model predicts 0.114 J/output-tok for that workload — within 36%, so we apply a 1.56× correction.

Source: scripts/co2-footprint-model.py

3. The six estimation lines

Each is independent. Each makes different assumptions. The geometric mean of all centrals is 1805 kg.

1. Pure roofline (peak optimum)

Roofline

63.2 kg195 kg
97.7 kg

Includes: Active accelerator power × FLOPs ÷ throughput. Peak batch, peak utilization, no overhead.

Excludes / caveats: Excludes datacenter PUE, idle machines, host CPU/DRAM, training amortization, embodied carbon, real-world overhead.

Theoretical floor — real production is always higher.

2. Roofline + comprehensive stack overhead

+Stack

109 kg336 kg
168 kg

Includes: Add Google's measured 1.72× factor for host CPU+DRAM, provisioned idle machines, datacenter PUE.

Excludes / caveats: Still excludes training amortization, embodied carbon, production-fleet inefficiencies.

Matches Google's published 'comprehensive' measurement boundary.

3. + MLPerf calibration + training + embodied

v4 model

220 kg679 kg
340 kg

Includes: Add MLPerf v5.1 calibration (×1.56), training amortization (×1.20), embodied carbon (×1.08). Total bridge 3.48×.

Excludes / caveats: Does not include production overhead beyond MLPerf benchmark conditions.

Our v4 bottom-up. Probably still too low for long-context production.

4. Google fleet measurement, decomposed by prompt

Google scaled

3562 kg8192 kg
5461 kg

Includes: Take Google's 0.24 Wh/median prompt. Split into fixed-per-prompt and per-token marginal cost. Apply to our prompt count and token count, scaled by model size ratio.

Excludes / caveats: Assumes our long-context workload follows the same per-token marginal as Google's short-prompt median. Could over-scale for long prompts.

Most direct extrapolation from a published production measurement.

5. Mistral LCA scaled by params

Mistral LCA

12.5 t41.7 t
20.8 t

Includes: Mistral Large 2 published LCA (Jul 2025, ADEME-audited): 2.85 mg CO2/token. Scale linearly by active params. Adjust for training amortization base size.

Excludes / caveats: Mistral's number includes a single model's training amortized over only 18 months. Anthropic/Google have larger amortization bases → lower training share per token.

Only published LCA for a frontier model. Upper-bound flavor.

6. API spend × electricity share

$ proxy

8517 kg262.9 t
54.4 t

Includes: Industry heuristic: electricity is 3-20% of provider cost. Real Gemini spend ($17,668) × elec share ÷ enterprise rate ($0.04-0.08/kWh). For Claude, use list-price equivalent (~$105K) × cost-to-list ratio (~30%).

Excludes / caveats: Sensitive to electricity-share assumption (5× swing between 3% and 20%). Provider margins on inference are debated.

Market-based sanity check. Wide range because variables are not well-known.

Source: scripts/co2-estimation-lines.py

4. Equivalents — conversion factors

Every "1805 kg equals X burgers" statement in the post uses the conversion factors below. Each is cited.

Unitkg CO₂e / unitRangePrimary source
🍔 Quarter-pound beef burger638Reducing food's environmental impacts through producers and consumers
🚗 Average European petrol car, per km0.180.140.22CO₂ performance of new passenger cars in Europe (2024 reporting cycle)
✈️ AMS ↔ LHR round-trip flight (economy)245130310atmosfair flight calculator
✈️ AMS ↔ NYC round-trip flight (economy)295017003500atmosfair flight calculator

5. All sources

Every [n] footnote in the post points here.

  1. 8.0 million Gemini API calls, 30.6 billion tokens, $19,588 spend, 22.6 million page-credits processed [measured]
    Source: gemini_usage_daily MongoDB collection, aggregated 2026-01-02 to 2026-05-23. page_count backfilled 2026-05-25 for ~748K legacy records (PR #2006 + #2009) that were missing the field due to pre-April 2026 direct-Mongo writers; translation page-credits ratio went from 0.45 to 1.83 pages/call after the fix. Token and cost totals were unaffected by the bug — only the per-call page-count attribution.scripts/gemini-usage-aggregate.mjs
  2. Claude Code: 139M output tokens, 43.5B cache-read tokens, 1.6B cache-create tokens [measured]
    Source: ~/.claude/projects/-Users-dereklomas-sourcelibrary/ session JSONL files; 11.9% byte-sample extrapolated to full corpusscripts/sample_tokens.py
  3. Median Gemini Apps prompt: 0.24 Wh energy, 0.03 g CO2e [cited]
    Source: Elsworth et al. (Aug 2025), 'Measuring the environmental impact of delivering AI at Google scale'
  4. Mistral Large 2: 1.14 g CO2e per 400-token response (2.85 mg/token full LCA) [cited]
    Source: Mistral AI (Jul 2025), 'Our contribution to a global environmental standard for AI'
  5. Llama 3.1-70B on 8×H200 = 31,391 tok/s offline = 0.18 J/output-tok [cited]
    Source: MLPerf Inference v5.1 results (Sep 2025)
  6. Decode is memory-bandwidth-bound; prefill is compute-bound [cited]
    Source: Roofline analysis of transformer inference; arXiv 2507.14397 'Efficient LLM Inference'
  7. Cache hits use ~90% less energy than full inference [cited]
    Source: Li et al. (2024), 'A Survey on Large Language Model Acceleration based on KV Cache Management'
  8. Claude Opus runs on AWS Trainium2 (Project Rainier, ~500K chips) [cited]
    Source: Data Center Dynamics (Oct 2025), 'AWS activates Project Rainier cluster'
  9. Anthropic has not disclosed Scope 1, 2, or 3 emissions [cited]
    Source: Stanford CRFM Foundation Model Transparency Index (Dec 2025)
  10. Geometric mean of six estimation methods: ~1,800 kg CO2e total [computed]
    Source: Computation across all six methods (see lines 1-6 in /methodology)scripts/co2-estimation-lines.py
  11. Beef: 60 kg CO2e per kg (global LCA median) [cited]
    Source: Poore & Nemecek (2018), Science
  12. EU passenger car fleet average: ~180 g CO2/km well-to-wheel [cited]
    Source: European Environment Agency, CO2 performance of new passenger cars (2024)
  13. AMS-LHR economy RT: ~245 kg CO2e with radiative forcing factor [cited]
    Source: atmosfair flight calculator + DEFRA 2024 conversion factors
  14. AMS-NYC economy RT: ~2,950 kg CO2e with radiative forcing factor [cited]
    Source: atmosfair flight calculator + DEFRA 2024 long-haul factor (0.149 kg/passenger-km)
  15. Dutch per-capita emissions: ~8.4 t CO2e/year [cited]
    Source: CBS (Centraal Bureau voor de Statistiek), 2024

6. What we don't know

  • Anthropic per-token energy. Not published. Required disclosure under California SB 253 begins in 2026.
  • Active parameter counts for Gemini Pro and Claude Opus. Best estimates ±50%.
  • Production batch sizes for major providers. Estimated 12-128 depending on workload type and latency target.
  • Grid intensity for Anthropic's deployment regions. We model 60% Project Rainier (Indiana, ~650 g/kWh) + 40% older AWS clusters (us-west-2 etc.). Mix may shift over time.
  • Training amortization beyond what is implicit in Mistral's LCA. No comparable disclosure from Anthropic / Google / OpenAI.
  • Long-context overhead factor for Claude Code. We apply ×2.0 based on TokenPowerBench (Dec 2025) which measured 3× per-token energy from 2K → 10K context. Source Library's ~155K-token contexts are extrapolated, not measured directly.

7. Known data-quality issues

During this audit, we found several issues in the upstream pipeline data. None invalidate the headline number, but worth knowing if you're reading deeply.

  • Translation page-count under-logging — FIXED 2026-05-25. The long-form translation endpoint had been logging ~0.45 page-credits per call (vs ~3 for OCR). Root cause: the batch-collector wrote page_count: successCount, which is the count of pages whose DB row was matched at result-collection time — zero for batches whose results were already collected on a prior pass. Separately, ~748K legacy gemini_usage records written before the April 2026 Supabase migration had page_ids populated but no page_count field. Both fixed in PRs #2006 and #2009, plus a backfill of the historical records. Translation ratio is now 1.83 pages/call, total page-credits 413K → 2.68M, consistent with the ~5.4M pages with translation text in the pages collection.
  • Two translation type labels in history. Older records use type: "translate" (per-page, manual scripts) and newer records use type: "translation" (long-form, batched context — current default). A 2026-03 normalization consolidated the active code paths but ~250K legacy translate rows remain. Both are summed in this post's totals.
  • Book-level status fields are abandoned (and now confirmed safe to delete). books.ocr_status and books.translation_status have 4 and 10 entries respectively across 46K books. Status is tracked per-page now (via the pages collection) and per-book progress via pages_ocr / pages_translated counters. The legacy fields are not in the active Book TypeScript schema and not read by any public route; safe to drop in a future cleanup PR.
  • Re-OCR rate is 1.18×, not 1.4×. Earlier drafts assumed more re-OCR than is actually happening. Now corrected. The page_revisions collection (164K rows) stores pre-overwrite snapshots, but only for pages that were re-OCR'd, so it can't derive an absolute rate by itself — the API-log ratio of 7.24M OCR page-credits ÷ 6.14M unique OCR'd pages is the authoritative source.
  • Per-book denominator: 14,295 books with index/summary generated in window. The carbon-per-book averages divide window-total tokens by this count. Alternatives — 28K visible books, 15K with any OCR, 17K with anypipeline_auto.last_updated in window — would shift the per-book number 10–40%. We use index-generation because that's the phase that fires the full enrichment pass (summary + chapters + quality + collection assignment).
  • Visual + Unknown language books may be OCR'd unnecessarily. 14,544 books with language=Visual (image-only manuscripts, alchemical plates) and 10,703 with language=Unknown have no OCR filter upstream — the pipeline runs Gemini on them and saves whatever auto-detect returns. Net impact on this post's totals is small because batch API discount is 50%, but it's wasted compute. Pending fix as of 2026-05-25.
  • Claude Code token totals are sampled, not exhaustive. 11.9% by bytes of the JSONL session logs, extrapolated linearly. Sampling error ~±20%. A full scan was attempted but stalled at 98% due to slow I/O on the project directory.

Reproduce this

All scripts at github.com/sourcelibrary/sourcelibrary/scripts. All data files in this repo's /data directory.

This library is built in the open.

If you spot an error, have a suggestion, or just want to say hello — we’d love to hear from you.