Inspiration
Miami is heavily dependent on cars, and its public transportation network is limited compared with many other major U.S. cities. Miami-Dade’s Metrorail has only two lines, the Green and Orange lines, which means buses have to cover much of the county that rail does not reach.
Buses can be delayed by traffic or other disruptions, but there is another problem that is much harder to see: ghost buses. A ghost bus is a bus that is scheduled to serve a stop but never actually arrives.
This not only makes public transportation less reliable for riders, but it is also difficult to understand how often it happens, where it happens, and which routes are most affected if the available data is never analyzed together.
That is why we built Ghost Bus-ters. We wanted to use scheduled and real-time transit data to identify these missing buses, make the problem visible, and create a clearer picture of where public transportation is failing riders.
The data already exists. But without processing and analyzing it, it is much harder to understand the problem or know where improvements are needed.
What it does
Ghost Bus-ters combines Miami-Dade’s scheduled GTFS data with real-time vehicle data from Miami-Dade’s ArcGIS Bus Real-Time service to detect when a bus was supposed to serve a stop but never appears.
The platform lets users:
- explore Miami’s bus network on an interactive map
- see live vehicles
- identify detected ghost buses
- analyze historical observations over time
By connecting schedule data with actual vehicle movement, Ghost Bus-ters turns raw public transit data into useful information about where ghost buses happen, how often they happen, and which routes are most affected.
How we built it
We built Ghost Bus-ters by combining Miami-Dade’s GTFS schedule data with its ArcGIS real-time bus API.
The scheduled data tells us where and when a bus is supposed to be, while the live feed gives us the actual GPS positions of buses currently operating.
Our Java Spring Boot backend polls the real-time API every 20 seconds and stores bus positions over time in a PostgreSQL/Timescale database powered by Tiger Data.
We then compare those historical positions with scheduled stop times. If a bus was expected at a stop but we cannot find evidence that it reached that area within the expected time window, we mark that stop as missed and use those results to identify ghost buses and calculate reliability statistics.
On the frontend, we used React, TypeScript, and MapLibre GL to turn that data into an interactive map where users can explore routes, stops, live buses, and reliability information without having to interpret the raw datasets themselves.
We also integrated Snowflake for analytics and deployed the application on DigitalOcean, giving us a complete pipeline from data collection to processing, analysis, and visualization.
Challenges we ran into
One challenge was time synchronization. Our backend on DigitalOcean was using UTC, while the transit data followed Miami local time. This initially caused scheduled and real-time data to be compared incorrectly, making buses appear much later than they actually were.
We caught this early and fixed it by normalizing all timestamps before running our detection logic.
We also had to deal with the fact that our two main data sources structured routes, trips, and vehicles differently. The GTFS schedule files and the Miami-Dade real-time API did not share identifiers in a straightforward way, so we had to create matching logic to reliably connect scheduled service with live vehicles.
A more practical limitation was time. Because we only had the duration of the hackathon to collect live data, we could not build a large enough historical dataset to produce meaningful long-term reliability statistics yet. The system is designed to keep accumulating data over time, which will make those insights much more useful.
Accomplishments that we're proud of
We integrated the different parts of the project very early, which helped us catch issues quickly and avoid bigger integration problems later in the hackathon.
We are also especially proud that three members of our team were attending their first hackathon ever, and we still managed to build a complete working project together.
Most importantly, we are happy that we worked on a problem we genuinely care about using real, live transit data. Instead of relying on simulated, hardcoded, or mocked information, Ghost Bus-ters works with actual public transportation data from Miami-Dade, making the project much more grounded in a real problem.
What we learned
We learned how powerful public APIs and open data can be when raw information is transformed into something people can actually understand and use.
The data was already publicly available, but combining and processing it gave it much more meaning.
We also learned a lot about collaboration. For some members of the team, this was their first time working with GitHub in a real team environment, so using branches, merging changes, and coordinating development was a big part of the experience.
On the technical side, we touched many different parts of a full-stack application: frontend development, backend logic, database integration, deployment, domain and DNS configuration, and working with live external data sources.
That end-to-end experience was one of the most valuable parts of the hackathon.
What's next for Ghost Bus-ters
We are really proud of what we built during the hackathon, but the most valuable part of Ghost Bus-ters will come with time.
Our next step is to keep collecting real transit data so we can build a much larger historical dataset and produce more reliable long-term statistics.
With enough data, we could identify:
- which routes are most affected by ghost buses
- which stops and areas see the most missing service
- which times of day are less reliable
- how reliability changes over time
We would also like to turn those insights into clearer tools for both riders and transit agencies, making it easier to understand where service is failing and where improvements could have the most impact.
Built With
- api
- digitalocean
- docker
- gtfs
- java
- maplibre
- postgresql
- react
- rest
- snowflake
- springboot
- sql
- tigerdata
- typescript
- vite
Log in or sign up for Devpost to join the conversation.