GIS that makes the overlooked undeniable.
Real maps, real data, real people who needed someone to notice. New ones posted here roughly every week.
The 309 Doesn't Always Leave Elmhurst
A month of Pace's own bus tracker data, checked against Pace's own schedule: which buses never showed up, where, when, and why the wait at my stop was worse than any average suggested.
I catch the Pace 309 at the Elmhurst Metra station. It's the start of the line: every eastbound 309 trip begins there, at 1st Street and York, and heads out along Lake Street to Austin Boulevard. More than once this summer I stood at that stop on a weekday afternoon for over an hour with no bus. At that time of day, Pace's schedule says one should leave every half hour.
I wanted to know whether that was bad luck or a pattern. Pace doesn't publish any record of where its buses actually went, so I started keeping one.
How I got the data
Pace's Bus Tracker website shows live bus positions on a map. Behind that map is a request the page makes to Pace's server, route by route, that returns every bus currently on the route with its location. It needs no login or key. I wrote a small script that makes the same request for all 94 routes on the tracker, every minute or two, and saves the answers.
It ran from August 30 to September 30, 2026, and collected about 2.3 million bus positions from 575 different buses.
Then I compared those positions to Pace's published schedule (the GTFS feed Pace gives to Google Maps and other apps). For every scheduled trip, I checked each of its stops: did any bus on that route come within 500 meters of the stop within 15 minutes of the scheduled time? A trip where at least five stops could be checked, and not one of them was served, counts as a ghost trip: a trip on the schedule that never appeared on Pace's own tracker.
A few things this can and can't do:
- My computer wasn't watching all the time. The collector went down a few times (a reboot, a sleeping computer). Any stretch it wasn't watching is marked "unknown," not counted as a ghost.
- The tracker doesn't cover every route. Its route menu lists 94 routes. Another 40 routes that run on weekdays, about 17% of Pace's weekday trips, aren't on it at all, so I can't say anything about them. One more route, the 221 on Wolf Road, appears on the menu but showed just 2 positions all month. I left it out rather than call it a 100% ghost route.
- "Never appeared on the tracker" is not the same as "never ran." A bus that ran with its tracker switched off looks exactly like a bus that didn't run. I can't tell those apart, and nobody outside Pace can.
- The test is generous. Any bus on the route counts, in either direction, so a bus going the other way past a stop gives that stop credit. I'll come back to why that matters.
That left 123,187 scheduled trips on 86 routes that I could judge.
The whole system
Between 1.06% and 1.89% of the trips I could check never appeared on the tracker. That's roughly 1 in 94 to 1 in 53. On a typical weekday Pace schedules about 5,450 trips on these routes, and somewhere between 52 and 95 of them didn't show up.
It's a range because some trips are hard to call. When I looked closer at each ghost trip, some had a bus labeled with a different route passing a lot of their stops. Sometimes that's a bus running the trip under the wrong route number on the tracker; sometimes it's just two routes sharing a street. Trips where one such bus covered most of the stops I dropped as explained. The low end counts only trips where no single bus covered more than a fifth of the stops. The high end adds the ones in between, which I can't call either way.
All 86 measured routes as a table
| Route | Name | Trips checked | Never appeared |
|---|---|---|---|
| 366 | Park Forest - Chicago Heights | 1,069 | 10.8% to 26.4% |
| 367 | University Park - Park Forest | 738 | 25.5% to 26.1% |
| 357 | Lincoln Highway | 1,535 | 7.8% to 13.6% |
| 356 | Harvey - Homewood - Tinley Park | 1,483 | 2.1% to 9.2% |
| 542 | Bluff City | 1,171 | 3.0% to 9.1% |
| 890 | Chicago Heights - UPS Hodgkins Limited | 232 | 3.0% to 9.1% |
| 604 | Wheeling - Schaumburg | 1,005 | 8.5% to 8.7% |
| 508 | East Joliet | 550 | 4.4% to 8.6% |
| 564 | Jackson / 14th | 534 | 0.2% to 7.9% |
| 354 | Harvey - Oak Forest Loop | 634 | 3.1% to 7.7% |
| 358 | Torrence | 759 | 7.2% |
| 509 | Joliet-Fairmont | 751 | 2.5% to 5.7% |
| 471 | Highland Park-Northbrook Court | 413 | 0.0% to 5.6% |
| 359 | Robbins - South Kedzie Avenue | 1,113 | 5.1% to 5.4% |
| 310 | West Madison - Hillside | 807 | 0.1% to 5.2% |
| 353 | 95th/Dan Ryan CTA-Calumet City-Homewood | 1,761 | 4.9% to 5.1% |
| 803 | Carpentersville Local | 876 | 3.1% to 4.8% |
| 801 | Elgin-Geneva | 407 | 4.7% |
| 350 | Sibley | 3,175 | 4.0% to 4.4% |
| 549 | South Randall | 840 | 0.6% to 3.9% |
| 392 | Green Line Cicero CTA - UPS Hodgkins Limited | 158 | 2.5% to 3.8% |
| 317 | Westchester | 1,337 | 0.0% to 3.4% |
| 395 | 95th/Dan Ryan CTA - UPS Hodgkins Limited | 409 | 3.2% |
| 314 | Ridgeland Avenue | 628 | 1.4% to 2.4% |
| 223 | Elk Grove - Rosemont CTA Station | 2,669 | 0.7% to 2.2% |
| 270 | Milwaukee Avenue | 784 | 0.0% to 2.2% |
| 541 | Northeast Elgin | 1,192 | 0.2% to 2.1% |
| 302 | Ogden - Stanley | 674 | 1.5% to 1.9% |
| 472 | Highland Park - Highwood | 415 | 1.4% to 1.9% |
| 561 | Castlecrest via McAree | 492 | 0.0% to 1.8% |
| 563 | Great Lakes Naval Station | 630 | 0.2% to 1.6% |
| 505 | West Joliet Loop | 1,073 | 0.3% to 1.6% |
| 319 | Grand Avenue | 910 | 1.3% to 1.4% |
| 571 | Zion | 1,148 | 1.1% to 1.3% |
| 507 | Plainfield | 1,190 | 0.3% to 1.3% |
| 308 | Medical Center | 2,051 | 0.1% to 1.2% |
| 208 | Golf Road | 1,924 | 0.6% to 1.1% |
| 316 | Laramie Avenue | 1,276 | 0.6% to 1.1% |
| 305 | East Roosevelt | 1,382 | 0.9% to 1.1% |
| 349 | South Western | 3,230 | 1.0% to 1.0% |
| 215 | Crawford-Howard | 1,717 | 1.0% |
| 552 | North State - Spring Hill Mall | 1,138 | 0.0% to 0.9% |
| 290 | Touhy Avenue | 3,300 | 0.7% to 0.8% |
| 543 | Dundee-Carpentersville | 787 | 0.1% to 0.8% |
| 606 | Rosemont - Schaumburg Limited | 2,548 | 0.2% to 0.8% |
| 524 | West Aurora | 563 | 0.4% to 0.7% |
| 384 | Narragansett - Ridgeland | 573 | 0.0% to 0.7% |
| 303 | Forest Park - Rosemont | 1,198 | 0.0% to 0.7% |
| 332 | River Road - York Road | 761 | 0.0% to 0.7% |
| 554 | Elgin - Woodfield | 763 | 0.4% to 0.7% |
| 834 | Joliet - Downers Grove | 690 | 0.6% |
| 574 | CLC - Hawthorn Mall | 575 | 0.5% |
| 559 | Illinois Route 59 | 1,041 | 0.0% to 0.5% |
| 547 | Wing Park | 1,087 | 0.0% to 0.5% |
| 548 | Highland | 1,089 | 0.0% to 0.5% |
| 379 | Midway - Orland Park | 1,585 | 0.3% to 0.4% |
| 272 | Milwaukee Avenue North | 974 | 0.4% |
| 301 | Roosevelt Road | 1,977 | 0.2% to 0.4% |
| 352 | Halsted | 4,567 | 0.3% to 0.4% |
| 572 | Washington | 1,139 | 0.0% to 0.3% |
| 570 | Fox Lake - CLC | 626 | 0.3% |
| 364 | 159th Street | 2,830 | 0.3% |
| 100 | Pulse Milwaukee Line | 3,749 | 0.2% |
| 330 | Mannheim - LaGrange Roads | 2,125 | 0.1% to 0.2% |
| 568 | Belvidere | 1,386 | 0.2% |
| 309 | Lake Street | 1,139 | 0.0% to 0.2% |
| 331 | Cumberland - 5th Avenue | 1,879 | 0.1% to 0.2% |
| 533 | Northeast Aurora | 1,270 | 0.2% |
| 307 | Harlem | 2,958 | 0.1% |
| 565 | Grand Avenue | 1,389 | 0.1% to 0.1% |
| 381 | 95th Street | 3,521 | 0.1% |
| 250 | Dempster Street | 1,092 | 0.0% to 0.1% |
| 313 | St. Charles Rd. | 1,212 | 0.0% to 0.1% |
| 383 | South Cicero | 2,408 | 0.1% |
| 386 | South Harlem | 1,235 | 0.1% |
| 530 | West Galena - Naperville | 1,227 | 0.1% |
| 501 | West Jefferson | 1,365 | 0.1% |
| 315 | Austin Boulevard | 3,437 | 0.1% |
| 322 | Cermak Road - 22nd St. | 3,481 | 0.0% |
| 101 | Pulse Dempster Line | 3,888 | 0.0% |
| 213 | Green Bay Road | 1,875 | 0.0% |
| 311 | Oak Park Avenue | 1,631 | 0.0% |
| 318 | West North Avenue | 3,207 | 0.0% |
| 390 | Midway CTA - UPS Hodgkins Limited | 314 | 0.0% |
| 722 | Ogden Avenue | 1,213 | 0.0% |
| 802 | Aurora - Geneva via Lake Street | 1,233 | 0.0% |
Where: the south suburbs
The missing trips are not spread evenly. The 10 routes with the most confirmed ghost trips account for 68% of them, while running only 11% of the trips.
These are the 10 routes with the highest rates, among routes with at least 100 trips checked:
| Route | Name | Trips checked | Never appeared |
|---|---|---|---|
| 366 | Park Forest to Chicago Heights | 1,069 | 11% to 26% |
| 367 | University Park to Park Forest | 738 | 26% |
| 357 | Lincoln Highway | 1,535 | 8% to 14% |
| 356 | Harvey, Homewood, Tinley Park | 1,483 | 2% to 9% |
| 542 | Bluff City | 1,171 | 3% to 9% |
| 890 | Chicago Heights to UPS Hodgkins | 232 | 3% to 9% |
| 604 | Wheeling to Schaumburg | 1,005 | 9% |
| 508 | East Joliet | 550 | 4% to 8% |
| 564 | Jackson / 14th | 534 | 0% to 8% |
| 354 | Harvey to Oak Forest | 634 | 3% to 8% |
Six of the ten are in the south suburbs, around Park Forest, Chicago Heights and Harvey. Route 604 in the northwest suburbs stands out because its range is narrow: about 9% either way. On Routes 366 and 367, about one scheduled trip in four never appeared.
I'm deliberately not saying anything here about who lives along these routes. That's worth asking, but it needs Census data, not a guess.
When: late nights and weekends
By time of day, the morning rush is the most reliable: under 1.3% of trips starting between 6 and 9am went missing. After 7pm it climbs, and trips starting around midnight go missing 6 to 7% of the time. Weekends are worse than weekdays, with Saturdays roughly twice the weekday rate.
Why my stop didn't show up in any of this
Here's the part that surprised me. By the whole-trip test, the 309 is one of Pace's most reliable routes: almost none of its trips are ghosts. If I'd stopped there, I'd have concluded my hour-long waits were bad luck.
The problem is the generous test. At rush hour the 309 runs every half hour in both directions. If one trip doesn't run, the buses before and after it, and the buses going the other way, still pass most of its stops within 15 minutes. The trip gets credit for stops it never served. On a busy route, a whole missing trip can look like it ran.
So that system-wide range is a floor. On frequent routes, the real number is probably higher.
To check my own stop properly, I stopped asking "did a bus come near the stop?" and asked the question a rider asks: did an eastbound bus actually leave Elmhurst? Elmhurst is the end of the line, so buses arrive, park for a few minutes and then leave. I counted a departure only when a bus that had been at the station was, within 15 minutes, at least a kilometer and a half away and heading east, and timed it at the moment it left.
Getting that right took a few tries, and two of my early versions were wrong. The first one timed each bus at the moment it arrived rather than when it left. Buses park about 200 meters up York Street before leaving, so a bus that sat there for ten minutes made it look like a 129-minute wait that never happened. I found that by tracing individual buses ping by ping, and only trusted the method once it matched those traces.
What happened at Elmhurst
I paired every scheduled eastbound departure in September with the real departures, one bus per scheduled time, allowing a bus to be up to 5 minutes early and up to 30 minutes late (or until the next scheduled bus, if that's sooner).
103 of 525 scheduled departures never left. That's about one in five. But it depends heavily on the time of day:
| Weekdays | Scheduled departures checked | Never left |
|---|---|---|
| Before 6am | 21 | 5% |
| Morning rush, 6 to 9am | 126 | 25% |
| Midday, 9am to 2pm | 100 | 4% |
| Afternoon rush, 2 to 7pm | 161 | 34% |
| Evening, after 7pm | 57 | 7% |
At midday the 309 runs almost exactly to schedule. At rush hour, when the most people are trying to get home from the train, a quarter to a third of the scheduled buses never leave.
From the platform, that looks like this. Across all of September, the typical wait for the next bus was 4 minutes. But on weekday afternoons between 2 and 6pm, roughly a third or more of the scheduled departures were followed by a wait of over half an hour. On Wednesday, September 2, the 2:57, 3:33, 4:03, 4:33 and 5:03 buses never left. The next bus pulled out at 5:39pm, 2 hours and 42 minutes after the first one that didn't come. That's the kind of afternoon I'd been having.
It's the same trips, over and over. Some scheduled departures were missing on most of the weekdays I could check:
| Scheduled departure | Weekdays missing |
|---|---|
| 6:31am | 12 of 21 |
| 2:57pm | 9 of 17 |
| 5:03pm | 9 of 17 |
| 3:33pm | 8 of 18 |
| 6:01am | 8 of 21 |
| 4:33pm | 7 of 17 |
The 2:57 and the 5:03 are scheduled for the same bus.
The first trip of a bus's day is the one most likely to go missing. Pace's schedule data says which bus is meant to run each trip. When the Elmhurst departure is the first trip of that bus's day, it was missing 45% of the time (17 of 38, a small sample). When it's a later trip, 18%. That points less to buses running late in traffic and more to buses not getting out of the garage on time, or at all. Why that happens (drivers, vehicles, something else) is something only Pace can answer.
I checked the obvious alternative. Nearly every 309 bus also runs Route 313 during the day, switching at the Austin Boulevard end. If the tracker kept showing "313" on a bus that had switched to the 309, my method would have missed it. So I reran everything counting buses of any route label. Not one of the 103 missing departures turned out to have been run by a bus under another label.
What I can't tell you
- Whether a trip was cancelled or just very late. A bus more than 30 minutes late, or later than the next scheduled one, counts as missing. To someone standing at the stop, those feel the same.
- Whether a bus ran with its tracker off. I found one bus all month that left Elmhurst and then vanished from the tracker. Counting it or not changes nothing.
- Anything about the 40 routes the tracker doesn't cover.
- Whether September was typical. It's one month.
An earlier version
In early September I put up a live page for the Route 309, with a flyer at the stop, using a first version of this method. That version counted hours when my collector was switched off as missed buses, so it overstated the problem. It's still online, marked as out of date, and this page replaces it.