The solution we're building

NFTA's own data in, a simple screen out.

We read the information NFTA already produces, work out the next departures for every location, and serve a plain web page any screen can show. This page is the whole system, end to end.

Click any part of the map to see what it does
Backend service Docker · Railway NFTA's live bus feed Live bus feed GTFS-RT The published schedules Static GTFS bus + rail Live poller Live poller every ~30s Schedule ingester Ingester auto-refresh The resolver Resolver stops → times Board API Board API ?loc=<code> Board pages Board pages ?loc=<code> The displays Displays OptiSigns Redis, the live cache Redis live cache PostgreSQL, the source of truth PostgreSQL config + data Admin console, Phase 2 Admin console Angular · Phase 2

Technology: Python & FastAPI · PostgreSQL · Redis · runs in a container on Railway. The same kinds of tools NFTA's own team already works with, so it's straightforward to support long-term. Curious how the data is organized underneath? Explore the data model →

When things go wrong

Built to keep working

A feed hiccups

Screens keep showing the last good information with a small "as of" note. Riders never see a blank board or an error.

Something restarts

No single piece holds anything irreplaceable. Settings and schedules live safely in the database, and the live picture rebuilds itself within about 30 seconds.

A real problem

The team is alerted right away and can fix it before anyone notices. The screens just keep counting down from the last good data.

Many screens, one station

Each screen shows its own view

Big stations have more than one screen. University has three, one for each set of boarding bays, and each shows only the departures for the bays it faces. Same system everywhere; each screen simply carries its own short list of stops. Try them:

And the same idea covers every other split: the MTC interior signs each show specific routes, and Allen's track-level sign shows one direction only. NFTA staff can change any screen's view at any time, without touching the screen itself.

How it's organized

A clean, simple structure

Everything the platform knows lives in a few well-defined places. The first three run the screens today; the next three are already designed in, ready for Phase 2. Click any to peek inside.

Screens & locationsRuns now

Each display location is defined once: where it is and what it shows. The physical screens then point at a location, and several can share the same one.

That's what makes "100 screens, fewer locations" simple: define a location once, add as many screens as you like.

Routes shownRuns now

Which routes appear on each screen, and in what order. Filled in automatically from NFTA's data; nobody hand-picks routes. It can be fine-tuned later (hide one, reorder) if a location ever needs it.

Schedule & live dataRuns now

NFTA's full bus and rail schedules, loaded, versioned and kept current, with the live bus information layered on top. This is the source every departure is worked out from.

Messages & alertsReady for later

Service messages to show on screens: a detour, an elevator outage, a weather note. The structure is in place now; the tools to post them come with the admin console in Phase 2.

People & departmentsReady for later

Who is allowed to manage which screens. Set up so each department (bus, rail, and beyond) can run its own screens without affecting others.

Screen contentReady for later

A screen can hold more than departures. The structure already allows messages, weather and other content to be added as separate blocks, with no rebuild.