How We Built a Scalable Uber‑Like Backend with Go, UDP & ProtoBuf
This article details the design and implementation of a Go‑based backend for a ride‑hailing app, covering real‑time vehicle tracking, route planning with OSRM, bandwidth‑saving UDP + ProtoBuf communication, in‑memory storage, R‑tree indexing, and the full API workflow.
Overview
The story began in 2015 as a design project to develop a mobile ride‑hailing application that could display real‑time positions of taxis or shared cars. The goal was to show animated routes and implement optimal‑path algorithms.
First Step
We started by handling requests to store vehicle coordinates and creating a second request to generate animations for the cars, similar to what Uber or Didi display.
Because the raw coordinates were coarse, cars sometimes appeared in unrealistic places (fields, forests, rooftops). To improve this, we adopted the OpenStreetMap Routing Machine (OSRM) for route planning while keeping the same update interval.
The workflow was:
Send request
Obtain coordinates
Transmit coordinates to the server
Plan route via OSRM
Return data to the mobile client
This added routing layer worked, but we encountered a one‑way‑road issue where inaccurate GPS caused the start point of a route to be off, leading to incorrect navigation.
We solved it by discarding routes shorter than 20 meters and checking the shortest distance between two points before planning.
Data to Track
Driver (vehicle) location (longitude, latitude)
Driver session information (session ID)
Order records (order ID and trip cost)
We needed each transmission to be under 100 bytes, so we evaluated transport protocols.
Protocol Choice
Considering performance and bandwidth, we selected UDP because it sends datagrams without acknowledgment, is extremely lightweight (≈20 bytes overhead), and is not blocked in our region.
Data Format
Among JSON, MsgPack, and ProtoBuf, we chose ProtoBuf for its compactness. A typical packet contains 42 bytes of payload plus a 20‑byte IP header, totaling 62 bytes per tracking update.
Persistent Storage
We persisted data using Percona for durability, Redis as a cache, and ElasticSearch for geocoding queries. To support fast nearest‑driver searches, we evaluated KD‑tree and R‑tree; the latter provided a balanced tree suitable for our N‑nearest‑neighbor queries.
Final Backend Algorithm
Receive data via UDP
Attempt to fetch driver data from persistent storage
If missing, retrieve from Redis cache
Validate data integrity and freshness
Persist driver data
Initialize LRU cache if absent
Update R‑tree index
We exposed HTTP endpoints for:
Returning the nearest drivers
Deleting a driver by license plate or session ID
Fetching trip information
Fetching driver details
Summary
The completed ride‑hailing backend features UDP + ProtoBuf for bandwidth‑efficient data transfer, in‑memory storage with Percona, Redis caching, R‑tree for fast nearest‑driver queries, LRU for recent positions, and OSRM for map matching and custom route generation.
Source code and examples are available at https://github.com/maddevsio/openfreecabs .
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
21CTO
21CTO (21CTO.com) offers developers community, training, and services, making it your go‑to learning and service platform.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
