The US Wind Turbine Database Explained: Where Each Turbine Record Comes From

On this page

Problem statement

The US Wind Turbine Database looks like a plain list of turbines, but every record is assembled. The point comes from the Federal Aviation Administration's obstacle files, is checked against aerial imagery and moved to the base of the tower; the make and model come from the industry association, the developer or the FAA filing, and the capacity, hub height and rotor size are then looked up from the model. USGS rates its confidence in each part, records which imagery it used, and every quarter adds new turbines and removes ones that have gone. Knowing this is what tells you which questions the file can answer: where turbines stand today, yes; how many stood in 2012, no. This page reads those parts of version 9.1.

Quick answer

Each record carries two confidence codes, for its attributes and its location, from 1 (low) to 3 (high), and low attribute confidence means the specifications are mostly missing:

print(wt.t_conf_atr.value_counts().sort_index().rename("attributes").to_frame().join(wt.t_conf_loc.value_counts().rename("location")).to_string())
print(wt.groupby("t_conf_atr")[["t_model", "t_cap", "t_hh"]].agg(lambda s: s.notna().mean()).round(3).to_string())
            attributes  location
t_conf_atr                      
1                 5660       625
2                 4469        90
3                67710     77124
            t_model  t_cap   t_hh
t_conf_atr                       
1             0.135  0.136  0.085
2             0.997  1.000  0.940
3             1.000  0.998  1.000

Location confidence is high for all but 715 turbines. Attribute confidence is lower: 5,660 turbines are rated 1, and of those only 13.5% have a model and 8.5% a hub height. Code 1 mostly marks turbines whose position is confirmed but whose make and model USGS has not found yet. Code 2 has a model with nearly complete specifications, and code 3 is complete.

Two stacked bars of turbines by confidence code: for attributes 67,710 high, 4,469 medium and 5,660 low; for location 77,124 high, 90 medium and 625 low. Two stacked bars of turbines by confidence code: for attributes 67,710 high, 4,469 medium and 5,660 low; for location 77,124 high, 90 medium and 625 low.
Attribute and location confidence of the 77,839 records.

How a record is built

1. The point: FAA filings, checked on imagery

print(f"FAA obstacle number: {wt.faa_ors.notna().mean():.1%}; FAA study number: {wt.faa_asn.notna().mean():.1%}; EIA plant: {wt.eia_id.notna().mean():.1%}")
print(wt.t_img_src.value_counts().to_string())
FAA obstacle number: 95.7%; FAA study number: 95.4%; EIA plant: 93.5%
t_img_src
Vantor              59839
Bing Maps Aerial     6346
Planet               5559
NAIP                 5234
Google Earth          861

Almost every turbine carries an FAA number. Any structure taller than 200 feet must be notified to the FAA, which publishes it as an obstacle, and nearly every modern turbine is that tall. Those filings are how USGS learns of new turbines. Each point is then placed on aerial imagery at the base of the tower. Vantor (formerly Maxar) imagery was used for 59,839 turbines, and Bing, Planet, the USDA's NAIP photography and Google Earth for the rest.

2. The imagery date

img = pd.to_datetime(wt.t_img_date, format="%m/%d/%Y", errors="coerce")
print("no imagery date, by source:", img.isna().groupby(wt.t_img_src).sum()[lambda n: n > 0].to_dict())
print("dated 1 January, by source:")
print(((img.dt.month == 1) & (img.dt.day == 1)).groupby(wt.t_img_src).mean().round(3).to_string())
print(f"imagery from a year before the project year: {(img.dt.year < wt.p_year).sum():,}")
no imagery date, by source: {'Bing Maps Aerial': 6346, 'Vantor': 121}
dated 1 January, by source:
t_img_src
Bing Maps Aerial    0.000
Google Earth        0.000
NAIP                0.999
Planet              0.011
Vantor              0.000
imagery from a year before the project year: 1,271

Bing's imagery comes with no date at all, so all 6,346 turbines checked on it have none. NAIP photographs carry only a year, so USGS sets their month and day to 1 January, and 99.9% of NAIP-checked records show that date. Treat it as a year. 1,271 turbines were seen on imagery from before their project's year: they stood before the project came online, which fits the metadata's warning that p_year is sometimes estimated from the year a turbine was erected.

Stacked bars of turbines by the year of the image they were checked on, from 2010 to 2026, mostly Vantor imagery from 2016 on, NAIP in 2012-2013 and Planet in the latest years. Stacked bars of turbines by the year of the image they were checked on, from 2010 to 2026, mostly Vantor imagery from 2016 on, NAIP in 2012-2013 and Planet in the latest years.
The imagery each turbine was placed on, by year and source.

3. The specifications come from the model

spec = wt.dropna(subset=["t_model", "t_cap"]).groupby("t_model").t_cap.nunique()
print(f"models: {len(spec)}; models with more than one capacity: {(spec > 1).sum()}")
print(f"turbines with a model but no capacity: {(wt.t_model.notna() & wt.t_cap.isna()).sum()}")
models: 329; models with more than one capacity: 38
turbines with a model but no capacity: 164

USGS does not measure the specifications. It looks them up from the make and model: capacity, hub height and rotor diameter come from the manufacturer, the developer, the industry association or the FAA filing. 38 of 329 models appear with more than one capacity, because the same rotor and tower are sold with several generator ratings and the model name doesn't always say which. Only 164 turbines have a model but no capacity.

Versions and what they remove

The data used on this page

