Design a Mobile Public Transit App: Real-Time Transit

“Design a transit app” is a niche but technically rich mobile-system-design prompt. Citymapper, Transit, Moovit, Apple Maps Transit are the references. The interview tests whether you can reason about the GTFS data model, real-time vehicle tracking, multi-modal trip planning, and the offline-first requirements of “I am underground and need to know when my train arrives.”

Clarify scope

  • One city or multi-city?
  • Just bus/rail or also bike-share, scooters, ride-share?
  • Trip planning (point A to B) or just departure boards?
  • Real-time arrivals or schedule-only?
  • Pay-for-fare integration?

The GTFS data model

GTFS (General Transit Feed Specification) is the universal format for transit schedules:

  • Routes (e.g., “1 train”)
  • Stops (e.g., “59 St – Columbus Circle”)
  • Trips (one run of a route on a day)
  • Stop times (when each trip arrives at each stop)
  • Calendar (which trips run on which days)
  • Shapes (the geographic path of a route)

GTFS-realtime adds vehicle positions, trip updates (delays), and service alerts.

Schedule data: client or server?

  • Static GTFS for a major city is 50–500 MB compressed
  • Most apps cache the per-city schedule on device for offline lookup
  • Server provides differential updates (rare changes, mostly weekly)
  • Client computes “next arrivals at this stop” locally — needs offline

Real-time updates

  • GTFS-realtime feeds delivered as protobuf over HTTP, polled every 30–60 sec
  • Or WebSocket subscription for active trips/stops
  • Vehicle positions (lat/lon) animated client-side between samples
  • Trip updates: predicted arrival times that override the schedule

Trip planning

This is the algorithmically hardest part. Approaches:

  • RAPTOR (Round-Based Public Transit Routing) — the modern standard
  • CSA (Connection Scan Algorithm) — simpler, fast for fewer transfers
  • Multi-modal: combine walking + transit + bike-share segments

Server typically runs the routing engine; client renders results. For offline, OTP (OpenTripPlanner) or pre-computed transit-graph data can be embedded.

Live navigation during a trip

  • “You are on the 1 train, get off at 86 St in 3 stops”
  • Watch presence: tap to confirm boarding
  • Notifications: “Your stop is next”, “Get off here”
  • Disruption alerts: “Your route is delayed; here is an alternative”
  • Background location used sparingly to verify the user is on the predicted vehicle

Departure boards

  • Per-stop, per-route board showing next 3–5 arrivals
  • Refresh every 15–30 sec while screen is foregrounded
  • Apple Watch complication shows next arrival from the saved stop
  • Live Activity / Dynamic Island for active trips

Offline strategy

  • Cache schedules per city
  • Cache the trip plan when generated; works offline if no fresh real-time data
  • Show “Last updated 5 min ago” indicator when stale
  • Underground / no-signal: show schedule-based estimate as fallback

Map rendering

  • Vector tiles (Mapbox, MapLibre) for base map
  • Transit overlay rendered client-side from GTFS shapes
  • Vehicle markers updated via GTFS-realtime positions
  • Route highlighting on selected trip

Fare integration

  • Mobile ticketing: app-purchased ticket scanned at gate
  • OMNY / Clipper / Oyster: tap-to-pay using Apple Pay / Google Pay credentials
  • Subscription / pass management with auto-renewal

Accessibility

  • VoiceOver / TalkBack: announce next arrival times in natural language
  • Wheelchair-accessible filtering for trip planning
  • High-contrast mode for departure boards
  • Audio alerts for upcoming stops

Battery considerations

  • GPS only when the user is actively navigating; visit-based location otherwise
  • Background fetch limited to active trip
  • Reduce update frequency when app is backgrounded

Multi-city handling

  • Detect user’s city via location and cached city footprints
  • Download city schedule on first use; cache
  • Switch active city when user crosses a boundary or manually selects

What separates senior from staff

Senior candidates draw the GTFS client/server split. Staff candidates discuss the trip-planning algorithm choice, offline-first design, and the multi-modal integration story. Principal candidates address the data-quality problem (transit agencies vary widely in feed reliability) and the operational reality of running 50+ city integrations.

Frequently Asked Questions

Should I write my own routing?

No. OpenTripPlanner, Navitia, or commercial APIs (HERE, TomTom) all do this well. Build the UX; rely on a routing engine for the heavy math.

What about agency-specific quirks?

Reality of transit data — the BART feed is different from the MTA feed in subtle ways. Have an abstraction layer that normalizes per-agency adapters. Plan for “this agency’s GTFS-realtime is unreliable” as a permanent state for some.

How do I handle Subway-specific nuances?

NY Subway has uptown/downtown with the same route name; some lines run different patterns at night. These are GTFS modeling questions; the data is there but the app must surface it correctly.

Scroll to Top