Cab Booking System
Cab booking (Uber/Ola style) LLD covers riders, drivers, trips, location matching, fare calculation, and trip state — usually scoped to one city and in-process matching for inte…
Introduction
Cab booking (Uber/Ola style) LLD covers riders, drivers, trips, location matching, fare calculation, and trip state — usually scoped to one city and in-process matching for interviews.
Define Rider, Driver, Trip, LocationService, MatchingService, and FareCalculator. Trip states: Requested, Accepted, InProgress, Completed, Cancelled.
Extensions: surge pricing, ride pooling, rating.
Understanding the topic
Key concepts
- Driver: location, availability, vehicle type.
- Rider requests trip with pickup/drop.
- Matching: nearest available driver.
- Trip lifecycle state machine.
- Fare = base + distance + time + surge.
- Strategy for matching and pricing.
Step-by-step explanation
- Rider requests ride with endpoints.
- MatchingService finds nearby available driver.
- Driver accepts; trip becomes Accepted.
- Driver arrives; trip InProgress.
- Complete trip; calculate fare; charge rider.
- Driver becomes available again.
Informative example
Trip lifecycle with matching and fare calculation:
public record Location(double lat, double lng) {}public enum TripStatus { REQUESTED, ACCEPTED, IN_PROGRESS, COMPLETED, CANCELLED }public final class Driver {private final String id;private Location location;private boolean available = true;public Driver(String id, Location location) {this.id = id;this.location = location;}public boolean isAvailable() { return available; }public Location location() { return location; }public String id() { return id; }void assign() { available = false; }void release() { available = true; }}public final class Trip {private final String id;private final String riderId;private Driver driver;private TripStatus status = TripStatus.REQUESTED;private final Location pickup;private final Location drop;public Trip(String id, String riderId, Location pickup, Location drop) {this.id = id;this.riderId = riderId;this.pickup = pickup;this.drop = drop;}public void accept(Driver d) {if (status != TripStatus.REQUESTED) throw new IllegalStateException();driver = d;d.assign();status = TripStatus.ACCEPTED;}public void start() { status = TripStatus.IN_PROGRESS; }public void complete() {status = TripStatus.COMPLETED;driver.release();}public TripStatus status() { return status; }}public final class MatchingService {public Optional<Driver> nearest(List<Driver> drivers, Location pickup) {return drivers.stream().filter(Driver::isAvailable).min(Comparator.comparingDouble(d -> distance(d.location(), pickup)));}private double distance(Location a, Location b) {return Math.hypot(a.lat() - b.lat(), a.lng() - b.lng());}}
FareCalculator strategy uses distance(pickup, drop); TripRepository persists history.
Real-world use
Real-world applications
- Location-based matching LLD.
- State machine for trip lifecycle.
- Strategy for surge and vehicle types.
Best practices
- Trip owns status transitions with guards.
- MatchingService stateless; drivers updated on assign/release.
- LocationService interface for GPS updates.
- Fare breakdown transparent to rider receipt.
- Cancel rules per status (fee if after accept).
Common mistakes
- Driver available flag not reset after trip.
- Matching without considering already-assigned drivers.
- No trip id for rider tracking.
- Mixing HLD geo-sharding into LLD unnecessarily.
Advanced interview questions
Interview Prep
Practice concise answers, then expand each card for the explanation.
1BeginnerQuestionCore cab booking classes?+
Answer
2BeginnerQuestionTrip states?+
Answer
3IntermediateQuestionNearest driver matching?+
Answer
4IntermediateQuestionSurge pricing?+
Answer
5AdvancedQuestionRide pooling LLD change?+
Answer
Summary
Driver availability and location drive matching. Trip state machine controls lifecycle. MatchingService finds nearest available driver. Fare and surge via strategy pattern. Scope LLD; defer geo-sharding to HLD.