In this article
Choose a seam with a visible business outcome
Imagine an older order-management application where changing the reporting screen requires redeploying the entire system. Replacing reporting can be a useful first seam if its reads can be separated from order writes. Replacing the central order transaction first may involve far more hidden dependencies. Pick the slice from evidence, not from which code looks least modern.
The Strangler Fig pattern describes gradually replacing capabilities around an existing system. Applied here, a routing layer directs reporting requests to the new implementation while existing ordering stays available. That layer is itself a dependency: give it monitoring and a fallback. A gradual migration only reduces exposure if each slice can actually be operated and assessed independently.
Start with failure and change evidence
Map incidents, release lead time, fragile modules, unsupported dependencies, manual workarounds and data-quality failures. “Old technology” alone is not a business case for replacement.
Identify what must remain stable: contracts, operational calendars, identifiers, reports, integrations and regulatory evidence. These constraints define the migration boundary more than the target stack.
Create seams around valuable change
Place a tested boundary around one capability that changes often or causes disproportionate risk. Stabilise inputs and outputs before changing internals; do not expose the legacy database as the new public API.
A strangler path can route selected use cases to a new component while the existing system remains authoritative elsewhere. Use explicit ownership and compatibility rather than an invisible permanent dual system.
Replace one useful boundary at a time
A migration should keep a verifiable return path.
Observe the existing system
Identify the change that is currently expensive or fragile.
Create a seam
Place a stable interface around the chosen capability.
Migrate and compare
Reconcile data and stop when acceptance criteria fail.
Migrate data with reconciliation and stop rules
Define canonical ownership during every phase, test representative migrations, reconcile counts and business totals, and preserve a rollback window. Avoid bidirectional writes unless their conflict policy is executable and monitored.
Each increment needs a measurable outcome and a stop condition. If it does not improve release safety, recovery, user flow or operating cost, do not continue extracting components for architectural appearance.
Preserve behaviour before changing it
Capture representative inputs and outputs from the old path, including awkward historical cases. Some surprising behaviour may be a business rule; some may be a bug people have learned to work around. Review differences with the process owner instead of assuming the new implementation is correct because its code is cleaner.
For read-only reporting, run both paths on the same snapshot and compare totals, dates and record inclusion. Treat mismatches as evidence to investigate. Do not shadow live write operations by sending them to both systems without a deliberate consistency design: that can duplicate side effects. First establish which system owns each record and how changes reach the other during the transition.
Move one capability at a time
Illustrative read-only reporting migration. Write migrations need a separate ownership and synchronisation design.
Capture baseline → implement seam → compare outputs
Differences understood and acceptance met?
Yes
- Route bounded traffic → observe
- Retire old path after the agreed review
No
- Keep existing route active
- Investigate differences → repeat comparison
A rollback must include the data written since cutover
Routing users back to the old interface is straightforward only if it can still understand the current data. Before cutover, decide whether writes remain compatible, whether a change log can replay them or whether the migration has a point beyond which forward repair is safer. State that boundary openly rather than describing every release as reversible.
After the agreed observation period, remove the obsolete path, scheduled jobs, credentials and monitoring rules. Otherwise the organisation pays to operate both systems indefinitely. Measure success against the original problem: a reporting change should now be independently deliverable, with consistent results and clear ownership. Modernisation is complete for that slice when the old dependency can be retired, not when the replacement screen first appears.
Sources & further reading
Documentation consulted on .
FAQ / DECISIONS
Frequently asked questions
When is a complete rewrite justified?+
Only when incremental seams cannot preserve mandatory behavior or the existing platform cannot be operated through the transition. The rewrite still needs migration, parity and rollback evidence.