← Back to Blog
System DesignMicroservicesDistributed SystemsArchitecture

SAGA Pattern — How I'd Design Uber's Booking Flow

SY
Sumit Yadav
March 07, 20265 min read

The Problem with Distributed Transactions

In a monolith, handling a complex business operation is straightforward. You wrap everything in a single database transaction — either everything succeeds or nothing does. ACID guarantees handle the rest.

But in a microservices architecture, a single business operation spans multiple services, each with its own database. There's no single transaction boundary. This is where distributed transactions become one of the hardest problems in system design.

Let's make this concrete with a real example: Uber's ride booking flow.

When a user books a ride, the system needs to:

  1. Create the booking record
  2. Assign an available driver
  3. Charge the user's payment method
  4. Send notifications to both rider and driver

What happens if the payment succeeds but driver assignment fails? You've charged the customer but can't fulfil the ride. These aren't edge cases — at Uber's scale, they happen constantly.

This is exactly the problem the SAGA pattern solves.


What is the SAGA Pattern?

The SAGA pattern breaks a distributed transaction into a sequence of smaller, local transactions. Each step:

  • Performs its own local transaction
  • Publishes an event or message to trigger the next step
  • Defines a compensating transaction that can undo its work if a later step fails

Think of it like a chain reaction. Each domino falls in sequence. If one fails, you run the chain in reverse.

There are two ways to coordinate a SAGA:

Choreography

Each service listens for events and reacts independently. No central coordinator.

Pros: Fully decoupled, no single point of failure

Cons: Hard to track overall state, complex to debug

Orchestration

A central orchestrator tells each service what to do and waits for responses.

Pros: Easy to track state, clear flow of control, simpler debugging

Cons: Orchestrator becomes a central dependency

My preference for Uber's use case: Orchestration. Payment correctness is non-negotiable, and having a clear audit trail of what happened and when is critical for disputes and debugging.


Designing Uber's Booking Flow with SAGA

The Happy Path

The Failure Path — Compensating Transactions

This is where SAGA really shines. If payment fails after driver assignment:

The key insight: each service must implement both a forward action and a compensating action.


Handling the Hard Parts

Race Condition: Two Users Request the Same Driver

NX means "only set if not exists" — this is atomic and thread-safe.

Fan-Out Notifications

Each worker scales independently. During a surge, push notification volume spikes — scale only that worker.


Complete Architecture


Two-Phase Commit vs SAGA

2PCSAGA
BlockingYes — locks resourcesNo — async, non-blocking
ScalabilityPoorExcellent
Failure handlingCoordinator failure = stuckCompensating transactions
LatencyHighLow

At Uber's scale — millions of rides per day — 2PC would be catastrophic. SAGA's async, event-driven nature is the only approach that scales.


Key Takeaways

1. Use SAGA orchestration when payment correctness matters. The audit trail is invaluable for disputes and debugging.

2. Every service needs a compensating transaction. If you can't undo a step, you need a different strategy.

3. Idempotency is non-negotiable. If the same event is processed twice, the outcome must be the same. Use idempotency keys on all payment operations.

4. Design for failure, not the happy path. The real system design work is in the failure scenarios.

5. Eventual consistency is often acceptable. Notifications don't need to be perfectly consistent. Payments do. Know the difference.


This is the kind of architectural thinking that distinguishes Staff Engineers from Senior Engineers. Anyone can design the happy path. Staff-level engineers design for the full failure space — and build systems that recover gracefully when things inevitably go wrong.

← More ArticlesConnect on LinkedIn →