Legacy Modernization Without the Rewrite Trap
The big rewrite is the most reliably disappointing project in enterprise software. The strangler-fig pattern works, but only with the discipline that most descriptions of it leave out.
Every few years an organisation decides that the fifteen-year-old system at the centre of its business should be replaced. The reasoning is sound. The system is expensive to change, the people who understood it have left, the technology is genuinely obsolete. The plan that follows is usually a rewrite, and the rewrite usually disappoints.
The reason is structural rather than a failure of execution. A rewrite must reach feature parity with a system that has absorbed fifteen years of undocumented business logic before it can deliver any value at all. Meanwhile the old system cannot be frozen, because the business still needs changes. You end up funding two systems and shipping from the slower one.
The strangler fig, stated properly
The alternative is to route traffic through a layer you control, then move functionality behind it piece by piece until nothing is left of the original. The name comes from the fig that grows around a host tree and eventually stands on its own.
The pattern is widely cited and less widely executed, because the interesting part is not the routing layer. It is choosing the seams and actually removing the old code, which is the step teams skip.
Finding the seams
A good first slice has three properties: a clear boundary, low coupling to the rest of the system, and enough business value that finishing it is visibly worthwhile.
- Read-only views are the ideal starting point. Reporting, search, dashboards. No write path means no consistency problem, and you learn the routing and deployment machinery on low-risk traffic.
- Follow with a self-contained write path. Something that owns its data and does not participate in the monolith's transactions. Notifications, document generation, audit trails.
- Leave the transactional core until last. It is genuinely hard, and by the time you reach it you will understand the system far better than you do now.
Data is the hard part
Extracting behaviour is comparatively easy. Extracting data ownership is where migrations stall, because the legacy schema is usually the integration layer for a dozen consumers nobody has catalogued.
- Establish who owns each table before moving anything. Ownership means exactly one system writes it. Everything else reads through an interface.
- Dual-write only with reconciliation. If both systems must write during a transition, run a continuous comparison and alert on divergence. A dual-write without reconciliation is a silent corruption pipeline.
- Migrate reads before writes. Point consumers at the new interface while the old system still owns the data. When every reader has moved, flipping the writer is a small change instead of a coordinated event.
A migration you cannot roll back is not a migration. It is a launch, and it should be planned like one.
Delete the old code
This is the step that determines whether the effort compounds or merely accumulates. It is also the step that gets deferred indefinitely, because deleting working code feels risky and delivers no visible feature.
But a strangler migration that never deletes leaves you operating both systems permanently: the worst of both worlds, with double the surface area and an ambiguous source of truth. Make removal an explicit, scheduled part of each slice, not a clean-up task at the end. A slice is not done when the new path serves traffic; it is done when the old path is gone.
Instrument the old code paths so you can prove they are unused before removing them. Log every entry point, wait a full business cycle (a month, a quarter, whatever covers your seasonal patterns) and delete what has not been called. Evidence turns a scary decision into a routine one.
Done this way, modernization stops being a project with a completion date and becomes a capability the team retains. That is the actual goal. A system that can be changed safely is worth more than a system that is merely new, and newness is a depreciating asset.