BART On-Time Metric
I used to use BART quite a lot back in the day and despite the fact that often trains would be cancelled or whatever, transit enthusiasts and BART itself would frequently publish an on-time percentage that seemed suspiciously high. I was curious what was going on here so that I could reconstruct what was going on and so I opened a CPRA request[1] where I attempted to get to the bottom of this. I think I might have some understanding of what is going on here and I have an example of a day where the discrepancy between my experience and the reported metric is explained.
The Metric
[edit | edit source]There are many ways one can define a train being on time. As an example of why this is needed, consider a system with short headways, i.e. 5 min or so. Consider there was an issue at 0800 and the train scheduled for that time instead showed up at 0805 and then all trains thereafter were every five minutes. This would show as 0% punctuality in a naïve train number to scheduled time sense, but no rider would interpret it as that. So when you come up with an on-time metric, you sort of need to choose one that accurately represents the rider's experience.
There are a few out there. Here's a few and I'll show how they'll vary with some example data.
- BART's Passenger On Time (PoT) Metric
- BART's Train On Time (ToT) Metric
- NYC MTA's Customer Journey Time Performance Metric
Passenger on Time
[edit | edit source]This is the one that's commonly reported by BART. Their document, verbatim, says:

Mechanically, I'd say it goes like this[2], for each fare-gate trip with a tag-in at A and a tag-out at B:
- Use the tag-out time to determine the most-recent train T from A to B
- Look up that train's scheduled door-open
- Look up that train's actual door-open
- Calculate delay, in seconds
- The passenger-trip is considered delayed if
Then the delayed passenger trips, Y, are a subset of all trips, X where
PoT is then .
You can see the things this doesn't quite reflect:
- Reneges: passengers who decide not to take the train from A after tagging-in because it's too late
- Cancels: trains that just didn't show up
- Extreme lateness: and are treated the same.
Now, I'm inferring a few things here, but it mostly matches what they describe. After all, they don't have anything but tag-in and tag-out to verify. The pathological case does manifest on some days. Take for instance, the case of May 10, 2024:
BART @SFBART We currently have no train service between Richmond and MacArthur due to a wayside equipment problem.
The Yellow line is not impacted.
Millbrae service is provided by a shuttle train between SFO and Millbrae.
Richmond riders should seek other means to get to MacArthur.
May 10, 2024[3]
BART @SFBART Replying to @SFBART
Orange line service is running MacArthur to Berryessa.
Red line service is not running. For Millbrae riders, take the shuttle train between SFO and Millbrae and transfer to/from the Yellow line (Antioch-SFO).
Yellow, Green, and Blue line service is not impacted.
May 10, 2024[4]
BART @SFBART Replying to @SFBART
As of 11:10am, we have restored normal train service between Richmond and MacArthur. We will follow up with more details about the cause of the disruption.
May 10, 2024[5]
So there was no train between Richmond and MacArthur for a while. As far as we're concerned, this line didn't exist for 6.5 hours from 0448 to 1110[6]. The PoT metric for that day on BART was 96%[1], which is completely unremarkable[7]. You can get the data for BART[8] boardings by station for 2024 and you'll see that the usual boardings at the affected stations are missing. Estimating by looking at prior and posterior weeks, you'll note that some 6,600 passengers didn't take the train that day[9].
So it seems that this is right, absent trips don't affect lateness at all, and indeed this metric now creates the perverse incentive that cancelling trains that would be late will increase their published on-time performance. A Yellow Line train running once every 20 minutes that is 6 minutes late to leave is best cancelled if one wishes to optimize on-time performance, allowing passengers to take the next train which will arrive exactly on time. The rider experience is that they're waiting up to 40 minutes for a train.
Train on Time
[edit | edit source]BART also defines a different metric for its performance reviews[10] that looks a bit different.

