There is a legacy system that has been running for more than a decade. Core business operations depend on it. Adding a single feature takes two months, the developers who built it left years ago, and nobody can promise what will break if a line of code is touched.
"Let's take this opportunity to rebuild it from scratch."
The quotes come back with a substantial number and a timeline stamped on them: two years. The problem is that for those two years the business still has to use the existing system, and new requirements keep pouring in the whole time. Most full-rebuild discussions end without a decision, and the system grows another year older.
Four Structural Reasons Full Rebuilds Fail
What makes a full rebuild difficult in practice is not a shortage of technical skill. It is the structural limits of the project itself.
- Nothing of value is produced until it is finished: A two-year project has zero usable output through month 23. If organizational priorities shift or the budget tightens in that window, the entire effort drifts.
- The requirements are buried in code, not documentation: Much of the exception handling and business logic accumulated over ten years was never written down. Miss it during the rebuild, and complaints arrive from operations the week after go-live asking why a function no longer works.
- The existing system does not pause: While the new system is being built, regulations change, partners change, revenue structures change. Every one of those changes has to be applied to both systems, and that duplicated effort continues for the length of the project.
- All risk concentrates at the moment of cutover: Because everything changes at once on go-live day, there is effectively no way to roll back if a serious failure occurs.
The Strangler Pattern: Migrating Safely, Piece by Piece
The alternative is to move functions one at a time rather than replacing the whole system at once. It resembles the way a climbing vine wraps an old tree and slowly hollows it out from within, which is where the name comes from.
- Put a routing layer in front: Place an API gateway layer between users and the existing system to relay requests. Initially it forwards 100% of traffic to the existing system, unchanged.
- Build one function on the new system: Implement customer lookup, for example, on the new side. Then switch only customer lookup requests at the routing layer, leaving everything else with the existing system.
- Roll back immediately if something goes wrong: If a defect appears in the migrated function, you revert the routing configuration alone. From the user's perspective, the stable prior state returns within minutes.
- Repeat the process: As functions move across, the existing system's share of the work shrinks. Eventually only an empty shell remains, and it can be shut down safely.
The essential property here is that every step is reversible, and every step secures working value immediately.
What to Move First: Setting Priorities
Design the order badly and you hit a bottleneck on the very first piece. Three criteria matter most.
- Start with high-change areas: Migrate the functions that receive modification requests every month, and the improvement in delivery speed is felt at once. Moving a function untouched for three years delivers little relative to its cost.
- Start with low-dependency areas: Independent functions loosely coupled to other modules — simple lookup features, for instance — come first. Areas where multiple data sets interlock, such as settlement or period-end closing, wait.
- Start with failure-prone areas: Rework the modules that cause incidents repeatedly, and the migration cost is recovered quickly through the incident response effort you no longer spend.
Tip. Functions already scheduled for retirement, or used only a handful of times a year, are far more economical left in the legacy system. Migrating everything should never become the objective.
Data Synchronization: A Single Governing Principle
During the transition there will inevitably be a period when both systems need to read the same data. One rule governs this, the hardest stage of the work.
"Decide explicitly which side is authoritative, and keep the data flowing in one direction."
Allowing both systems to modify the same data breaks consistency and leads to a state where nobody can determine which record is correct. For an area under migration, treat the new system as authoritative and set the existing system to read-only; for areas not yet migrated, reverse it. The boundary has to be unambiguous.
The Execution Roadmap
- Step 1 — Assess the current state and map dependencies: Visualize which functions reference which data and how components are coupled. This typically takes two to four weeks, and the diagram it produces serves as a reference point for the whole project.
- Step 2 — Define domain boundaries: Set the boundaries along which the system will be divided, aligned with business units and organizational structure.
- Step 3 — Migrate the first pilot piece: Move the selected function and verify that rollback works. The purpose of the first piece is validating the stability of the migration process itself, not producing a result.
- Step 4 — Iterate: Apply what the pilot taught you and migrate the remaining modules in sequence. From here it becomes predictable risk management.
Weighing Cost Against Risk
Incremental modernization is not always cheaper in absolute budget terms. Running two systems in parallel during the transition carries duplicated infrastructure cost and management effort, and building the routing layer is additional work.
The reason to choose it anyway is control over risk.
- Budget can be committed in stages rather than secured all at once.
- If the project stops midway, everything already migrated remains in use.
- The blast radius of a failure is reduced to a single piece rather than the whole system.
If you can firmly guarantee the full budget and two years of development time, and freeze new business requirements for that period, a full rebuild is faster. If either of those is uncertain, incremental modernization is the realistic alternative.
For the architectural perspective on connecting existing systems to newer services, deciding whether your company actually needs AX covers how to evaluate that before committing budget.
How Integrabbit Delivers Legacy Modernization
The most dangerous moment in a legacy modernization project is touching code while the dependencies between systems remain unclear. It leads directly to cascading failures nobody anticipated.
So we run current-state analysis and architecture assessment as an independent first phase. The dependency map and migration priority report produced there belong permanently to the client as a technical asset, and they remain a clear reference point for whichever team picks up the work later.
If you need help determining whether full replacement or incremental migration fits your system, a 30-minute technical consultation can help you map the current architecture and set priorities.