The US Geological Survey's US Wind Turbine Database, version 9.1 of 28 September 2026 (Hoen and others, doi:10.5066/F7TX3DN0), public domain, with the changelog that comes in the download. USGS replaces the file every quarter, so the version used here was saved on this site on 19 October 2026.

from pathlib import Path
import re
import zipfile

import pandas as pd
import requests

Path("data").mkdir(exist_ok=True)
# USGS US Wind Turbine Database v9.1 (28 September 2026) with its metadata and changelog, Census 2024 cartographic
# boundary counties and the EIA-860 2025 wind table. Saved 19 October 2026: USGS replaces the file every quarter.
# Live: https://energy.usgs.gov/uswtdb/assets/data/uswtdbCSV.zip
ARCHIVE = "usgs-uswtdb-v9-1-2026-10-19.zip"
if not Path(f"data/{ARCHIVE}").exists():
    Path(f"data/{ARCHIVE}").write_bytes(requests.get(f"https://data.spatialworkflow.io/{ARCHIVE}", timeout=600).content)
Z = zipfile.ZipFile(f"data/{ARCHIVE}")
wt = pd.read_csv(Z.open("uswtdb_V9_1_20260928.csv"), dtype={"t_fips": str})
log = Z.read("CHANGELOG.txt").decode()
print(f"US Wind Turbine Database v9.1: {len(wt):,} turbines; changelog {len(log.splitlines()):,} lines")
US Wind Turbine Database v9.1: 77,839 turbines; changelog 1,071 lines

Example 1: every version since 2018

parts = re.split(r"\n## \[v?([\d.]+)\] - (\d{4}-\d{2}-\d{2})", "\n" + log)


def count(pattern, text):
    return sum(int(n.replace(",", "")) for n in re.findall(pattern, text))


ch = pd.DataFrame([{"version": v, "date": d, "new": count(r"([\d,]+) new turbines?", body),
                    "decommissioned": count(r"([\d,]+) decommissioned turbines?", body),
                    "duplicates": count(r"([\d,]+) duplicate turbines?", body),
                    "not a turbine": count(r'([\d,]+) (?:turbines )?reclassified as "not a turbine"', body)}
                   for v, d, body in zip(parts[1::3], parts[2::3], parts[3::3])])
print(f"{len(ch)} versions, {ch.date.min()} to {ch.date.max()}")
print(ch.head(4).to_string(index=False))
print(ch[["new", "decommissioned", "duplicates", "not a turbine"]].sum().to_string())
30 versions, 2018-04-19 to 2026-09-28
version       date  new  decommissioned  duplicates  not a turbine
    9.1 2026-09-28  592              23          53             55
    9.0 2026-06-22 2362             419         290              1
    8.3 2026-03-25  367               3          41             13
    8.2 2025-12-10  179             675          50             86
new               30890
decommissioned     7227
duplicates         1950
not a turbine      1089

The changelog in the download covers 30 versions, from the first public release in April 2018 to version 9.1. Since then 30,890 new turbines were added, and 7,227 decommissioned turbines, 1,950 duplicates and 1,089 structures that turned out not to be turbines were removed, on top of the 5,992 records the first release dropped from the older USGS dataset. Version 8.2 in December 2025 removed 675 decommissioned turbines and added only 179 new ones.

Bars for each of 30 versions from 2018 to 2026, upward for new turbines added (up to about 2,600) and downward for decommissioned turbines, duplicates and non-turbines removed. Bars for each of 30 versions from 2018 to 2026, upward for new turbines added (up to about 2,600) and downward for decommissioned turbines, duplicates and non-turbines removed.
What each version added and removed.

Example 2: a current fleet, not a history

by_year = wt.groupby("p_year").size()
print(by_year.loc[[1985, 1990, 1995, 2000]].to_string())
print(f"turbines with no project year: {wt.p_year.isna().sum()}")
p_year
1985.0    148
1990.0      1
1995.0      1
2000.0     28
turbines with no project year: 842

Because decommissioned turbines are deleted, the file describes the fleet standing today. Only 148 turbines remain from 1985 projects and one each from 1990 and 1995. Thousands more were built in those years and have since been removed or replaced. Counting turbines by p_year gives the survivors of each year, not what was installed, so for installations by year use EIA's operating dates or an older version of this file. For the same reason, a turbine missing from version 9.1 may have stood in an earlier version.

Getting the turbine data without code

  • Look first: the USWTDB Viewer is a map of every turbine. Click one for its project, model, size and imagery date, or filter by state, year and height. No download is needed.
  • Download: the data page has the whole database as CSV (about 2 MB zipped), shapefile (about 7 MB) and GeoJSON (about 2 MB). The CSV opens in a spreadsheet. The shapefile and GeoJSON open in QGIS or ArcGIS. Each download comes with the XML metadata, which defines every column.
  • How current it is: USGS updates the file up to every quarter, and it lags new installations by about a quarter. Older versions are kept on ScienceBase. That matters because each version removes turbines that have been taken down.
  • Terms and credit: USGS data are public domain, and the metadata sets no use constraints. The suggested citation is Hoen, Diffendorfer, Rand, Kramer, Garrity and Hunt, United States Wind Turbine Database V9.1 (September 28, 2026), USGS, American Clean Power Association and Lawrence Berkeley National Laboratory data release, doi:10.5066/F7TX3DN0.
  • The copy these pages use: version 9.1 is saved unchanged at data.spatialworkflow.io with its metadata and changelog, so the numbers here can be checked after USGS publishes the next version.