Open Data

US Airport Security & Immigration Wait Times

Airports publish their current wait time and then overwrite it. Nobody keeps the history. This is that history — every reading from 30 US airports, collected about once a minute since 2026-04-01 and published in full.

Free to use for anything, including commercially, under CC BY 4.0. All I ask is attribution.

Browse and download on Hugging Face →

What's in it

46,564,071 observations across 157 lanes (airport × terminal × standard/PreCheck), last updated 2026-11-11. The archive grows by roughly 120,000 rows a day.

AirportTerminalsObservationsSince
EWR Newark35,284,6152026-04-01
JFK JFK54,756,0592026-04-01
PHL Philadelphia64,219,9392026-04-01
MCO Orlando33,160,4822026-04-01
MIA Miami32,971,5442026-04-01
BOS BOS72,654,2322026-08-14
DFW DFW52,284,4102026-08-14
LGA LaGuardia32,209,2402026-04-01
SFO SFO72,175,3802026-08-14
IAH IAH72,042,1182026-08-14
LAS LAS41,787,6642026-08-14
BWI BWI41,728,8162026-08-14
PHX PHX51,156,5152026-08-14
DCA DCA31,080,2662026-08-17
SEA SEA61,074,1012026-08-14
DEN DEN3927,4842026-08-14
SAN SAN3927,4362026-08-14
MSP MSP4927,3762026-08-14
CLT CLT3923,2762026-08-14
PDX PDX2892,9882026-08-17
CLE CLE3490,1002026-08-17
DTW DTW2463,4782026-08-14
PIT PIT1447,5182026-08-17
CVG CVG1445,6882026-08-17
HOU HOU1432,6682026-08-14
JAX JAX1339,4912026-08-17
CMH CMH1223,7152026-08-17
STL STL1223,5282026-08-17
SLC SLC1222,0192026-08-17
IAD IAD191,9252026-08-17

It ships as four subsets, all Parquet:

  • waits· 6.2M ·One row per distinct reading, with the window it stood for. Start here.
  • waits_raw· 12.7M ·Every individual poll, unfiltered.
  • hourly· 116k ·Per lane per hour: mean, median, p75, p95 and max. Open lanes only.
  • cbp· 24k ·CBP immigration halls, with passenger counts, booths open and flights landed.

Using it

Load a subset straight from the Hub:

from datasets import load_dataset

ds = load_dataset("digitalhen/us-airport-wait-times", "waits", split="train")

Or query the Parquet in place, without downloading the whole archive — here, the busiest morning hours at EWR:

-- DuckDB
SELECT terminal, queue_type, round(avg(avg_wait), 1) AS avg_wait
FROM 'https://huggingface.co/datasets/digitalhen/us-airport-wait-times/resolve/main/data/hourly/hourly.parquet'
WHERE airport = 'EWR' AND hour_of_day BETWEEN 5 AND 8
GROUP BY 1, 2
ORDER BY 3 DESC;

Full column-by-column schema for every subset is in the dataset card.

Before you draw conclusions

These are posted wait times, not measured transit times. Every value is what the airport chose to display. It is an operator's estimate, produced by methods that differ per airport and are not published. This is a dataset about what airports told passengers, which may or may not match what passengers experienced.

The effective resolution varies by airport. Collection runs about once a minute, but the underlying feeds refresh at very different rates — the Port Authority feeds behind JFK, EWR and LGA update far less often than those behind MIA, MCO and PHL. The n_scrapes column tells you how long a reading stood unchanged. Be careful comparing volatility between airports; you may be measuring how often they publish rather than how the queues moved.

Gaps are real gaps. Upstream outages and deploys leave holes. Nothing is backfilled or interpolated — a missing interval is simply absent, never invented.

Where it comes from

Security wait times come from each airport operator's own public feed. Immigration data comes from U.S. Customs and Border Protection's public airport wait-time service. No personal data is collected: every value is an aggregate the operator already publishes to the travelling public.

The same pipeline powers the live boards on this site, so the archive is a byproduct of running the service rather than a separate effort — which is also why it should keep growing.

Built something with this? I'd like to hear about it.