Every modernisation talk includes the same slide: a fig tree slowly wrapping itself around an old one until the old tree is gone. It’s a good picture. It also hides most of the work.
We’ve replaced eleven large systems this way since 2019, including a bank’s payments core and a carrier’s routing engine. Here’s what we wish someone had told us the first time.
The hard part is the seam, not the new code
Building a new service is the easy bit. The hard bit is the seam: the place where traffic can be sent to the old system, the new one or both. If the old system has no clean way in, you build one first, and that often takes longer than the first slice itself.
- Put a routing layer in front of the old system before you replace anything.
- Make the routing decision per customer, depot or account, not all or nothing.
- Log every decision, so you can explain where any transaction went.
Run both, and compare everything
Shadow mode is where the confidence comes from. The new service processes a copy of live traffic, and a reconciliation job compares its results with the old system’s. At Ruwaq Bank we didn’t switch any flow across until it had matched for 30 days in a row.
The comparison job is the most important code you’ll write, and it’s the first thing teams cut when they’re short of time.
Pick the first slice for learning, not glory
The first slice should be valuable, but mostly it should teach you how the seam, the deployment and the comparison work. High volume, well understood and easy to reverse beats the most painful part of the system every time.
Decide what ‘done’ means early
The last ten per cent of an old system is often batch jobs, reports and odd integrations nobody remembers. Agree up front what happens to each of them, including switching some off, or the old system lives on for years in a corner.
If you’re weighing up a rewrite, we’re happy to talk it through. A two-week architecture review usually settles the question.