We talk about AI infrastructure as buildings and GPUs. Those buildings still plug into a regional grid. This page is the twin ofThe Buildings Behind AI: that one counts facilities; this one watches what is generating, whether demand beat the forecast, and how little spare capacity is left. Pick a region and a week. Read the system, not a national percentage.
Power under the models · ERCOT
The grid is the real AI infrastructure
Electric Reliability Council of Texas. West Texas and Central Texas cloud build-out. Fuel mix tells you what is running. Spare capacity tells you how close the system is to trouble. Keep those questions separate.
SNAPSHOT · ERCOT2026-07-08 04:00 CTHeat peak
Showing a fixed ERCOT week (saved 2026-07-10T18:00:00-05:00). Not a live feed.
A hot week. Demand runs above the day-ahead forecast into the evening, and spare capacity gets thin—even while gas and solar rearrange under the stack.
ERCOT, last hour in view: demand 53,506 MW, spare capacity about +1.6%, mostly Natural gas (47%), 12,455 MW below the day-ahead forecast.
Demand-12,455 MW vs forecast
53.5KMW
ERCOT, last hour in view: demand 53,506 MW, spare capacity about +1.6%, mostly Natural gas (47%), 12,455 MW below the day-ahead forecast.Spare capacityRough, from public series
+1.6%
Higher is more comfortable. See the methods note for what this number is and is not.Largest fuelNatural gas
47%
Natural gas is the largest share of generation.Demand versus forecast
Amber = hotter than forecast · cyan = coolerERCOT: demand versus day-ahead forecast
Where load ran high or low against what the day-ahead schedule expected
What is generating
Stacked by fuel · not emissionsSpare capacity over the week
Brush the strip below to zoomBrush the lower strip to focus part of the week.
Tightest hours
Hatched bars are the danger band · color is not the only cueHow to read spare capacity
- Comfortable · 20% or more
- Watch · 12% to 20%
- Tight · under 12% (hatched)
Spare capacity here is a simple estimate: generation plus imports, minus demand, as a percent of demand. It is good enough to teach the shape of a tight evening. It is not the official contingency reserve a control room uses. The data is a fixed week shaped like EIA Hourly Grid Monitor series—not a silent empty chart, and not pretending to be live. Emissions are out of scope on purpose; fuel mix is not a carbon ledger. The math helpers live in semiotic/recipes so you can reuse them outside this page.
Why these charts (and what the suggestion engine picks)
We already chose the layout. This drawer asks Semiotic’s suggestion engine the same question on the demand-versus-forecast table—does it land near the same forms?—and prints a short plain-language read for anyone who cannot see the charts.
- EventDropChart — score 3.00 · Strong fit for change-detection (3/5)
- Scatterplot · [object Object] — score 0.60 · x = demandMw, y = t
- BubbleChart — score 0.60 · x = demandMw, y = t
- Histogram · [object Object] — score 0.00 · x = demandMw, y = t
A difference chart of y by t. This is a trend chart; read it for the overall direction of y.
Fields it noticed:demandMw, t, forecastMw
Regions: ERCOT, CAISO, PJM, NYISO · 5 weeks to replay · companion to The Buildings Behind AI
JSX
import { stackFuelSeries, demandForecastRows, reserveSeries, thresholdBandsForReserve, summarizeOperatingPoint, gridEventAnnotations, } from "semiotic/recipes" import { applyAnnotationLifecycle } from "semiotic/ai" import { DifferenceChart, StackedAreaChart, MinimapChart } from "semiotic" import { BarChart } from "semiotic/ordinal" import { BigNumber } from "semiotic/value" // Pure helpers turn BA hours into chart-ready series — agents import the same // pipeline, not a 2k-line page fork. const fuelStack = stackFuelSeries(hours) // StackedAreaChart const demandForecast = demandForecastRows(hours) // DifferenceChart a/b const reserves = reserveSeries(hours) // Minimap + risk bars const operating = summarizeOperatingPoint(hours) const styleRules = thresholdBandsForReserve({ tight: 5, watch: 12 }) const annotations = applyAnnotationLifecycle( gridEventAnnotations(events), { dataExtent: [hours[0].t, hours.at(-1).t] }, ) <DifferenceChart data={demandForecast} xAccessor="t" seriesAAccessor="a" seriesBAccessor="b" seriesALabel="Demand" seriesBLabel="Forecast" seriesAColor="var(--semiotic-warning)" seriesBColor="var(--semiotic-info)" /> <StackedAreaChart data={fuelStack} xAccessor="t" yAccessor="mw" areaBy="fuel" colorScheme={FUEL_COLOR_MAP} /> <BarChart data={tightestHours} categoryAccessor="label" valueAccessor="reserveMarginPct" styleRules={styleRules} // hatch on the tight band />