Technical writing
EIA Electricity Data: The Federal Dataset Behind Every Kilowatt-Hour Generated, Sold, and Priced
The Energy Information Administration runs the most comprehensive mandatory reporting system for the United States electricity sector outside of the regulated utility filings themselves. Every significant generator, every distribution utility, and every grid operator feeds data into EIA's three primary electricity collections: Form 923 for plant-level monthly operations, Form 861 for utility-level annual financials, and the EIA-930 Hourly Electric Grid Monitor for real-time grid operations. All of it is free, public, and bulk-downloadable. The result is an unbroken quantitative record of how American electricity has been generated, delivered, and priced — a record that makes the transformation of the US power grid from coal to gas, wind, and solar legible at the level of individual power plants.
What EIA Electricity Data Is
EIA electricity data is mandatory, not voluntary. Any power plant with 1 megawatt or more of nameplate capacity must report monthly generation, fuel consumption, and heat rates through Form 923. Any electric utility making retail sales must file annual financial and operational data through Form 861. Any balancing authority — the grid operators who dispatch generators in real time — feeds hourly data into the EIA-930 system. Failure to report carries civil penalties, which means the coverage is essentially universal for the regulated electricity sector.
Three datasets collectively describe the full electricity supply chain. Form 923 covers the production side: what plants generated, what fuel they burned, how efficiently, and what that fuel cost. Form 861 covers the delivery and retail side: how much electricity utilities sold to residential, commercial, and industrial customers, at what average price, and through what programs. EIA-930 covers the real-time grid operations layer: how much each balancing authority generated by fuel type each hour, and how much power flowed between neighboring balancing authorities. Historical data is free to download in bulk CSV and JSON formats from eia.gov/electricity.
EIA Form 923 — Power Plant Operations
Form 923 is the plant-level operational record. Every power plant at or above the 1 MW nameplate threshold submits monthly data identifying the plant by EIA Plant Code (a persistent integer identifier), operator ID, state, county, and NERC reliability region. The core monthly data elements are net generation in megawatt-hours broken down by prime mover and fuel type, fuel consumption in physical units (tons for coal, thousand cubic feet for natural gas, barrels for oil), heat rate in BTU per net kWh, and fuel cost per million BTU.
The fuel types tracked include coal, natural gas, nuclear, conventional hydroelectric, pumped hydro, wind, utility-scale solar PV, geothermal, biomass, landfill gas, petroleum liquids, and a residual “other” category. This classification makes it possible to track each fuel's share of monthly generation at the plant level — which plants ran, how much they produced, and at what heat rate — rather than relying on aggregate national estimates. Annual bulk CSV files go back to 2001 and are structured so that joining on Plant Code links Form 923 generation data to the Form 860 generator inventory for the same plant.
The heat rate field is analytically underappreciated. Heat rate — BTU consumed per net kWh sent to the grid — is the primary measure of a thermal plant's efficiency. A natural gas combined cycle plant typically achieves 6,000–7,000 BTU/kWh. A subcritical pulverized coal steam unit typically runs 9,500–11,000 BTU/kWh. Combined with the fuel cost per million BTU, heat rate directly determines a plant's variable cost of generation — the minimum electricity price at which it is worth dispatching. A plant with a high heat rate and high fuel costs will be pushed off the dispatch stack first when electricity prices fall.
EIA Form 861 — Utility Annual Data
Form 861 shifts the unit of analysis from the power plant to the distribution utility. Every electric utility making retail electricity sales files annually, reporting electricity sales in megawatt-hours, revenues in dollars, and customer counts broken into four sectors: residential, commercial, industrial, and transportation (the last covering EV charging infrastructure and electric rail). Dividing revenue by sales yields the average retail price of electricity by sector, utility, and state — the most widely cited figure in energy economics and state regulatory proceedings.
Form 861 data goes back to 1990. The three decades of coverage make it possible to track how state-level electricity prices have evolved relative to national averages, how industrial load has shifted geographically as energy-intensive manufacturing has moved or closed, and how the residential electricity price gap between high-cost states (Hawaii, California, Massachusetts) and low-cost states (Idaho, Louisiana, Oklahoma) has widened or narrowed over time.
Beyond the core sales data, Form 861 also collects net metering customer counts and aggregate capacity — the rooftop solar footprint — broken down by utility and state. It collects demand response program participation: how many megawatts of load utilities have under contract to curtail during system stress events, and how much load was actually curtailed. It collects advanced metering infrastructure (smart meter) deployment. And it collects green pricing and renewable energy certificate program data: how many customers have voluntarily subscribed to renewable energy programs and at what premium. Together these fields make Form 861 a comprehensive annual census of the retail electricity market.
EIA-930 — Hourly Electric Grid Monitor
The EIA-930 Hourly Electric Grid Monitor is the real-time grid layer. Every balancing authority in the United States — there are approximately 65 covering the contiguous grid — reports hourly demand, net generation, and interchange flows to EIA. Data is published roughly one hour after the operating hour, making this the only publicly available near-real-time view of the US grid at the balancing authority level.
The major balancing authorities tracked include CAISO (California), MISO (Midwest), PJM (Mid-Atlantic and parts of the Midwest), ERCOT (Texas), NYISO (New York), ISONE (New England), and SPP (the Great Plains). Each BA reports total demand and net generation; from 2019 onward, EIA-930 also includes generation broken down by fuel type, making it possible to track the hourly mix of coal, gas, nuclear, wind, solar, and hydro for each BA in near-real time.
Historical hourly data is available for download in bulk CSV format back to 2015 for demand and interchange and to 2019 for generation by fuel type. The EIA-930 API is accessible at https://api.eia.gov/v2/electricity/rto/ and requires a free API key. Sub-routes include /rto/daily-region-data/ for daily BA demand and generation summaries, /rto/region-sub-ba-data/ for interchange flows between BAs, and /rto/fuel-type-data/ for hourly generation by fuel type. The EIA-930 data is the correct tool for analyzing grid events: a sudden drop in solar output in CAISO during a heat event, a wind drought across SPP during winter, or the moment-by-moment generation collapse in ERCOT during the 2021 Uri winter storm.
The Grid Transformation Story in the Data
The most consequential story in EIA electricity data over the past twenty-five years is the transformation of the US generation mix. In 2000, coal provided approximately 52 percent of US electricity generation. Natural gas provided about 17 percent. Nuclear was roughly 20 percent. Wind was less than 0.1 percent. Utility-scale solar was effectively zero. By 2023, coal had fallen to approximately 16 percent of generation. Natural gas had risen to roughly 43 percent, lifted by the shale revolution that made gas persistently cheap after 2008. Wind had grown from negligible to around 10 percent. Solar — utility-scale plus small-scale rooftop, which EIA tracks separately — had reached approximately 5.5 percent. Nuclear remained remarkably stable at 18–19 percent despite plant retirements, because the remaining fleet operates at capacity factors above 90 percent.
This transformation is visible at the plant level in Form 923. The coal units that generated hundreds of terawatt-hours in 2005 appear in the data with declining capacity factors through the early 2010s as cheap gas began displacing them in dispatch merit order, then with retirement dates as economics and environmental regulations made continued operation untenable, and finally disappear from the active generation records. The wind farms that began appearing in Texas, Iowa, and the Great Plains in the mid-2000s accumulate in the Form 860 inventory as their capacity additions are reported each year. The solar farms that barely registered before 2013 and then exploded after 2018 as module costs collapsed are recorded with installation dates, nameplate capacities, and locations that tell the geographic story of where the build-out happened and at what pace.
Nuclear deserves particular attention. From 2000 to 2023, the US retired a substantial number of nuclear reactors — Vermont Yankee, San Onofre, Oyster Creek, Pilgrim, Three Mile Island Unit 1, Indian Point 2 and 3, and others. Yet nuclear's share of generation barely moved. The explanation is capacity factor: the remaining operating reactors run at 90–93 percent capacity factors, generating more actual electricity per megawatt of nameplate capacity than any other technology. Nameplate capacity statistics understate nuclear's contribution to the grid; generation statistics capture it correctly.
EIA API v2 Structure
The EIA Open Data API is at https://api.eia.gov/v2/ and requires a free API key obtained at eia.gov/opendata/. The API uses a faceted query structure where callers specify a data route, filter dimensions using facets parameters, and request one or more data columns using the data[] parameter array syntax. Pagination is handled through offset and length parameters.
The principal electricity routes are:
/electricity/retail-sales/— utility retail electricity sales, revenues, customer counts, and average prices by state, sector, and utility. Corresponds to Form 861 data. Frequency options: monthly and annual./electricity/facility-fuel/— plant-level generation and fuel consumption by fuel type and prime mover. Corresponds to Form 923 data. Useful for pulling generation history for a specific plant by filtering on the EIA plant code facet./electricity/electric-power-operational-data/— aggregate monthly generation by fuel type and sector (utility, independent power producers, combined heat and power) at the national and state levels. The route used in the Python example below./electricity/rto/daily-region-data/— daily demand and generation by balancing authority from EIA-930. Good starting point for BA-level analysis without the volume of full hourly data./electricity/state-electricity-profiles/— state-level electricity generation summaries, capacity, and retail price data compiled into annual state profiles.
The API returns JSON with a response.data array and aresponse.total count. When total exceeds the page length (maximum 5,000 records per request), callers must increment the offset and fetch additional pages. Rate limits are not published but the API handles reasonable analytical workloads without throttling.
ERCOT and Texas Grid Isolation
ERCOT — the Electric Reliability Council of Texas — is the balancing authority for roughly 90 percent of Texas load. It is also the only major US grid operator that is substantially isolated from both the Eastern Interconnect and the Western Interconnect, connected to neighboring grids only through a small number of direct current ties that limit interchange capacity. This isolation was a deliberate political choice: by avoiding substantial interstate electricity commerce, ERCOT sidesteps FERC jurisdiction and remains regulated primarily by the Texas Public Utility Commission under state law rather than federal oversight.
The practical consequence of ERCOT's isolation is that Texas cannot easily import power during emergencies. The February 2021 Winter Storm Uri illustrated this catastrophically. Extreme cold disabled natural gas wellhead equipment and pipelines that had not been weatherized, cutting off fuel supply to gas generators. Wind turbines without cold-weather packages iced up. Two nuclear units tripped offline. ERCOT demand surged as residents ran electric heating continuously. The grid came within minutes of an uncontrolled cascading collapse that would have left millions without power for weeks rather than days.
EIA-930 data recorded the collapse in real time: ERCOT generation dropped precipitously over the nights of February 10–11, 2021 while demand remained elevated. Form 923 data for ERCOT-connected plants documents the generation outages at the plant level — which gas plants went offline, when they restarted, and what their generation looked like in the months before and after. The final toll was 246 deaths directly attributed to the storm and an estimated $200 billion or more in economic damages. The EIA data provides the empirical foundation for every analysis of what went wrong and what weatherization standards would prevent a recurrence.
Power Plant Retirements and Additions
EIA Form 860 is the definitive public inventory of every US generator's status: operating, retired, on standby, under construction, or in the planning pipeline. The Form 860 annual file includes both the current generator roster and a detailed schedule of planned additions and retirements extending several years forward, based on utility filings and interconnection queue data. Key fields include Plant ID, generator ID, prime mover code, energy source codes, nameplate capacity in megawatts, commercial operation date, planned retirement date (if announced), operational status code, and latitude/longitude of the plant.
The post-2015 coal retirement wave is visible across multiple dimensions in Form 860. The volume of retirements accelerated after the EPA finalized the Mercury and Air Toxics Standards in 2012, which imposed compliance capital costs on old coal units. Low natural gas prices reduced the revenue coal units could earn in competitive wholesale markets. State renewable portfolio standards created policy pressure and economic opportunity for utilities to replace coal with wind and solar. Form 860 shows the wave: hundreds of coal units transitioning from operational to retired status between 2015 and 2024, concentrated in the Midwest coal belt — Illinois, Indiana, Ohio, Kentucky, Missouri — and in the Southeast.
On the additions side, Form 860's planned capacity data and interconnection queue data document the pipeline of solar, wind, and battery storage projects. As of the mid-2020s, the interconnection queues for most ISOs and RTOs contained hundreds of gigawatts of solar and battery storage projects seeking grid connection, far exceeding what will ultimately be built given permitting, financing, and interconnection delays. Form 860 tracks which projects have received interconnection agreements and moved into the under-construction status — a significantly smaller set that is more predictive of actual additions within a 2–3 year window.
Python: Monthly Generation by Fuel Type, 2010–2024
The following script uses the EIA API v2 to pull monthly net generation by fuel type for the entire United States from January 2010 through December 2024. It then computes each fuel's share of total tracked monthly generation and produces a stacked area chart that makes the fuel mix transformation visible. The 12-month rolling mean applied before plotting removes seasonal variation — summer peaks in gas generation, spring peaks in hydro, winter lows in solar — so the structural multi-year trend in each fuel type is the dominant visual signal.
import requests
import pandas as pd
import matplotlib
matplotlib.use("Agg")
import matplotlib.pyplot as plt
EIA_API_BASE = "https://api.eia.gov/v2/electricity/electric-power-operational-data/data/"
# EIA fuel type facet codes for Form 923 monthly generation series
# COW = coal, NG = natural gas, NUC = nuclear
# WND = wind, SUN = solar, HYC = conventional hydroelectric
FUEL_CODES = ["COW", "NG", "NUC", "WND", "SUN", "HYC"]
LABEL_MAP = {
"COW": "Coal",
"NG": "Natural Gas",
"NUC": "Nuclear",
"WND": "Wind",
"SUN": "Solar",
"HYC": "Hydroelectric",
}
def fetch_monthly_generation(api_key, start="2010-01", end="2024-12"):
"""
Pull net generation (thousand MWh) from EIA API v2.
Sector 99 = all sectors combined. Location US = national.
Paginates automatically until all records are retrieved.
"""
params = {
"api_key": api_key,
"frequency": "monthly",
"data[0]": "generation",
"facets[fueltypeid][]": FUEL_CODES,
"facets[sectorid][]": ["99"],
"facets[location][]": ["US"],
"start": start,
"end": end,
"sort[0][column]": "period",
"sort[0][direction]": "asc",
"offset": 0,
"length": 5000,
}
records = []
while True:
resp = requests.get(EIA_API_BASE, params=params, timeout=30)
resp.raise_for_status()
body = resp.json()
page = body["response"]["data"]
records.extend(page)
total = body["response"]["total"]
params["offset"] += len(page)
if params["offset"] >= total or not page:
break
df = pd.DataFrame(records)
df["period"] = pd.to_datetime(df["period"])
df["generation"] = pd.to_numeric(df["generation"], errors="coerce")
return df
def compute_fuel_shares(df):
"""
For each month, compute each fuel type's share of total generation
across the six tracked fuel codes.
Returns a pivot table: index = period, columns = fuel code, values = share (0-1).
"""
pivot = df.pivot_table(
index="period",
columns="fueltypeid",
values="generation",
aggfunc="sum",
).sort_index()
row_totals = pivot.sum(axis=1)
shares = pivot.div(row_totals, axis=0)
return shares
def plot_fuel_mix_transition(shares, output_path="eia_fuel_mix.png"):
"""
Stacked area chart of monthly fuel share, 2010-2024.
Uses a 12-month rolling mean to smooth seasonal variation.
Coal decline and wind+solar rise are the dominant visual signals.
"""
smoothed = shares.rolling(12, center=True).mean().dropna()
fig, ax = plt.subplots(figsize=(13, 6))
# Stack order: coal at bottom, gas above, then nuclear, hydro, wind, solar at top
stack_order = ["COW", "NG", "NUC", "HYC", "WND", "SUN"]
cols_present = [c for c in stack_order if c in smoothed.columns]
labels = [LABEL_MAP.get(c, c) for c in cols_present]
ax.stackplot(
smoothed.index,
[smoothed[c] * 100 for c in cols_present],
labels=labels,
alpha=0.85,
)
ax.set_ylabel("Share of tracked generation (%)")
ax.set_xlabel("Month")
ax.set_title("US Electricity Generation Mix, 2010-2024 (12-mo rolling avg)")
ax.legend(loc="upper left", fontsize=9)
ax.set_ylim(0, 100)
plt.tight_layout()
plt.savefig(output_path, dpi=150)
print("Saved chart to " + output_path)
return smoothed
# --- Usage ---
# Replace with your free EIA API key from https://www.eia.gov/opendata/
# api_key = "YOUR_EIA_API_KEY"
# df = fetch_monthly_generation(api_key)
# shares = compute_fuel_shares(df)
# smoothed = plot_fuel_mix_transition(shares)
# Quick summary: coal share change from 2010 to 2023
# coal_2010 = str(round(shares.loc["2010", "COW"].mean() * 100, 1))
# coal_2023 = str(round(shares.loc["2023", "COW"].mean() * 100, 1))
# print("Coal share 2010: " + coal_2010 + "% -> 2023: " + coal_2023 + "%")
The API pagination loop is necessary because the full 14-year, six-fuel query returns more records than a single API response allows. The facets[sectorid][]value 99 selects all sectors combined (utility, independent power producers, and combined heat and power), giving the total national generation figure. The resulting chart will show coal's share declining from roughly 45 percent in 2010 to around 16 percent by 2024, natural gas rising from around 24 percent to 43 percent, wind growing from under 3 percent to around 10 percent, and solar rising from effectively zero to around 5–6 percent of the tracked total. Nuclear will appear as a relatively stable band, confirming its role as a baseload constant through the entire period despite plant retirements.
Power plants are among the largest stationary sources of air pollution in the United States. EPA's Toxics Release Inventory tracks annual emissions of hazardous substances from power plants and other industrial facilities. See EPA Toxic Release Inventory: Annual Chemical Emissions From Every Reporting Facility.
Electricity markets in most of the US are overseen by FERC, which enforces rules against market manipulation, reviews rate filings, and adjudicates disputes between generators and grid operators. See FERC Energy Enforcement: How Federal Electricity Market Oversight Works.
Natural gas and electricity prices are actively traded in futures markets. The CFTC Commitments of Traders report shows the positioning of commercial hedgers, managed money, and other market participants in energy futures. See CFTC Commitments of Traders: Energy Futures Positioning and Market Structure.