The warehouse
Where every number comes from, and how it was checked.
Every scheduled flight of the reporting carriers from January 2015 to July 2026 went through named quarantine rules (flagged and counted, nothing deleted) into a dbt warehouse of 18 models and 206 tests. The metric layer defines each metric once over the flights and once over the shipped mart and compares them at 4 grains.
The quarantine report
| Rule | What it catches | Rows | Share | Excluded from |
|---|---|---|---|---|
| duplicate key | a second row with the same carrier, date, flight number, origin, destination and scheduled departure | 4 | 0.00% | everything |
| actual without scheduled | an actual departure, arrival or elapsed time with no scheduled time to measure it against | 2 | 0.00% | everything |
| impossible time | a negative taxi time, or an air time or an actual or scheduled elapsed time at or below zero or longer than the longest a domestic flight can take | 31 | 0.00% | everything |
| elapsed mismatch | actual elapsed time that differs from taxi out plus air time plus taxi in by more than the tolerance | 15 | 0.00% | everything |
| status conflict | a row flagged both cancelled and diverted, which cannot both have happened to one flight | 13 | 0.00% | everything |
| missing actual | a flight neither cancelled nor diverted that reports no departure delay, no arrival delay, no actual elapsed time or no air time | 974 | 0.00% | everything |
| cause mismatch | reported delay causes that do not sum to the arrival delay within the tolerance | 119 | 0.00% | the cause shares in chapter 6 |
| tail missing | no tail number on the row | 338,715 | 0.46% | the rotations of chapter 4 |
| tail format | a tail number that is not a valid FAA registration (N, a digit 1 to 9, at most two trailing letters) even after a missing leading N is restored, such as an airline's own fleet number | 1,142,859 | 1.54% | the registry join; the rotations keep the row, since the value still names one aircraft |
| revision | a row that a later download of the same month changed (the later kept, the change counted) | 0 | 0.00% | nothing; the earlier version is the one that is replaced |
Source: BTS Reporting Carrier On-Time Performance (real); population: every row of every monthly file in the window; as of 2026-10-01.
The quarantine report by carrier and month
Rows flagged by each rule, by carrier and month; a row can trip more than one rule
Source: BTS Reporting Carrier On-Time Performance (real), the warehouse's mart_quarantine.
The metric layer, reconciled
3,501 cells compared across 4 grains, 0 disagreements.
| Metric | Over the flights | Over the mart |
|---|---|---|
| scheduled flights | count(*) | sum(scheduled) |
| cancellation rate | avg(cancelled::int) | sum(cancelled) / sum(scheduled) |
| completion factor | 1 - avg(cancelled::int) | 1 - sum(cancelled) / sum(scheduled) |
| diversion rate | avg(diverted::int) | sum(diverted) / sum(scheduled) |
| on time rate | avg((arr_delay < 15)::int) filter (where not cancelled and not diverted) | sum(on_time) / sum(flown) |
| mean arrival delay | avg(arr_delay) filter (where not cancelled and not diverted) | sum(arr_delay_sum) / sum(flown) |
| median arrival delay | quantile_disc(least(greatest(arr_delay, -60), 300), 0.5) filter (where not cancelled and not diverted and arr_delay is not null) | median_from_histogram |
| mean scheduled block | avg(crs_elapsed) filter (where not cancelled and not diverted) | sum(crs_elapsed_sum) / sum(flown) |
| mean actual block | avg(actual_elapsed) filter (where not cancelled and not diverted) | sum(actual_elapsed_sum) / sum(flown) |
| mean padding | avg(padding) | sum(padding_sum) / sum(padding_flights) |
| padding share | sum(padding) / sum(crs_elapsed) filter (where padding is not null) | sum(padding_sum) / sum(padding_block_sum) |
| reported late aircraft share | sum(cause_late_aircraft) filter (where cause_ok) / sum(cause_late_aircraft + cause_carrier + cause_nas + cause_weather + cause_security) filter (where cause_ok) | sum(cause_late_aircraft_sum) / (sum(cause_late_aircraft_sum) + sum(cause_carrier_sum) + sum(cause_nas_sum) + sum(cause_weather_sum) + sum(cause_security_sum)) |
| reported carrier share | sum(cause_carrier) filter (where cause_ok) / sum(cause_late_aircraft + cause_carrier + cause_nas + cause_weather + cause_security) filter (where cause_ok) | sum(cause_carrier_sum) / (sum(cause_late_aircraft_sum) + sum(cause_carrier_sum) + sum(cause_nas_sum) + sum(cause_weather_sum) + sum(cause_security_sum)) |
| reported nas share | sum(cause_nas) filter (where cause_ok) / sum(cause_late_aircraft + cause_carrier + cause_nas + cause_weather + cause_security) filter (where cause_ok) | sum(cause_nas_sum) / (sum(cause_late_aircraft_sum) + sum(cause_carrier_sum) + sum(cause_nas_sum) + sum(cause_weather_sum) + sum(cause_security_sum)) |
| reported weather share | sum(cause_weather) filter (where cause_ok) / sum(cause_late_aircraft + cause_carrier + cause_nas + cause_weather + cause_security) filter (where cause_ok) | sum(cause_weather_sum) / (sum(cause_late_aircraft_sum) + sum(cause_carrier_sum) + sum(cause_nas_sum) + sum(cause_weather_sum) + sum(cause_security_sum)) |
| reported security share | sum(cause_security) filter (where cause_ok) / sum(cause_late_aircraft + cause_carrier + cause_nas + cause_weather + cause_security) filter (where cause_ok) | sum(cause_security_sum) / (sum(cause_late_aircraft_sum) + sum(cause_carrier_sum) + sum(cause_nas_sum) + sum(cause_weather_sum) + sum(cause_security_sum)) |
| inherited share | sum(inherited_minutes) / sum(arr_delay_pos) | sum(inherited_minutes_sum) / sum(arr_delay_pos_sum) |
Source: BTS Reporting Carrier On-Time Performance (real); population: every flight in the window, through the metric layer; as of 2026-10-01.
The recovery study
Every estimator, run on simulated networks where the truth is known, 12 conditions with 20 seeds each, before it touched a real flight.
Padding error, by condition
Largest in magnitude under confounding none, propagation strong, noise high
Source: simulated airline network with known truth; population: the recovery study, every condition and seed; seeds: 20; as of 2026-10-01.
Changepoint date error, by condition
Largest in magnitude under confounding moderate, propagation strong, noise high
Source: simulated airline network with known truth; population: the recovery study, every condition and seed; seeds: 20; as of 2026-10-01.
Rho bias, by condition
By condition
Source: simulated airline network with known truth; population: the recovery study, every condition and seed; seeds: 20; as of 2026-10-01.
Rho coverage, by condition
Largest in magnitude under confounding none, propagation weak, noise low
Source: simulated airline network with known truth; population: the recovery study, every condition and seed; seeds: 20; as of 2026-10-01.
Inherited share error, by condition
By condition
Source: simulated airline network with known truth; population: the recovery study, every condition and seed; seeds: 20; as of 2026-10-01.
Raw rank correlation, by condition
Largest in magnitude under confounding none, propagation strong, noise high
Source: simulated airline network with known truth; population: the recovery study, every condition and seed; seeds: 20; as of 2026-10-01.
Adjusted rank correlation, by condition
Largest in magnitude under confounding none, propagation weak, noise high
Source: simulated airline network with known truth; population: the recovery study, every condition and seed; seeds: 20; as of 2026-10-01.
Bunching false positives, by condition
Largest in magnitude under confounding moderate, propagation strong, noise high
Source: simulated airline network with known truth; population: the recovery study, every condition and seed; seeds: 20; as of 2026-10-01.
Bunching power, by condition
Largest in magnitude under confounding moderate, propagation strong, noise high
Source: simulated airline network with known truth; population: the recovery study, every condition and seed; seeds: 20; as of 2026-10-01.
Weather share error, by condition
Largest in magnitude under confounding strong, propagation strong, noise low
Source: simulated airline network with known truth; population: the recovery study, every condition and seed; seeds: 20; as of 2026-10-01.
Weather coverage, by condition
Largest in magnitude under confounding moderate, propagation weak, noise low
Source: simulated airline network with known truth; population: the recovery study, every condition and seed; seeds: 20; as of 2026-10-01.
Detector precision, by condition
Largest in magnitude under confounding moderate, propagation weak, noise low
Source: simulated airline network with known truth; population: the recovery study, every condition and seed; seeds: 20; as of 2026-10-01.
The data dictionary
| Published file | Bytes |
|---|---|
| briefing.json | 13,679 |
| charts/causes.json | 4,032 |
| charts/decision.json | 59,807 |
| charts/definition.json | 4,565 |
| charts/inherited.json | 2,851 |
| charts/line.json | 14,811 |
| charts/meltdowns.json | 14,744 |
| charts/padding.json | 18,148 |
| charts/ranking.json | 6,519 |
| hub_curves.json | 62,738 |
| manifest.json | 333,454 |
| marts/mart_airport_day.parquet | 12,126,757 |
| marts/mart_carrier_day.parquet | 635,782 |
| marts/mart_carrier_month.parquet | 132,213 |
| marts/mart_delay_histogram.parquet | 821,283 |
| marts/mart_hour_profile.parquet | 247,142 |
| marts/mart_inherited_month.parquet | 11,284 |
| marts/mart_leg_position.parquet | 14,938 |
| marts/mart_quarantine.parquet | 12,513 |
| marts/mart_route_month.parquet | 17,750,284 |
| marts/rotation_samples.parquet | 74,290 |
| marts/rotation_worst_days.parquet | 1,648 |
| recorded_session.json | 382,570 |
| story.json | 35,172 |
Every column of every exported table is named in the CSV bundle's dictionary, and every definition is in docs/definitions.md.
Exports and the BI companions
- The workbook with live formulas
Change the year on the summary sheet and every figure moves; LibreOffice recalculates it in the tests against the metric layer.
- The Tableau extracts and view specification
The route by month mart as one CSV per year and the carrier by month mart as one CSV, with the views the companion workbook shows.
- The Power BI model specification
Tables, relationships and DAX measures generated from the metric layer.
- The CSV bundle and its dictionary
Every chapter's table as CSV, with every column named.
What the ops director would push back on
A warehouse can agree with itself and still be wrong about the world. The reconcile proves that two expressions over two grains give the same number; it cannot prove the carriers reported their times correctly. That is why the quarantine rules flag impossible times, causes that do not add up and duplicate rows rather than fixing them, and why every flagged row is counted here by carrier and month.