Ecorpin

Insights

Splitting a ledger monolith without a big-bang rewrite

Ledger and settlement systems often start as one database and one release train. Peak load, audit, and new products then collide. This is how we peel domains apart without freezing the business.

4 min readEcorpin Engineering
Share:

The usual bind

A ledger that posts, settles, and reports in one process is easy to start. It becomes hard when a new product needs a different posting rule, when audit wants an immutable trail, and when peak volume fights the same tables as overnight close.

A full rewrite sounds clean and rarely is. The business still has to move money while you cut over.

Split on money-movement boundaries

We look for seams the domain already has: posting versus settlement, products that do not share a balance, reports that can lag the book. Those become services or modules with explicit contracts, not a forest of shared tables.

Where an event log earns its keep — fan-out, replay, a trail operations can explain — we add one. We do not introduce a bus because it is fashionable.

ledger-cutover-strategy.ts
// Pattern: Domain-bounded ledger split with dual verification
interface LedgerCutoverPlan {
  readonly phases: ['dark-reads', 'shadowed-writes', 'reversible-cutover'];
  readonly sourceOfTruth: 'Immutable Event Log (Kafka / CDC)';
  readonly balanceVerification: 'Continuous double-entry invariant assertions';
  readonly rollbackWindow: '< 60 seconds without data loss';
}

Keep one source of truth for money

Caches, read models, and product APIs can be many. The record of what moved, and the balances that follow from it, stay singular. Dual-writing two books is how you lose money and trust.

Rollouts are staged: dark reads, shadowed writes, then a cutover you can reverse. Operations stay boring on purpose.

Have a similar architectural challenge?

Talk directly with a senior engineer about tradeoffs, cutovers, and sizing.