1. Measured inputs
These are recorded, not estimated. Re-runnable from the scripts in the source repository.
Gemini pipeline (real billed totals)
| API calls | 8,032,886 |
| Input tokens | 23,644,100,054 |
| Output tokens | 6,921,374,368 |
| Pages processed | 22,599,950 (page-credits; backfilled May 2026) |
| Real billed cost | $19,588.33 |
| Tracking window | 2026-01-02 → 2026-05-25 (144 days) |
| Project window | 2025-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 tokens | 43,515,829,041 |
| Cache-create input tokens | 1,602,566,493 |
| Fresh input tokens | 10,540,005 |
| Session files / total bytes | 4,811 / 1.55 GB |
| Sample fraction | 11.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
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
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
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
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
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
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.
| Unit | kg CO₂e / unit | Range | Primary source |
|---|---|---|---|
| 🍔 Quarter-pound beef burger | 6 | 3–8 | Reducing food's environmental impacts through producers and consumers |
| 🚗 Average European petrol car, per km | 0.18 | 0.14–0.22 | CO₂ performance of new passenger cars in Europe (2024 reporting cycle) |
| ✈️ AMS ↔ LHR round-trip flight (economy) | 245 | 130–310 | atmosfair flight calculator |
| ✈️ AMS ↔ NYC round-trip flight (economy) | 2950 | 1700–3500 | atmosfair flight calculator |
5. All sources
Every [n] footnote in the post points here.
- 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
- 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 corpus↻ scripts/sample_tokens.py
- 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' ↗
- 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' ↗
- 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) ↗
- Decode is memory-bandwidth-bound; prefill is compute-bound [cited]Source: Roofline analysis of transformer inference; arXiv 2507.14397 'Efficient LLM Inference' ↗
- 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' ↗
- Claude Opus runs on AWS Trainium2 (Project Rainier, ~500K chips) [cited]Source: Data Center Dynamics (Oct 2025), 'AWS activates Project Rainier cluster' ↗
- Anthropic has not disclosed Scope 1, 2, or 3 emissions [cited]Source: Stanford CRFM Foundation Model Transparency Index (Dec 2025) ↗
- 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
- Beef: 60 kg CO2e per kg (global LCA median) [cited]Source: Poore & Nemecek (2018), Science ↗
- EU passenger car fleet average: ~180 g CO2/km well-to-wheel [cited]Source: European Environment Agency, CO2 performance of new passenger cars (2024) ↗
- AMS-LHR economy RT: ~245 kg CO2e with radiative forcing factor [cited]Source: atmosfair flight calculator + DEFRA 2024 conversion factors ↗
- 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) ↗
- 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 legacygemini_usagerecords written before the April 2026 Supabase migration hadpage_idspopulated but nopage_countfield. 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 thepagescollection. - Two translation type labels in history. Older records use
type: "translate"(per-page, manual scripts) and newer records usetype: "translation"(long-form, batched context — current default). A 2026-03 normalization consolidated the active code paths but ~250K legacytranslaterows remain. Both are summed in this post's totals. - Book-level status fields are abandoned (and now confirmed safe to delete).
books.ocr_statusandbooks.translation_statushave 4 and 10 entries respectively across 46K books. Status is tracked per-page now (via thepagescollection) and per-book progress viapages_ocr/pages_translatedcounters. 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_revisionscollection (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 any
pipeline_auto.last_updatedin 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 withlanguage=Unknownhave 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.