What I Learned Building a Transit Router for Ghana's Tro-tros

·8 min read

I've been working on Trosky, a routing app for tro-tros in Accra and Kumasi. The goal is simple: tell someone which tro-tro to take from point A to point B. Getting there turned out to be more interesting than I expected.

The first thing that broke my assumptions

Early in development, the router kept returning zero direct routes for most stop pairs. My first instinct was a bug. I spent time checking the algorithm, retracing the data pipeline, running the numbers again.

The algorithm was fine. The data was incomplete, but the zero results were also telling the truth: most tro-tro journeys in Accra genuinely require a transfer.

The network runs on a hub and spoke model, where major terminals act as connection points between routes rather than routes connecting directly stop to stop. Terminals like Abeka Lapaz handle 112 trips. Most regular stops handle exactly one. So if you're going from Kaneshie to Atomic Junction, there's no single tro-tro doing that full journey. You ride to a terminal, you transfer. That's not a gap in the data. That's the system.

Once I understood that, the routing logic made much more sense to design around.

How the routing actually works

The router runs in two phases.

Phase 1 looks for a direct trip: a single tro-tro that serves both your origin and destination in the right order. This works well for terminal-to-terminal journeys and routes that happen to overlap. When it finds a match, it returns the stops between origin and destination and ranks results by fewest stops.

Phase 2 kicks in when no direct trip exists. It searches for a transfer point: a stop that appears on a trip from your origin and also on a trip heading to your destination. The best transfer points are terminals with high trip counts, because more trips means more options for the second leg. When Phase 2 finds a match, it returns both legs of the journey and the transfer stop.

If both phases fail, the app recommends nearby stops that do have routes, within a few kilometers of the destination.

The underlying data structure that makes this fast is a stop index: a lookup table mapping every stop to the list of trips that serve it. Finding routes becomes a matter of checking which trips serve the origin, which trips serve the destination, and whether any stop connects them.

The harder problem: the data itself

The routing logic was solvable. The data is a different situation.

Trosky uses GTFS, the global standard for transit data. In theory it covers routes, stops, trips and schedules in a consistent format. In practice, the available GTFS data for Accra and Kumasi is a partial picture. Accra has thousands of tro-tro routes. The current dataset has 651 trips. Kumasi has 668.

Beyond coverage, there are consistency issues. The same stop appears under different names across different records. Many routes only have data for one direction, with no return trip. Stop coordinates are sometimes off. There's no schedule data at all, just stop sequences with no timing.

This isn't unusual for informal transit systems. Tro-tros aren't run by a central authority with a data team. Routes exist because drivers know them, not because someone filed paperwork. Capturing that into a structured dataset is genuinely hard, and the existing GTFS files reflect that difficulty.

The current data gives maybe 20 to 30 percent route coverage. A more complete dataset would change what the app can do significantly.

What's still missing

A few things would make Trosky substantially more useful:

  • More complete GTFS data is the biggest one. More trips in the dataset means more routes the app can actually find.
  • Walking connections would help a lot too. Right now if there's no tro-tro connection between two stops, the router returns nothing. In reality, walking 300 meters to a better-connected stop is often the right answer. Adding that as a routing option is on the list.
  • Multi-transfer routing would open up more of the city. Currently the router handles one transfer. Two transfers would cover significantly more origin-destination pairs.
  • Real-time vehicle positions would make the app practically useful rather than just directionally correct, but that requires a different kind of infrastructure.

It's open source and the data problem is solvable with help

Trosky is open source. The code is one part of what needs work. The data is another, and that's where people with local knowledge can contribute in ways that no algorithm can replace.

If you know Accra or Kumasi's routes well, that knowledge is directly useful. If you want to work on the routing algorithm, add walking connections, build out multi-transfer support, or improve the data pipeline, there's real work to do.

The project is at github.com/konuamah/ghana-gtfs-project. Contributions on either the code or the data side are welcome.