fivenines
1/38

Theory Tutorial

The product: a ride exchange

Time
5m
Level
not specified
Artifacts
theory + practice
Progress0%
Lesson 0.2

The product: a ride exchange

The obvious design is to treat ride hailing as ordinary request/response CRUD: a rider asks for a row, a driver updates a row, and a backend coordinates the rest. It makes the happy path simple, but it protects the wrong property. The exchange core must clear time-sensitive rider demand against changing driver supply, while slower settlement and reporting work remains outside that latency boundary.

Uber is an exchange: riders submit bids for transportation (demand orders), drivers stream availability (supply orders), and a matching engine continuously clears the market under latency constraints, with price (surge) as the balancing mechanism. Framing it as an exchange is more than a metaphor — it dictates the architecture. Like a financial exchange, the core loop (order in → match → execution) must be extremely fast and extremely available, while everything around it (settlement, reporting, analytics) can be slower and more forgiving. That asymmetry is the seed of Parts 2 and 3.

The system in context

flowchart LR
  R["📱 Rider app"] --> X
  D["🚗 Driver app"] --> X
  OPS["🖥️ City ops and support staff"] --> X
  subgraph X ["RideX — the ride exchange"]
    CORE["Exchange core: presence, matching, trips, pricing"]
    SUPPORTING["Supporting: identity, payments, comms, ratings"]
    PLATFORM["Platform: infra, observability, data and BI"]
  end
  X --> MAPS["🗺️ Map and routing provider"]
  X --> PSP["💳 Payment service provider"]
  X --> KYCV["🪪 Identity and background-check vendor"]
  X --> TEL["📞 Telephony, SMS and push vendors"]
  X --> REG["🏛️ Regulators and tax authorities"]
Context diagram. We build the exchange; we buy maps, payment processing, background checks and telephony.

Functional requirements

We will cover a deliberately broad slice of the real product. Grouped by who they serve:

GroupRequirementsBuilt in
IdentityRider signup/login; driver onboarding with document + background checks; profiles; devices1.2
SupplyDriver goes online/offline; continuous location ingestion; nearby-driver queries; rider sees cars moving on the map1.4
DemandFare quote with ETA before requesting; ride request; scheduled rides; ride tiers (economy / XL / premium)1.3, 1.5
MatchingDispatch: candidate selection, ranked offers to drivers, accept/decline/timeout, re-dispatch1.6
TripsFull lifecycle: assigned → arriving → in progress → completed / cancelled; live tracking; route recording; cancellation fees1.7
MoneyCard auth and capture; wallets and promo credits; tips; a double-entry ledger; weekly driver payouts; receipts and invoices1.8
CommsPush/SMS notifications; rider–driver in-app chat; phone-number-masked calls1.9
TrustTwo-way ratings; trip history; support tickets; safety features (share trip, SOS); fraud detection1.10, 2.11
BusinessCity-ops dashboards; driver earnings statements; financial and regulatory reporting; experimentation and BI1.13, 2.10
🧠 Load note

Pooled rides (UberPool-style shared trips), food delivery, and multi-modal transport reuse this exact architecture with a more complex matcher; we name where they would plug in but do not design them. This keeps the matching lessons at one level of complexity.

Now consider what happens when a maps or payment vendor is unavailable while riders and drivers are still trying to form trips. If the central guarantee disappears here, the design has confused an optimization with a correctness boundary.

Next step

See what actually stuck.

Take the practice scenarios now.

Explore the full Build Your Own Uber track