The Ride Sharing LLD problem (designing Uber or Ola) is one of the most commonly asked advanced LLD questions in product-based company interviews. It tests your ability to model real-time systems, state machines, and multiple interacting entities. This guide breaks down everything you need to ace it.
What Interviewers Are Testing
- Can you model a multi-state real-time system?
- Do you understand the State pattern for driver lifecycle?
- Can you design an extensible fare calculation system?
- How do you handle asynchronous events like driver acceptance?
Core Requirements
- Rider requests a ride with pickup and drop location
- System finds and assigns the nearest available driver
- Driver can accept or reject — timeout after 30 seconds
- Real-time trip status: Requested → Accepted → Ongoing → Completed
- Fare calculation based on distance, time, and ride type
- Post-trip ratings for both rider and driver
- Surge pricing during peak hours
Core Entities
- Rider — has profile, location, payment methods
- Driver — has vehicle, current location, state
- Trip — the central entity connecting rider, driver, route, fare
- Location — latitude/longitude value object
- RideRequest — captures pickup, drop, ride type
- FareCalculator — strategy for pricing
- MatchingService — finds nearest available driver
Driver State Machine
The State pattern is essential here. A driver is always in one of these states:
enum DriverState { OFFLINE, AVAILABLE, ON_TRIP, UNAVAILABLE }
class Driver {
state: DriverState;
location: Location;
goOnline() { this.state = DriverState.AVAILABLE; }
goOffline() { this.state = DriverState.OFFLINE; }
startTrip() { this.state = DriverState.ON_TRIP; }
endTrip() { this.state = DriverState.AVAILABLE; }
}Trip Lifecycle
enum TripStatus {
REQUESTED, DRIVER_ASSIGNED, DRIVER_ARRIVED,
ONGOING, COMPLETED, CANCELLED
}
class Trip {
id: string;
rider: Rider;
driver: Driver;
pickup: Location;
drop: Location;
status: TripStatus;
startTime: Date;
endTime: Date;
fare: number;
rideType: RideType; // ECONOMY | PREMIUM | XL
}Fare Calculation with Strategy Pattern
Different ride types have different rates. Surge pricing multiplies the base fare. Using Strategy keeps the Trip class clean:
interface FareStrategy {
calculate(distanceKm: number, durationMin: number): number;
}
class EconomyFare implements FareStrategy {
calculate(distanceKm: number, durationMin: number): number {
return 50 + (distanceKm * 12) + (durationMin * 1.5);
}
}
class SurgeFare implements FareStrategy {
constructor(private base: FareStrategy, private multiplier: number) {}
calculate(distanceKm: number, durationMin: number): number {
return this.base.calculate(distanceKm, durationMin) * this.multiplier;
}
}Driver Matching
In an interview, keep matching simple but extensible. Use a MatchingService that can swap algorithms:
interface MatchingStrategy {
findDriver(request: RideRequest, drivers: Driver[]): Driver | null;
}
class NearestDriverStrategy implements MatchingStrategy {
findDriver(request: RideRequest, drivers: Driver[]): Driver | null {
return drivers
.filter(d => d.state === DriverState.AVAILABLE)
.filter(d => d.vehicle.supportsRideType(request.rideType))
.sort((a, b) =>
distance(a.location, request.pickup) -
distance(b.location, request.pickup)
)[0] ?? null;
}
}Observer Pattern for Status Updates
Both rider and driver need real-time trip status updates. Use Observer:
interface TripObserver {
onStatusChange(trip: Trip, newStatus: TripStatus): void;
}
class Trip {
private observers: TripObserver[] = [];
addObserver(o: TripObserver) { this.observers.push(o); }
updateStatus(status: TripStatus) {
this.status = status;
this.observers.forEach(o => o.onStatusChange(this, status));
}
}Common Interview Mistakes
- Embedding fare logic in Trip — violates SRP. Use FareStrategy.
- Not modeling driver state transitions — interviewers specifically check this.
- Ignoring driver rejection flow — what happens when all nearby drivers reject? Re-search with wider radius.
- Missing RideType as an entity — Economy, Premium, XL have different vehicle requirements and pricing.
Follow-up Questions
- "How do you implement surge pricing?" → Decorator on FareStrategy
- "How do you handle driver timeout?" → Timer + fallback to next driver
- "How do you track driver location in real time?" → Separate LocationService, event-driven updates
- "How would you support ride pooling?" → Trip becomes 1-to-many riders
Companies That Ask This
Uber, Ola, Swiggy (for delivery matching), Rapido, Porter, and increasingly Amazon (for logistics) ask this problem. It's a standard LLD problem for SDE-2 and above roles at product companies.