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.

21CTO
21CTO
21CTO
How We Built a Scalable Uber‑Like Backend with Go, UDP & ProtoBuf
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 .

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

GoProtobufRide HailingUDPR-treeOSRM
21CTO
Written by

21CTO

21CTO (21CTO.com) offers developers community, training, and services, making it your go‑to learning and service platform.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.