If you ask most web developers how to build a live leaderboard, the answer sounds straightforward: open a WebSocket, push JSON updates when someone crosses a sector, and render the sorted table in React. That works well enough for a typical dashboard.
It stops working the moment you put twelve sim rigs on the same track, send them into Turn 1 separated by three hundredths of a second, and watch the screen freeze.
When we started building CHRONO, our platform for commercial venues and broadcast events, we quickly ran into constraints that normal web development rarely encounters. Live timing looks like a simple table with lap numbers, but keeping that table accurate during a close race requires rethinking how data moves across the room.
The problem with ordered delivery
Almost every standard web connection runs over TCP. TCP promises that every byte arrives reliably and in the exact order it was sent. In an office tool or a store checkout, that guarantee is essential. On a race track, it works against you.
If Car 4 crosses Sector 2 at 250 km/h and a single network packet drops over the venue network, TCP halts all downstream data while it waits for a retransmission. By the time that missing packet arrives 200 milliseconds later, the position data inside it is already useless. The car is somewhere else entirely.
Worse, because the connection paused to wait for that stale packet, fresh timing marks from eleven other cars stacked up in the queue behind it. On the broadcast screen, the entire leaderboard freezes for a beat, then jerks forward to display an overtake that actually finished two corners ago.
Streaming live positions over UDP
To keep screens responsive, we split CHRONO into two separate data paths. General event management, driver rosters, and official race results still travel over standard web requests. But the live stream of car positions runs through a dedicated telemetry service using WebTransport over UDP. This connects directly to the shared memory layer we built for handling multi-sim telemetry pipelines and our driver display in APEX.
Because UDP datagrams travel independently, one dropped packet cannot block the ones behind it. If a frame goes missing, the client simply paints the next incoming snapshot a few milliseconds later. The display stays smooth, and viewers see overtakes unfold as they happen on track.

When network arrival lies
Dropping stale packets keeps the feed smooth, but an even trickier problem shows up at the finish line: clock synchronization. Simulators like Assetto Corsa or iRacing update their internal physics at up to 400 Hz, while network telemetry samples at a much lower rate.
When two drivers cross the line separated by four milliseconds, the second car's packet can easily reach the central timing server a fraction of a millisecond before the first car's packet. Thread scheduling on the rig PC or a minor network switch delay is all it takes. If the server ranks finishes by when packets arrive over the wire, it crowns the wrong winner in front of the whole venue.
The only reliable fix is capturing the simulator's internal physics tick at the precise moment the virtual transponder crosses the timing line. Our rig agent records that sim timestamp alongside the sector index, and the timing engine uses it to order the standings. Network jitter might influence when a packet arrives on the server, but it cannot alter who got to the line first.
Keeping the board honest
Good timing software does not need complex visual tricks. It comes down to a pair of quiet architectural habits: letting go of dropped packets so the screen never stalls, and trusting the car's physics clock rather than network arrival time.
When twelve cars brake into the first corner on a crowded grid, those two decisions make the difference between a jerky screen and a timing board spectators can rely on.
If you run a sim racing venue or broadcast event, take a look at how CHRONO handles live race sessions.




