Diagrammatic

Find a Rider for Uber or Uber Eats — System Design Interview Practice

Design a matching algorithm to efficiently connect riders/customers with drivers in real-time. Work through the requirements, architecture trade-offs, and an interactive design review.

Concepts and architecture decisions to consider

  • matchingConcept to explore
  • location servicesConcept to explore
  • real timeConcept to explore
  • optimizationConcept to explore
  • geospatialConcept to explore

Interview prompt

Design Design a matching algorithm to efficiently connect riders/customers with drivers in real-time. so users can Match riders with nearby drivers reliably at scale.

  • Define the source of truth for Match riders with nearby drivers; Optimize for wait time and distance and make retries idempotent.
  • Use bounded, partitioned state to meet Handle millions of matches per day and Match within seconds.
  • Separate the critical request path from Geospatial indexing for proximity, Matching algorithms (Hungarian, greedy), Priority queue for requests.
  • Explain consistency, failure recovery, authorization, observability, and a degraded mode.

Requirements and scale assumptions

  • Support the core workflow to Match riders with nearby drivers.
  • Expose status, results, and freshness appropriate to Design a matching algorithm to efficiently connect riders/customers with drivers in real-time..
  • Support authorization, validation, updates, deletion, and recovery semantics.
  • Meet Match within seconds under normal load.
  • Scale to Handle millions of matches per day without a single hot key or unbounded synchronous work.
  • Do not lose committed state; make retries and duplicate events safe.
  • Degrade safely when downstream workers, caches, or external dependencies fail.
  • Handle millions of matches per day
  • Partition by the primary tenant, user, item, or geographic key and isolate hot partitions.
  • Keep serving state bounded; retain raw events or durable records for replay and auditing.
  • Peak scale: Handle millions of matches per day — Capacity assumption that drives partitioning and backpressure.
  • Latency target: Match within seconds — User-facing budget for the primary request or read path.
  • Durable boundary: Committed before async — The source of truth is Match riders with nearby drivers; Optimize for wait time and distance.
  • Async boundary: At-least-once workers — Keep Geospatial indexing for proximity, Matching algorithms (Hungarian, greedy), Priority queue for requests off the synchronous path.

Key entities

  • InteractioninteractionId, actorId, objectId, type, version, occurredAt

    Canonical find a rider interaction with an idempotency key and ordering version.

  • ConnectionSessionsessionId, userId, deviceId, roomKey, lastHeartbeat, status

    Ephemeral but observable find a rider connection registration used for routing and presence.

  • FanoutCursorstreamKey, shard, offset, consumerGroup, updatedAt

    Durable progress marker for find a rider fan-out and replay.

  • DeliveryReceiptinteractionId, recipientId, channel, attempt, status, deliveredAt

    Deduplicated find a rider delivery state for reconnects, retries, or acknowledgements.

Data flow

  1. 1. Accept and commit the interactionThe find a rider gateway authenticates the actor, validates room or object membership, applies rate limits, and conditionally commits the interaction.
  2. 2. Publish an ordered eventAn outbox emits the committed find a rider transition with an event ID, partition key, sequence, and replay retention.
  3. 3. Fan out by partitionConsumers route find a rider events to connected recipients, durable inboxes, or notification channels without making the origin write wait for every recipient.
  4. 4. Resume and reconcile connectionsClients reconnect with a cursor; the find a rider service replays missed events, deduplicates delivery, and exposes stale or degraded state.
  5. 5. Measure latency and recoverOperations tracks find a rider publish-to-deliver latency, hot partitions, reconnect storms, dropped events, and consumer lag for replay or repair.

Deep dives and trade-offs

  • Ordering, idempotency, and hot keysChoose a find a rider partition key that preserves required order while distributing high-volume rooms, users, or objects. Use event IDs, inboxes, consumer offsets, and conditional state transitions for at-least-once delivery. Split or isolate hot partitions without changing the client-visible sequence contract.
  • Reconnect and replay semanticsIssue resumable find a rider cursors with an expiry and a clear snapshot-plus-delta fallback. Bound replay windows and rebuild from durable state when a cursor is too old. Expose version and freshness so a client can distinguish current, catching up, and degraded state.
  • Backpressure and presenceKeep connection heartbeats and ephemeral presence separate from durable find a rider interactions. Coalesce safe updates, shed low-value work, and protect critical events during reconnect storms. Measure end-to-end delivery, not only broker publish latency.
  • Direct fan-out versus pull-based readsUse push for latency-sensitive find a rider deltas and pull or replay for reconnect, history, and recovery. A push-only design loses state when clients disconnect and a pull-only design wastes latency and bandwidth.
  • Per-recipient queues versus shared streamsUse shared partitioned streams with per-recipient cursors where fan-out is large, and isolate exceptional high-fanout objects. A queue per recipient becomes expensive and hard to inspect at large scale.
  • Strong ordering versus availabilityGuarantee ordering only within the scope the product needs, such as a room, object, or conversation. Global ordering introduces a bottleneck and still does not solve duplicate delivery or reconnect recovery.
Diagrammatic — system design practice and architecture review.