← Home
💬Real-life Scenario-based Interview QuestionsInterview QuestionsNEW
Advanced
Experience levelSenior · 5+ YOESenior / staff depth expected

A rider books a cab while a network partition exists between two regions. How would you prevent duplicate bookings while maintaining good availability?

Multi-RegionCAPBookingIdempotency

How I frame it

Duplicate booking here means two active trips for one rider intent (or two drivers assigned for one request) after clients retry across regions. Pure CP (block until both regions agree) hurts availability. Pure AP (both regions assign freely) creates double dispatch. Design: high availability for accept, strong fencing for assign, and idempotent rider intent.

Core design

  1. Idempotency key per book attempt (client UUID). Retries — even to another region after heal — map to one booking_id.
  2. Sticky home region for the ride: Geo/DNS sends the rider to the nearest healthy region. That region becomes owner of the booking. During partition, the other region does not create a second open trip for the same key — either route fails closed to owner, or accepts only as forward-to-owner when link is up.
  3. If owner region is reachable: Create MATCHING locally — available. Driver pool for that metro is usually co-located, so partition across continents often does not block city matching.
  4. Driver assign = compare-and-set: UPDATE drivers SET status='ON_TRIP', trip_id=? WHERE id=? AND status='AVAILABLE' (or Redis Redlock + fencing token). Only one booking wins a given driver.
  5. Rider uniqueness: Partial unique index / constraint: UNIQUE(rider_id) WHERE status IN ('MATCHING','ASSIGNED','IN_TRIP'). Second concurrent book in same region fails fast — "you already have an active trip."
Cab book under partition — sticky region + conditional assign
Rider app ──────────────────────────────┐
                                        │
        Region US (reachable)           │         Region EU (partitioned)
        ┌─────────────────────┐         │         ┌─────────────────────┐
        │ Accept booking      │◄────────┘         │ (unreachable)       │
        │ booking_id = B1     │                   │                     │
        │ state = MATCHING    │                   │                     │
        │ Pin trip to US      │                   │                     │
        └─────────┬───────────┘                   └─────────────────────┘
                  │
                  ▼
        Assign driver with fencing / compare-and-set on driver_id
        On heal: replicate B1; reject second booking with same idempotency key

Partition edge cases

  • Rider retries hit the other region: Without shared state, a naïve AP design creates booking B2. Mitigation: regional accept only if rider sticky cookie / booking_home = this region; otherwise return 307 / error "retry primary" or queue until sync. Prefer slight unavailability of secondary over double trip.
  • Both regions think they own matching (split brain): Avoid multi-master writes on bookings. Use single-region primary per city (city affinity), not global active-active for trip state.
  • Heal: Replicate log; conflict on same idempotency_key → keep first created_at / lower fencing epoch; cancel loser; never leave two ASSIGNED drivers for one key.
  • Payment hold: Auth hold tied to booking_id, not to HTTP attempt — duplicate HTTP cannot double-auth if PSP idempotency key = booking_id.
Good availability:  book + match inside city region while cross-region link is down
Good safety:        one active trip per rider; one driver per trip; idempotent key
Trade-off:          secondary region may refuse new book for that rider until heal

Walkthrough

Rider in Mumbai; booking service primary for BOM is ap-south-1. Partition isolates eu-west. App still reaches ap-south-1 → booking B1 created, driver D9 assigned via CAS. Rider's flaky client also POSTs the same idempotency key to a global endpoint that lands on eu-west — EU cannot see B1, so it rejects or parks instead of assigning D12. After heal, EU sees B1 for that key and returns the same booking payload. Rider never gets two cabs.

Weak answer

"Use eventual consistency and merge bookings later." Sending two drivers to one pickup is unacceptable UX and cost. "Take a global lock across regions for every book." During partition that lock is unavailable — you sacrificed the availability the question asks you to keep.

Follow-up questions

Same rider, two devices, two regions simultaneously?

Active-trip uniqueness should be global when possible (central trip index), or accept rare conflict with quick cancel+notify on heal. City-primary + idempotency covers most retries; multi-device is the hard residue — product may allow only one active trip and cancel the newer on merge.

Driver app is in a different region than rider?

Matching runs where the trip geography lives, not where the phone's SIM roaming is. Drivers heartbeat to city region.

How is this different from seat booking?

Seats are inventory rows; cabs are moving supply with short-lived locks. Same CAS idea, plus geography-based ownership to survive cross-region partitions.

SLI during partition?

Track duplicate_active_trips (must be 0), book success rate in primary city region, and secondary reject rate due to partition.