How risky?
Miss rate by layover, hub, carrier, time of day and season — with confidence intervals.
[ Analytics case · independent project · 2026 ]
I turned 7 million real 2025 U.S. flights into 4.8 million hub connections, measured how often each one was actually missed, and turned the result into a booking rule and a risk badge for TripMate.
Booking sites happily sell a 35-minute connection. Nobody tells you the odds.
Airlines publish a minimum connection time and booking engines sell anything above it. For a traveller — and for TripMate, the travel copilot I built — the useful question is different: what is the chance this connection fails, what happens if it does, and which layover is fastest on average once misses are counted? I split it into three questions the data can actually answer.
Miss rate by layover, hub, carrier, time of day and season — with confidence intervals.
The real wait for the next flight to the same destination after a miss, from the actual schedule.
The layover that minimises expected travel time, and a risk badge the product can show at booking.
There is no “missed connection” dataset. I built one from what actually happened.
The DOT file lists every domestic flight by the large carriers with scheduled and actual times — but not who connected. So I built realistic itineraries: each inbound flight into a carrier’s hub is paired with that carrier’s next departure 30–180 minutes later, three random layovers per inbound. Each pair is labelled from the real outcome of both flights, so a storm that delays both is captured instead of assumed away.
missed = inbound cancelled or diverted OR outbound pushed back < 20 min after inbound landed
20 min gate-to-gate
Risk drops fast for the first hour, then flattens — and when you land matters as much as how long you wait.
Going from 30 to 60 minutes halves the risk (15.9% → 7.6%). Doubling again to 120 takes off only 3.8 more points. About 1.2–1.3 points never go away: inbound cancellations that no layover can fix.
Delays pile up through the day. A 7 a.m. arrival misses ~4.8%; after 9 p.m. it’s 13–15% — three times as risky for the same layover.
June–July are worst (10.6–11.4%): summer thunderstorms on full schedules. September is the calmest month (6.2%).
When the inbound is late, the outbound often is too — the same storm, the same crew. Breaking that link predicts 6.66% misses instead of the real 5.73%: the common shortcut of multiplying two delay rates overstates risk by ~16%. Labelling from paired real outcomes was worth the effort.
Delay minutes by reported cause
Weather is rarely the direct culprit. Knock-on delays from earlier flights and carrier operations cause four in five delay minutes — which is exactly why late-day arrivals are riskier.
A model helps — but measured honestly, booking-time data has a ceiling.
If TripMate shows a risk number, it must be calibrated (a 10% badge should fail about 10% of the time) and tested on months the model never saw. I trained gradient boosting on what is known at booking — layover, arrival hour, hub, carrier, origin, weekday, distance — and compared it with two baselines a PM could build in a spreadsheet.
| Approach | AUC | Avg. precision | Brier |
|---|---|---|---|
| Layover only | 0.657 | 0.096 | 0.0504 |
| Hub × carrier × layover table | 0.664 | 0.104 | 0.0503 |
| Gradient boosting (calibrated) | 0.690 | 0.123 | 0.0499 |
AUC 0.690 vs. 0.664 for the lookup table. Layover and arrival hour carry ~80% of the signal; the rest of the risk is day-of weather and operations nobody knows at booking.
With this ceiling the product should show Low / Medium / High risk with the % behind it — not a falsely precise score.
Calibrated on calm September, the model under-predicts Oct–Dec by ~1.5 points. An early version used month as a feature and was worse. Fix: train on 2023–2025 so it can learn seasonality.
A miss costs hours, not minutes — so the fastest layover isn’t the shortest.
For every missed connection I looked up the next real departure to the same destination from that hub that day or the next. Two bounds: any carrier (optimistic) and the same mainline carrier (realistic for most tickets).
expected time = layover + P(miss) × wait after a miss
On American at DCA, a 45-minute connection misses 16% of the time: expected 118–151 minutes. Booking 60–75 minutes is faster on average (115–140) — and far calmer. The answer barely moves between $25/h and $100/h value of time, because the cost of a miss is itself mostly time.
| Hub | 30–59 | 60–89 | 90–119 | Fastest | Overnight |
|---|---|---|---|---|---|
| ATLDL | 10.9 | 6.1 | 4.3 | 45 min | 29-30% |
| DFWAA | 15.2 | 9.9 | 7.3 | 45-75 min | 41-43% |
| CLTAA | 11.8 | 7.1 | 5.1 | 60 min | 40-42% |
| DENUA | 12.3 | 6.6 | 4.9 | 45-75 min | 34-57% |
| DENWN | 9.3 | 5.0 | 3.3 | 45-60 min | 35-50% |
| LASWN | 8.1 | 4.5 | 2.6 | 45-60 min | 41-49% |
| ORDUA | 10.1 | 6.4 | 4.4 | 60 min | 33-54% |
| SEAAS | 13.7 | 6.6 | 4.2 | 60 min | 47-59% |
| BWIWN | 8.0 | 4.5 | 3.3 | 45 min | 51-53% |
| PHXWN | 8.3 | 5.0 | 3.3 | 45 min | 44-52% |
| DALWN | 8.6 | 5.1 | 3.6 | 45 min | 53-53% |
| MDWWN | 8.5 | 4.8 | 3.2 | 45 min | 58-58% |
| MSPDL | 11.1 | 6.3 | 4.1 | 60 min | 56-58% |
| IAHUA | 10.2 | 5.7 | 3.9 | 45 min | 46-51% |
| MIAAA | 14.4 | 8.4 | 5.7 | 60-75 min | 45-46% |
| PHXAA | 12.5 | 7.9 | 5.3 | 60-75 min | 37-59% |
Three rules for travellers, one feature for TripMate.
Fastest on average at almost every hub. Never 30: one in six of those connections fails.
Arriving after 5 p.m. or flying in June–July? Add 15–30 minutes — risk is two to three times higher.
Roughly half of misses mean an overnight. If it’s the last connection of the day, book the longer one.
A 60–75 min connection misses 9–12% and is faster on average.
Source: DOT on-time data 2025 · afternoon arrivals
The model writes a lookup table of calibrated miss probabilities by carrier × hub × arrival time × layover (risk_table.json), small enough to ship to the front end with no model server. In TripMate it becomes a badge next to every connecting itinerary.
Add 2023–2024 so the model learns month effects instead of under-predicting winter.
Regional partners file under their own codes, so connections onto them are out of scope. Next: map partner flights to marketing carriers.
Gate-to-gate time varies by terminal. Next: vary it by hub using terminal maps — and by whether you check a bag.
I use the next nonstop to the same destination. Real rebooking may route via another hub (faster) or hit full flights (slower).
Data: U.S. DOT Bureau of Transportation Statistics, Reporting Carrier On-Time Performance, Jan–Dec 2025. Every number on this page is computed by my own code from those files; code available on request.
Want the notebook, or a walkthrough of how I would put this in front of a product team?