STS fare comparison: method and findings
How the fare comparison in "Nobody has done the subtraction" was made, what it found, and which of its own findings didn't survive checking.
Most of Nobody has done the subtraction rests on public documents that any reader can check by reading them. One section doesn't. The claim that Southwest's arrival made flying from Santa Rosa cheaper is testable against ticket data, and testing it required original analysis. This page sets out how that was done, what it found, and — as much to the point — which of its own earlier findings did not survive checking.
The finding, in short. On routes where a fair comparison is possible, fares from Santa Rosa sit close to parity with San Francisco and Oakland. Southwest's own four routes do show a discount, but two months is not enough to establish whether it lasts, and even at its largest the gap is smaller than ordinary variation between fares on the same route.
The data
The source is the Bureau of Transportation Statistics' DB1C "O&D Market" files: a 40 percent sample of US domestic airline tickets, collected monthly, which replaced the older 10 percent quarterly DB1B system from July 2025. Each row is one itinerary — origin, destination, fare, passenger count, carrier, and whether the trip was flown nonstop. The files are published at the BTS origin and destination survey page.
This dataset rather than something simpler because it is the only public source giving itinerary-level fares by route and originating airport. That matters: comparing airport-wide average fares would be meaningless, since San Francisco's average is dragged upward by transcontinental and long-haul flying that has nothing to do with the price of a comparable trip. The comparison has to be made route by route.
Eleven months were used, July 2025 through May 2026 — nine months before Southwest's entry on 7 April 2026, and the two months after.
A few things about the file format worth recording
Anyone repeating this will hit the same obstacles.
The monthly download is not a zip containing a CSV. It contains three parallel copies of the same data: a nested .asc.zip, a nested .csv.zip, and a .parquet file. The script reads the parquet member, which needs no second unzip and loads fastest.
The column names mostly follow the old convention — Origin, Dest, Passengers, MktAmount, MktTax, MktGeoType, NonStopMiles, MktCarrier, Nonstop. One does not: the field is V_Yield, with an underscore.
V_Yield looked like a validity flag and is not one. The assumption carried over from DB1B was that a value of 1 marks a usable fare record. In this data it is 0.0 for 99.1 percent of rows and null for the rest, across 2.3 million records — never 1. No BTS documentation for that field in the Market file could be found. It was dropped as a filter rather than guessed at; data quality is handled instead by excluding fares below $50 or above $2,500, which removes award, employee, and taxes-only tickets.
MktGeoType and Nonstop were both checked rather than assumed, after the V_Yield problem. Both behave as expected.
The script prints its full column list and several value counts on first load, so that a future change to the BTS schema shows up as a readable message rather than a silent wrong answer.
What was tested
Did fares at Santa Rosa fall after Southwest arrived?
Passenger-weighted average one-way fare at STS, nine months before against two months after.
The result was $203.23 before, $197.31 after — a fall of 2.9 percent. Passenger volume rose over the same comparison, from roughly 9,800 a month to roughly 13,700.
Three limits apply, and they are substantial. Seasonality is uncontrolled: the earlier window spans three seasons, the later one covers two spring months. No system-wide trend is netted out, so if fares fell everywhere over the period, Santa Rosa would show a fall regardless of Southwest. And an early version of this comparison, using only two pre-entry months, produced a larger apparent effect of 4.3 percent; the fuller baseline halved it. That is a caution against reading much into any short window — including, possibly, this one.
Does Santa Rosa carry a fare premium on the same destinations?
For every destination reachable from all three airports with at least 100 sampled passengers after Southwest's entry: passenger-weighted average fare at each origin, and the gap between Santa Rosa and whichever Bay Area airport was cheaper.
The first result was a premium of $8.26 — Santa Rosa pricier on average. That figure was wrong to trust, and the reason is the most important correction in the exercise.
Route-level comparison removes the route-mix problem, but within a single route it can still compare different products. If Santa Rosa's service to a city is a connection and San Francisco's is a nonstop, the fare difference reflects the connection, not the airport. Connections cost more everywhere. The Nonstop field settles this directly rather than requiring inference — and it was in the data from the start, unused.
Splitting the comparison by whether Santa Rosa is mostly nonstop on that particular route:
| Group | Markets | Passengers | Weighted premium |
|---|---|---|---|
| Santa Rosa mostly nonstop | 10 | 22,679 (91%) | +$2.69 |
| Santa Rosa mostly connecting | 13 | 2,155 (9%) | +$66.94 |
Ninety-one percent of passengers in shared markets fly routes where Santa Rosa is close to parity. The blended figure let thirteen thin, connecting-only markets — Austin, Spokane, Boise, Salt Lake City and others, each under 200 passengers — outweigh where the traffic actually is. The nonstop-comparable figure is the honest summary number.
Two results are not explained, and are left unexplained rather than guessed at. Phoenix is 83 percent nonstop from Santa Rosa, comparable to the Bay Area airports, and still carries a 51 percent premium on 1,558 passengers; the nonstop confound does not account for it. Denver runs the other way — only 29 percent nonstop from Santa Rosa, yet $17 cheaper than the Bay Area's mostly-nonstop service. United flew Denver nonstop from Santa Rosa before Southwest arrived, so that average may blend two carriers' pricing.
One concern applies to the whole post-entry window. April and May 2026 are the launch months for Southwest's four routes. New entrants routinely price below their eventual level to build traffic. Southwest's own announcements contain no explicit introductory-fare language, and the county's promotional materials hedged that pricing effects would emerge over time — so this is unresolved rather than settled either way. It needs June to August data to answer.
Does the shorter drive cover the difference?
The nonstop-comparable premium of $2.69 was netted against a ground-access cost model — distance, parking, and time — for a solo traveler.
The result is a net advantage of $0.82 to flying from Santa Rosa: breakeven, not a win either way. Every figure in that model is a stated assumption rather than a measurement, and they are set out in the GROUND block at the top of the script so they can be changed and the calculation re-run. Time is valued at zero, so it is a comparison of money only.
One sensitivity was not run: party size. The fare premium scales with the number of travelers; driving and parking costs largely do not. The sign could flip for a family.
How much do fares on one route vary anyway?
The largest discount found anywhere was Burbank, at $30.95 each way. The obvious question is whether a saving that size matters against the ordinary spread of fares on the same route.
| Percentile | Fare |
|---|---|
| 10th | $64.66 |
| 25th | $82.79 |
| Median | $118.13 |
| 75th | $164.19 |
| 90th | $230.04 |
The gap between the 10th and 90th percentile is $165.38 — more than five times the difference between airports. A price-sensitive traveler has a considerably larger lever in the variation between fares on the same route than in the choice of airport.
One caveat on interpretation: this is total variation within the market. The data does carry a purchase-window field, but it was not used here, so the spread cannot be attributed specifically to booking date, day of week, or any other single cause.
What did not survive checking
Several findings along the way were revised rather than kept. Recording them seems more useful than presenting only the surviving ones.
| Finding | What happened |
|---|---|
| Fares fell 4.3 percent after Southwest entered | Revised to 2.9 percent. The short two-month baseline overstated it; the full nine months halved the effect. |
| Santa Rosa carries an $8.26 fare premium | Revised. The blended figure is not representative. Ninety-one percent of passengers face a premium of $2.69 — near parity. |
| The premium is explained by connections rather than airports | Rejected on the first test. Nonstop share was nearly identical across all three airports in aggregate (82.7 to 86.0 percent). It took a market-by-market check to establish that the confound was real for specific routes despite the aggregate looking clean. |
| A hand estimate that the nonstop-group premium would be negative | Wrong. It came out at +$2.69. The estimate had incorrectly excluded Phoenix. The computed figure stands, not the estimate. |
| Southwest's discount reflects durable competition | Unresolved. Equally consistent with introductory pricing that has not yet faded. Flagged as open rather than asserted. |
Two of those corrections moved the picture toward a less dramatic finding rather than a more dramatic one.
What was not pursued
These were set aside on time and value grounds once the result looked sufficiently well supported without them. Several point toward undermining the current reading rather than reinforcing it.
- Differencing the before-and-after change at Santa Rosa against San Francisco and Oakland over the same months, to remove any system-wide trend.
- Restricting the before-and-after comparison to destinations served in both windows, separating "existing routes got cheaper" from "new routes changed the mix."
- Comparing April against May on Southwest's four routes, as a weak early test of whether the discount is fading.
- A carrier-level check on Denver, to separate United's fares from Southwest's.
- Party-size sensitivity on the ground-access calculation.
Re-running it
python3 -m venv .venv
source .venv/bin/activate
pip install pandas requests pyarrow
python sts_fare_analysis.py # fetch all 11 months (~9GB), then analyze
python sts_fare_analysis.py --no-fetch # reuse files already in ./db1c/
python sts_fare_analysis.py --no-fetch --fare-spread STS,BUR # fare spread for one route
Downloads are cached in ./db1c/ and not re-fetched. The script hard-codes each month's filename, which includes a BTS release-date stamp; if a download fails, check the BTS page for a re-released file and update the FILES list.
Researched and drafted in collaboration with Claude (Anthropic).