For this one, I'm going to try to reverse-engineer the rule based off that text rather than ask[11].
For a train, , all scheduled trains for that day:
- Was T dispatched? If not, it is delayed and
- Did T run to the end of the line? If not, it is delayed and
- Did T stop at every station on its route? If not, it is delayed and .
- Otherwise, look up its scheduled arrival and actual arrival at the last station Z
- Compute the terminal delay .
- If seconds, T is delayed
Then the on-time trains, Y, are a subset of , where:
and consequently, the on-time metric ToT is .
Now, this is a bit harsh. If there's nearly no one on the train by the time it reaches its terminal station but it's a bit late pulling in there, it's going to look awful. In general, it suffers from a lack of passenger-weighting and so on when we're looking for a metric that represents passenger-experienced delay.
Comparison with PoT
[edit | edit source]One of the quarterly reports for BART shows how these two metrics can diverge so much[12].

It does seem hard to believe that 80% of passengers can get somewhere on time when half of all trains are late.
Customer Journey Time Performance
[edit | edit source]Neither of the above metrics really capture what I want, though, which is that when I arrive at a location A, intending to go to a location B, I want to measure the deviance from the scheduled journey time. For instance, if there's a train scheduled at 0812 that arrives at destination at 0827 and I tag in at 0805, I'd want some slop time to make it to the platform, let's say 3 minutes, so that the train that shows up at 0812 and arrives at the destination at 0827 counts as perfectly on-time, and perhaps counts as on-time even if it arrives just short of 0832 (five minutes past the scheduled arrival).
So if I tag in at 0805, and the train is cancelled and the next one that arrives is ten minutes later at 0822 and arrives correctly on time at the destination at 0837, then that's a 10 minute delay for me. PoT would say I just had an on-time arrival, but my subjective experience is that I'm actually quite late.
NY MTA Metrics
[edit | edit source]It turns out there are systems that actually do something like this. The Office of the State Comptroller in NY audited the MTA[13] and got them to publish metrics they said they would, and they came up with a few things that helped.
In September 2017, Transit introduced the new metrics: Additional Platform Time (APT), the average time that customers wait at a station beyond their scheduled wait time; Additional Train Time (ATT), the average time customers spend on board a train beyond their scheduled travel time; and the sum of these, Additional Journey Time (AJT). AJT is the key component of Customer Journey Time Performance (CJTP), the percentage of customer trips completed within five minutes of the scheduled time.
— New Customer-Focused Subway Metrics, Metropolitan Transportation Authority - New York City Transit[13]
Okay, so the new metrics are described in slightly more detail as[13]:
- Additional Platform Time (APT) - The average added time that customers spend waiting on the platform for a train, compared with their scheduled wait time. APT is measured using a combination of customers’ MetroCard entry data into stations and train departure times from those stations, using information from the real-time train tracking technologies that provide train arrival information.
- Additional Train Time (ATT) - The average additional unanticipated time customers spend onboard the train due to various service issues. Additional Train Time is measured using a combination of customers’ MetroCard entry data into their starting stations and customers’ arrival times at their destination stations, using information from the real-time train tracking technologies that provide train arrival information.
- Additional Journey Time (AJT) - The sum of APT and ATT.
- Customer Journey Time Performance (CJTP) - The percentage of customers whose journeys (waiting and traveltime) are completed within five minutes of their scheduled journey time. This can also be understood as the percentage of trips where AJT is less than five minutes.
The MTA itself has some caveats about this approach that are mostly specific to its own infrastructure[14] but they're not relevant to the idea itself. They do have some assumptions that they think cause this to differ from the customer experience, though I think it seems fine for the most part.
Transit assigns two customers to a start wait time for a train on a platform at 7:00 a.m. and 7:05 a.m., respectively. A train is scheduled to arrive every 10 minutes (6:50 a.m., 7:00 a.m., and 7:10 a.m.). Transit determines that these two customers’ scheduled wait times are 0 and 5 minutes, However, if the 7:00 a.m. train arrived 6 minutes late, then one customer would have waited 6 minutes and the other would have only waited 1 minute rather than the expected 5 minutes. The APT for these two customers would be 6 minutes (7:00 a.m.–7:06 a.m.) and -4 minutes (7:10 a.m.–7:06 a.m.),respectively. However, in the averaging of APT, the -4 minutes will offset customers with +6 minutes.
— New Customer-Focused Subway Metrics, Metropolitan Transportation Authority - New York City Transit[13]
What I'd Love
[edit | edit source]My ideal system without changing BART's tagging system would have something like the following:
- A station -specific estimated walk time from entrance to platform over all entrances
- An arrival time for a train T,
- A tag-in time for each ride
- A Dijkstra-optimal route from to end
Then let's just consider the single-route case for comprehension.
- Compute the platform-ready time
- Select the earliest-scheduled train on the route that scheduled to serve after
- Look up the scheduled arrival time
- Using the tag-out time , determine the most recent train that arrived prior to , . Its arrival time is
- Delay is then
- The trip is delayed if seconds
And to avoid the problem of missing trains, estimate the demand from counterfactual days without disruption and consider all those trips delayed. This is all a result of having to report a single number, though. It's probably the case that we're just facing a dimension reduction problem where many different aspects of a trip need to be considered. So perhaps the right approach is to report:
- on-time percentage as calculated above
- estimated number of journeys missed due to disruption
- p90 passenger delay for delayed trips
Notes
[edit | edit source]- ↑ 1.0 1.1 "Passenger_On-Time.pdf (daily Passenger On-Time, 2024) — CPRA request 26-230". Bay Area Rapid Transit.
- ↑ BART's docs don't say that they choose the most-recent train, only that they use the ticket variables origin station, destination station, and destination time but it's hard to see how these three could be used meaningfully in any other way.
- ↑ BART [@SFBART] (May 10, 2024). "We currently have no train service between Richmon..." (Tweet) – via Twitter.
- ↑ BART [@SFBART] (May 10, 2024). "Orange line service is running MacArthur to Berrye..." (Tweet) – via Twitter.
- ↑ BART [@SFBART] (May 10, 2024). "As of 11:10am, we have restored normal train servi..." (Tweet) – via Twitter.
- ↑ "Normal train service has resumed between Richmond and MacArthur Station | Bay Area Rapid Transit". www.bart.gov. Retrieved 2026-09-17.
- ↑ The range is 92-98% on a typical Friday.
- ↑ "BART Origin-Destination Ridership Data - 2024".
- ↑ The surrounding Fridays have about 6,600 people board there during that time. And the surrounding Fridays have a median of 150,219 trips vs. 143,758 that day. Everything points to those people just not taking BART, rather than driving to a farther station and taking BART from there or whatever.
- ↑ "BART Quarterly Service Performance Review - First Quarter Fiscal Year 2025 - Presentation" (PDF). Archived from the original (PDF) on 2026-09-16.
- ↑ My CPRA request took months to deliver and I'm not eager to go through and repeat it because it'll take so long to deliver but also I feel a bit guilty having put them up to having to do such an intense task which I thought would honestly have been a bit simpler. Then again, who knows how these things are prioritized. It was probably just bumped every day until one day someone hit it with an LLM.
- ↑ 12.0 12.1 "BART Quarterly Service Performance Review - Second Quarter Fiscal Year 2025 - Presentation" (PDF). Archived from the original (PDF) on 2026-09-16.
- ↑ 13.0 13.1 13.2 13.3
"New York City Transit's Implementation of New Customer-Focused Subway Metrics". Office of the New York State Comptroller. 2020-01-17. Archived from the original on 2026-09-16.
Additional Platform Time is the average time that customers wait at a station beyond their scheduled wait time... Transit's automated fare collection system does not require customers to swipe out of the system, so Transit does not know where and when each customer's trip ends.
- ↑ MTA only knows which six-minute interval you entered with your MetroCard, some 4% of people don't use metro cards, and the destination and arrival time are unknown so it's proxied by checking the next swipe within 48 hours and assuming that was the destination, and the route is unknown so the Dijkstra-optimal route is taken.