top of page

Sagas

  • Writer: Pradeep P
    Pradeep P
  • 3 days ago
  • 3 min read

Layer 4 · Post 8 of 11

← Previous: Two-Phase Commit → Next: CQRS

Layer 4 — Data · Post 47 of 88

A saga breaks a long business flow into local transactions plus compensating actions, so you do not need one giant distributed commit.

What you'll learn

  • Choreography versus orchestration — who owns the next step

  • Why a compensation is not a database rollback, and must be idempotent

  • How payment and booking flows are sagas even when nobody uses the word

The idea in one minute

A saga is a sequence of local ACID transactions. Each step commits for real. If step 4 fails, you do not un-commit steps 1–3 with 2PC. You run compensating transactions that semantically undo them: refund the charge, release the seat, cancel the shipment.

Reserve inventory --> Charge card --> Confirm order | | | (release) (refund) (cancel) <----- compensations if a later step fails

Between steps the system is partially done. That is eventual consistency with a business-shaped repair kit. Users may see "payment pending." That is the point, not a bug you forgot.

Why it matters

2PC does not talk to Stripe, does not span week-long human approvals, and does not survive a coordinator reboot gracefully in most web stacks. Sagas are how you still say "this booking either completes or we make the customer whole."

Interviewers want you to name visible intermediate state, idempotency, and compensation that can itself fail (a refund queue, not a single HTTP call you ignore).

How it works

Two ways to drive the sequence:

  • Orchestration: one orchestrator (a workflow engine, a state machine in Postgres, Temporal, Step Functions) tells each service what to do, records the step, and on failure runs compensations in reverse. Easier to audit. The orchestrator is a thing you must run.

  • Choreography: each service emits an event (InventoryReserved); the next service reacts (PaymentService charges). No central boss. Harder to see the whole flow; easy to get loops and "who handles the timeout?"

Every step needs:

  1. A local transaction in that service's database.

  2. An idempotency key so retries do not double-charge.

  3. A compensation that is also idempotent (RefundPayment twice is still one refund).

  4. A timeout / deadline so "stuck pending" becomes "failed and compensated."

Compensations are business undos. You cannot un-send an email; you send an apology. You cannot un-see a GDPR delete; you design the step order so that is last.

A simple example

Hotel + flight package. Orchestrator: reserve hotel (PMS/API), reserve flight, charge Stripe, write BookingConfirmed. If the flight fails, compensate: cancel hotel hold, do not charge — or refund if you charged early.

Charge-last is a good default: fewer refunds. Sometimes you authorize (hold) then capture after both reservations succeed — Stripe's authorize/capture is a saga step.

Common mistakes

Compensation = DELETE. The card was charged; you need a refund object, not a row delete. Money has a ledger.

No idempotency. Kafka redelivers; the user double-clicks. You run Charge twice.

Choreography with no owner for "this timed out." A lost event is a silent stuck booking. Someone must watch state and expire it.

Giant orchestrator that calls 20 services synchronously in one request. That is a distributed monolith with extra latency. Persist state, run async.

How this shows up in real systems

  • Temporal, Cadence, AWS Step Functions, Azure Durable Functions: orchestrated sagas as code.

  • Stripe: PaymentIntents, webhooks, refunds — saga with a vendor.

  • Airline / hotel booking: GDS holds and cancels.

  • Kafka choreography: OrderCreated → inventory → payment topics; you still need a status table.

Recap

  • A saga is local commits + compensations, not one distributed ACID transaction.

  • Intermediate states are visible. Design them. Make every step idempotent.

  • Reads that span services will be messy. CQRS (next) is how teams often split "write the saga" from "show me my bookings."

Layer 4 · Post 8 of 11

← Previous: Two-Phase Commit → Next: CQRS

Comments


About Me

DSC_7604.jpg

Hi, I am a software engineer from Bangalore, India. Love spending time on gaming and photography. This website is where I will ocassionally throw what comes to my mind. Hope it is useful or at least entertaining to you. :)

 

  • Instagram
  • Facebook
  • Twitter
  • LinkedIn
  • YouTube
  • 500px

© 2023 by Going Places. Proudly created with Wix.com

bottom of page