Marketplaces, an interactive architecture walkthrough
Ride-hailing platform: how the architecture works
How a ride-hailing platform streams driver locations, matches a rider to a nearby driver, prices the trip with surge, and takes payment.
This is a learning explainer based on public engineering writing and general design practice. It is simplified, it is not the actual architecture of any company, and it may be inaccurate.
Interactive diagram
Overview
A ride-hailing platform is a real-time marketplace. Drivers stream GPS positions into a geospatial index, a trip service owns the state of every ride, and a matching service combines nearby candidates with road-network ETAs to pick a driver. This is a generic ride-hailing reference design, not the architecture of any specific company.
Trade-offs and what changes at scale
Matching each request greedily to the nearest driver is simple but can leave other riders worse off; batching requests for a few seconds and matching them together gives better global results at the cost of latency. Location pings are the highest-volume traffic, so the geospatial index and the event stream are partitioned by area (geohash, S2 or H3-style cells) and by city or region, and trip state is sharded the same way rather than kept in one database. Surge is smoothed over time and zones so prices do not flicker. At ride-hailing volume operators usually run their own routing and ETA engine, because a maps API call per candidate is slow and costly.
How it works, step by step
The walkthrough above, as text. Each step lights up the components named under it.
The rider opens the app; requests hit the load balancer, then the gateway, which rate-limits and validates the JWT signature locally with cached keys. The auth service is only needed for login and revocation checks.
The rider enters a destination and gets a fare estimate. Pricing asks the ETA service for route distance and reads the current surge multiplier for the pickup zone from the surge store.
Confirming creates the trip in 'requested' state in PostgreSQL. The trip service is the single owner of state, so every transition is consistent and auditable.
Meanwhile online drivers keep a persistent connection open to the driver gateway and stream GPS pings over it. The gateway writes the latest position to Redis and publishes every ping to Kafka.
Matching queries the geospatial index for nearby drivers, then ranks candidates by real pickup ETA, not straight-line distance, using the ETA service and routing engine. The chosen driver is reserved with a short-lived lock in Redis (a SET with NX and an expiry) for the offer window, so concurrent requests skip a driver while an offer to them is open.
The best driver gets the offer over the connection they already have open to the driver gateway, because an offer expires in seconds. A mobile push through the notification service is only a fallback for a driver whose app is in the background. If they decline or time out, the lock is released and matching moves to the next candidate.
The driver accepts, or declines, over the same open connection. The matching service confirms the reservation and releases the offer lock, and the trip moves to matched, then en route and in progress as the driver app reports each change.
During the ride, a tracking consumer reads the location events of drivers on active trips from Kafka and hands them to the trip service, which pushes them to the rider's app through the gateway (a long-lived connection in practice), so the map moves live.
On completion the trip service asks pricing for the final fare, then asks payments to charge it with an idempotency key derived from the trip id, so a retry does not charge twice. Payments calls the processor and records the result in its own ledger database, so money data stays isolated. Many platforms authorise the card at request time and capture at completion.
Separately, pricing consumes location and trip events from Kafka to compute supply versus demand per zone and writes updated surge multipliers to the surge store asynchronously, which is what step 2 reads.
After the ride, rider and driver rate each other. Ratings are stored separately so they never slow down the trip path.
Status changes such as driver arriving and receipts reach riders through the same notification service, by push and, for key moments, SMS, which keeps channel logic in one place.
Every service exports metrics, logs and traces to observability, so matching latency, payment failures and ping lag can be alerted on.
Sequence diagram
The same walkthrough as a UML sequence diagram, one lane per layer or group (24 components in all), left to right in the order a request reaches them, numbered by step. A loop on a lane is a step that stays inside that group. Solid arrows are synchronous calls, dashed are asynchronous.
Key components
Client appslayer
- Driver app: go online, accept offers, stream GPS
- Rider app: request ride, track, pay
Edge layerlayer
- API gateway: routing, rate limits, auth check
- Auth service: login, JWT tokens
- Load balancer: TLS termination, traffic spreading
Pricing & paymentsdomain
- Payments database: ledger, payment records (postgresql)
- Payments service: charges, receipts
- Pricing service: fares and surge multipliers
- Surge store: surge multipliers per zone (redis)
Third-party providerslayer
- APNs / FCM: mobile push delivery
- Payment processor: card charges
- Routing engine: road graph, traffic, ETAs (own or provider)
- SMS provider: text messages
Trip & dispatchdomain
- ETA service: pickup time estimates
- Matching service: find, rank, reserve, offer to drivers
- Trip database: trips, state history (postgresql)
- Trip service: trip state machine
Real-time location pipelinedomain
- Driver gateway: WebSocket/gRPC: GPS pings in, offers out (grpc)
- Event stream: location, trip, demand events (kafka)
- Geospatial index: driver positions by geohash, offer locks (redis)
Engagementdomain
- Notification service: push fallback, rider push and SMS
- Ratings database: ratings and reviews (postgresql)
- Ratings service: two-way trip ratings
Observability
- Observability: metrics, logs, traces
Sources
Public writing this explainer draws on. Read these for what the real systems actually do.
Make it yours
Copy this diagram and its walkthrough into your own workspace, then change anything: swap Postgres for DynamoDB, add a cache, rewrite the narration. Free, and it uses no AI credits.
Related walkthroughs
- Food delivery platformHow a food delivery platform runs each order as a durable state machine, tracks couriers in a geo index, and times dispatch to when food is ready.
- Ticket booking with seat reservationHow a ticketing system sells each seat once under heavy demand: waiting room, cached seat map, time-limited holds, conditional updates and safe payment.
- E-commerce checkout and inventoryHow an online store turns a cart into an order: stock reservation, idempotent payment, a saga with compensation, and reliable order events.
This is a learning explainer based on public engineering writing and general design practice. It is simplified, it is not the actual architecture of any company, and it may be inaccurate. Real systems differ in the details. Browse the library.