← All insightsEngineering deep dive

Breaking Monolithic Data Stores: Implementing the Saga Pattern

Splitting the database is the moment the distributed transaction disappears. The saga is what you build in its place — and it is a business design, not just a technical one.

What you lose when the schema splits

In a monolith, a single database transaction spanning six tables gives atomicity for free. Split those tables across services and that guarantee evaporates. Two-phase commit is technically available and practically inadvisable at scale: it couples availability across services and introduces blocking behaviour precisely when the system is already under stress.

A saga replaces the atomic transaction with a sequence of local transactions, each of which publishes an event, and each of which has a defined compensating action. The system is never in a globally consistent state mid-flight; it is eventually consistent, and every intermediate state must be one the business can tolerate and explain to a customer.

Choreography versus orchestration

Choreographed sagas have each service react to events without a central coordinator. They are simple for short flows of two or three steps and become opaque beyond that, because no single artefact describes the whole process. Orchestrated sagas put an explicit coordinator in charge of sequencing and compensation. They introduce a component to operate, but they give you something invaluable: a readable, testable state machine that both engineers and business analysts can inspect.

For modernization work replacing long multi-table transactions, orchestration is usually the right default. The flows being replaced are typically five to twelve steps with real money or regulated obligations attached, and the ability to query 'which sagas are stuck and at which step' is operationally decisive.

Compensation is a product decision

The hardest part of saga design is not the plumbing. It is deciding what compensation means when a step cannot be undone. A payment can be refunded but not unmade; an email cannot be recalled; an inventory reservation may have expired. These are product questions, and they must be answered explicitly with the business rather than improvised in code.

Implementation discipline matters equally. Every step must be idempotent, because retries are certain. Use the transactional outbox pattern so state changes and event publication commit together. Give every saga a correlation identifier that flows through logs and traces. Persist saga state durably and expose it — the ability to inspect, resume, and manually complete a stuck saga is not an optional admin feature, it is the operational contract that makes the pattern safe to run.

Key takeaways

  • Prefer orchestration for long, regulated flows; choreography for short ones.
  • Define compensation with the business for every irreversible step.
  • Use the transactional outbox pattern to avoid lost or phantom events.
  • Persist and expose saga state so stuck instances can be resumed safely.

Modernizing a system you cannot take offline?

CodeWave Consulting scopes engagements within 72 hours of an assessment submission.

Start an assessment

Related articles