# AI Trends Time-series charts on AI compute, economics, research and adoption, rebuilt daily from public sources and published to GitHub Pages. **→ https://stevenfazzio.com/ai-trends/** Every chart plots published numbers and links back to them. Almost all are someone else's. The exception is the energy-per-task chart: that was measured for this site, and is published with its method and raw data in [llm-energy-per-task](https://github.com/stevenfazzio/llm-energy-per-task), which the build reads like any other upstream. ## How it works A GitHub Actions job runs each morning, fetches every series in the registry, commits the result to `data/`, and deploys the static site. ``` src/ai_trends/ registry.py the list of charts -- the only file you edit to add one model.py SeriesSpec / Line / Axis build.py fetch -> data/*.json -> _site/ http.py shared session, retries, local response cache sources/ one module per upstream provider data/ committed output, one JSON per series cache/ committed intermediate counts (arXiv), so CI stays cheap manual/ hand-entered observations, one CSV per series, with citations site/ index.html, app.js, style.css -- rendered with Plotly events.toml model-release markers drawn across the charts ``` ### Two kinds of series Sources differ in whether they hand you history, and the pipeline treats them differently: - **`recompute`** — the upstream holds the full history (Epoch, METR, SEC, Census, OpenAlex, arXiv, Indeed, llm-energy-per-task). Every run rebuilds the series from scratch, so upstream revisions flow through. - **`append`** — the upstream only exposes a current value (OpenRouter pricing). Each run records one observation. These series have no history before collection started and can never be backfilled, which is why the job runs daily rather than on demand. ### Hand-entered series Some numbers have no feed at all. Public opinion polling is the case in point: Pew, Gallup and Ipsos publish their AI trend questions as prose and images, behind no API, and the figures move once or twice a year. Scraping that would be brittle for data this slow, so those observations live in `manual/*.csv`, one row per figure, each carrying the source and URL it came from. The loader refuses a row without a URL. If a number can't be traced to a published release, it doesn't belong in the file. ## Running it locally ```sh uv sync uv run python -m ai_trends.build # everything uv run python -m ai_trends.build --only nvidia-revenue uv run python -m ai_trends.build --fail-fast # stop on the first fetch error python3 -m http.server 8000 --directory _site ``` A failing upstream does not blank a chart: the previously committed JSON stays in place and the page shows a "last refresh failed" badge. The first build populates `cache/arxiv_monthly_counts.json` by asking arXiv for one count per category per month, at their requested one-request-per-three- seconds. That takes roughly half an hour once; afterwards only the trailing two months are refetched. ## Adding a chart 1. Write a function in `src/ai_trends/sources/` returning `list[Line]`. 2. Add a `SeriesSpec` to `SERIES` in `registry.py`. 3. `uv run python -m ai_trends.build --only your-new-id --fail-fast` The page is driven entirely by `data/manifest.json`; no front-end changes are needed. ## Sources | Series | Source | Licence | |---|---|---| | Task time horizon | [METR](https://metr.org/time-horizons/) | — | | Largest known training run, training power draw | [Epoch AI — models](https://epoch.ai/data/ai-models) | CC BY 4.0 | | Datacentre power capacity | [Epoch AI — data centers](https://epoch.ai/data/ai-data-centers) | CC BY 4.0 | | Compute per watt | [Epoch AI — hardware](https://epoch.ai/data/machine-learning-hardware) | CC BY 4.0 | | Cumulative equity raised, annualised revenue | [Epoch AI — companies](https://epoch.ai/data/ai-companies) | CC BY 4.0 | | Hyperscaler capex, NVIDIA revenue | [SEC EDGAR XBRL](https://www.sec.gov/edgar/sec-api-documentation) | public domain | | Token price index | [OpenRouter](https://openrouter.ai/docs/api-reference/list-available-models) | — | | Cheapest model at a fixed ARC-AGI score | [Epoch AI — benchmarks](https://epoch.ai/benchmarks), from the [ARC Prize leaderboard](https://arcprize.org/leaderboard) | CC BY 4.0 | | AI papers by country | [OpenAlex](https://openalex.org) | CC0 | | arXiv submissions | [arXiv API](https://info.arxiv.org/help/api/index.html) | — | | AI share of job postings | [Indeed Hiring Lab](https://github.com/hiring-lab/ai-tracker) | Hiring Lab terms | | Share of US businesses using AI | [Census Bureau — BTOS](https://www.census.gov/hfp/btos/data_downloads) | public domain | | American public opinion | [Pew](https://www.pewresearch.org/topic/internet-technology/emerging-technology/artificial-intelligence/), [Gallup](https://www.gallup.com/topic/artificial-intelligence.aspx) | hand-entered, cited per row | ## Not here yet **More capability benchmarks.** The group holds one chart, METR's time horizons. LMArena's HuggingFace mirror carries dated leaderboard CSVs from May 2023 but stopped updating in August 2025, so Elo history is available but stale, and the live source needs work. SWE-bench Verified is reconstructable from per-submission metadata in [SWE-bench/experiments](https://github.com/SWE-bench/experiments). ARC-AGI has no JSON endpoint — the leaderboard is embedded in the page payload. **Geographic splits** exist only where the upstream carries a country field: Epoch (organisation country), OpenAlex (author institutions), Indeed (per country, no China). Benchmarks, prices and arXiv have no usable country dimension, so those charts are single-region by necessity rather than choice. Epoch's datacentre coverage nominally has a country column, but 68 of the ~80 tracked sites are American, so splitting it would imply a comparison the data can't support. **Datacentre water use** is in Epoch's schema but populated for 10 of 441 timeline rows — too sparse to plot honestly. **Non-US polling** would need Ipsos' AI Monitor, which covers ~30 countries annually but publishes as PDF only.