E. Leveque
ENTheme: system
← Back to the course (P3 · km 58,2)

Zotracker

Live GPS tracking of a foot race: my loved ones follow me on a map, with nothing to install.

A simulated race on the official Grand Trail d'Auvergne route.

The problem

Zotracker was born for the Lille marathon: my parents, family and friends wanted to follow me live. It runs in the browser, with no app to install, and I plan to reuse it on other races.

The decisions

JSON files rather than a database

Trade-off: No service to run or back up. Downside: disk writes are on me. I've already added a retry on failure and a refusal to start if the file is corrupted.

A vanilla JavaScript front end, no bundler

Trade-off: No build step. Downside: duplicated code between server and browser. Statistics are computed twice, and the two results already diverge on the estimated finish time before the start.

Distance computed on the GPX route

Trade-off: Distance follows the official course, without the GPS zigzag. Points more than 100 m away are ignored, and a gap above 150 m shows "off route". Without a GPX file, the server falls back to raw points, which are less accurate.

The architecture

Zotracker architectureThe runner's phone GPS, which can cut out when the screen locks, sends the position to the Node.js server with a tracker key. The server projects it onto the GPX route, computes pace and split times, then streams the public page and the admin in real time, triggers alerts through Web Push and ntfy, and saves the state in JSON files. An optional simulation feeds a virtual runner into the same flow.Phone GPSbrowser or appcuts out when the screenlocksSimulationvirtual runneroptionalNode.js serverprojects the positiononto the GPX route,computes pace andsplit timesPublic page and adminlive trackingAlertsWeb Push, ntfy (private SOS)state.json, secrets.jsonstorage in JSON filestracker keyreal time (SSE)Zotracker architectureThe phone GPS, which can cut out when the screen locks, sends the position to the Node.js server, which projects it onto the GPX route then feeds the public page and the admin in real time, the Web Push and ntfy alerts, and JSON files. An optional simulation feeds a virtual runner into the server.Phone GPSbrowser or appcuts out when the screen lockstracker keyNode.js serverprojects onto the GPX route,pace and split timesPublic page and adminreal time (SSE)AlertsWeb Push, ntfy (private SOS)state.json, secrets.jsonstorage in JSON filesSimulationvirtual runner, optional
Solid line: always called. Dashed: optional. Orange: the weak link on race day, the phone GPS.

The wall at km 60

On race day, anything can give out: the network drops, the browser GPS shuts off when the screen locks (on iPhone), and safety alerts must still go out. Points are queued when the network drops; the rest of that reliability is still to be built.

What I take from it

An app used on race day isn't judged by its demo: it's judged at the worst moment of the race. Hence the simulation mode, to test without running.