All posts

Anatomy of a real-time taxi booking

Real-time · 2 min read ·

I built the backend for a taxi dispatch system in Toronto, and the most useful thing I can give you is not code. It is the picture I kept drawing on every call with the team:

Rider Driver Dispatch server 1 · "book a taxi" 2 · "new job!" GPS ping every 2 s 3 · car position, live 4 · WebRTC voice call: phone to phone, never touches the server arrows 1-3 ride on one WebSocket connection each; opening a new HTTP request per ping would melt the server
The whole system on one napkin: two phones, one server in the middle, and a voice call that skips it entirely.

The three decisions that matter

WebSockets, not polling. A driver sends a location every 2 seconds. Over HTTP that is a new connection, headers, and auth on every ping. Over one WebSocket it is a 30-byte frame. With 200 drivers online the difference is the whole ballgame.

The server owns matching, nothing else. Dispatch decides which driver gets the job and relays positions. It does not carry the voice call.

Voice goes peer to peer. WebRTC needs the server once, for the handshake (arrow 1 and 2 style messages that swap network addresses). After that, audio flows phone to phone. Zero bandwidth cost on your side, lower latency for them.

Everything real-time in this system is a fan-out of small facts: "driver moved", "job accepted", "car arrived". If you model it as events and keep each event tiny, the architecture stays boring, and boring is what you want at 2 a.m. when a taxi is lost.

Stack for the curious: Laravel for the API and matching, WebSockets for the live channel, WebRTC for the calls, and a queue (see the first post) for receipts and notifications.

Notes from readers

  1. No notes yet. The first one is the bravest.
Building something like this? I can help. Contact