Building Real-Time Order Tracking with WebSockets: Lessons from a Production Restaurant App
Real-time order tracking looks simple from the outside: a little map, a moving dot, a status label. "Order confirmed → Preparing → On the way." Then you build it, ship it, and watch it break at 8 PM on a Friday when 200 riders are online — and you learn that geospatial state is a stream, not a point. I work on MealApp , a restaurant marketplace in Antwerpen that handles delivery, pickup, and…
Real-time order tracking appears simple from the outside, featuring a map, a moving dot and a status label. However, implementing it proves to be deceptively difficult. MealApp, a restaurant marketplace in Antwerp that provides delivery, pickup and table reservations within a single app, encountered significant challenges while building their live rider tracking feature. This tutorial post outlines the architecture, the bug they shipped twice, and the solution they found.
The naive version of the approach involves sending the rider's location every two seconds using setInterval and broadcasting the location update to the customer's app. This works in development, staging, and the demo to the team, but fails in production.
The main bug they shipped twice was due to treating rider.location as a single mutable object. Two issues arose from this: out-of-order delivery and concurrent updates racing. Out-of-order delivery occurs because networks do not guarantee ordering, causing location updates to be out-of-sync. Concurrent updates race when multiple nodes behind a load balancer process different updates for the same rider at the same time, leading to inconsistencies.
To fix the problem, they adopted an append-only event log and timestamped projection instead of storing the location. They store every location as an immutable event, including a clientTimestamp and serverTimestamp, so the consumer can project the newest valid one. This way, they append new events to the store, rather than overwriting the existing location. They also ensure that only the newest event is broadcasted to the customer app.
On the customer's side, they follow the same discipline of only keeping the newest position. They update the rider marker only if the received position is newer than the last seen position. This eliminates the teleporting issue and drops stale-location reports to zero.
The same approach was applied to order status. They treated order status as events rather than a simple flag that could be disagreed upon by two services. This resulted in a more resilient system that degrades gracefully, displaying a position that is at most two seconds old, rather than an incorrect one.
Written by urgent.news from Dev.to's reporting — not their text. Machine-written — may contain errors; check the original before relying on it.