Skip to content
Latticework
Esc
Try
No. 114From the Masters

Starbucks Does Not Use Two-Phase Commit

Real businesses scale through asynchronous, compensating processes, not distributed transactions.

“…a two-phase-commit can make life a lot simpler but it can also hurt the free flow of messages (and therefore the scalability)…”

Hand work on asynchronously, correlate it by name, and fix the rare failure with a compensation instead of locking everything.

To an executive

Businesses that serve many customers do not freeze everything while one step completes. They accept rare errors and fix them afterwards, which keeps service fast and customers moving.

To an engineer

Prefer asynchronous steps linked by a correlation identifier over distributed transactions. Handle failures by write-off, retry with idempotent receivers, or a compensating action.

The idea

Hohpe noticed that Starbucks takes your order and payment, then passes the drink order to baristas asynchronously, on a queue of marked cups. Drinks are made in parallel, often out of sequence, and matched to customers by a correlation identifier: the name on the cup. If something goes wrong, they remake the drink or refund you.

The business is optimising for throughput. A two-phase commit would mean the cashier and customer waiting at the counter until the drink was finished, which would sharply cut the number of customers served. Instead, the shop accepts the occasional failure and handles it with one of three strategies:

  • Write-off: accept or discard the error when fixing it would cost more than the loss.
  • Retry: try again when success is likely, which is safe if the receiver is idempotent.
  • Compensating action: undo completed steps, such as refunding the payment.

Why it works

Locks kill throughput. Holding resources across slow, independent steps means everyone waits for the slowest one. Asynchronous hand-offs let each step run at its own pace.

Failures are rare and cheap to fix. When the cost of an occasional error is small, handling it after the fact is cheaper than preventing it with coordination on every order.

The business already knows the answer. Most organisations have long-standing ways of handling mistakes, such as refunds, adjustments and reconciliation. Those point to designs simpler than distributed transactions.

Where it applies

  • Cross-service workflows such as order, payment and fulfilment.
  • Migrations away from shared databases, where a single transaction can no longer span the data.
  • Integrations with external partners, which will never join your transaction.
  • High-volume processes where throughput matters more than instant consistency.

How to apply

  1. Ask the business how it handles each failure today, and use that as the starting design.
  2. Split the process into a short synchronous exchange and longer asynchronous steps.
  3. Correlate messages with an identifier that travels through every step.
  4. Choose a strategy per step: write-off, retry with idempotent receivers, or an explicit compensation.
  5. Model the whole flow as a saga, with its states and compensations visible and monitored.

Example scenario

An order platform used distributed XA transactions across inventory, payment and shipping databases. Under peak load, lock contention caused timeouts, and failed orders left customers unsure whether they had been charged.

The team asked operations how they handled problems by hand, and found refunds and stock adjustments were already routine. They replaced the transaction with a saga that reserved stock, charged the card and booked shipping in turn, compensating on failure. Throughput rose sharply, and failures became visible, recoverable states instead of timeouts.

Questions to ask

  • How does the business handle this failure in the real world today?
  • If this step fails, do we write it off, retry it or compensate, and who decides?
  • Do we really need atomicity here, or only eventual correctness?

When not to use it

  • Operations within a single database, where a local transaction is simple and correct.
  • Cases where inconsistency, even briefly, is unacceptable, such as some ledger postings, which need stronger guarantees.

How it misleads you

Relying on compensation for actions that cannot be undone, such as sending a notification or shipping goods. Those steps need a reservation or confirmation pattern first. Sagas also move complexity rather than remove it: you now have to design, test and monitor every failure path explicitly.

Further reading

Last reviewed · Suggest an improvement