Every established business has one: the system nobody wants to touch. It schedules the crews, prices the orders, or holds twenty years of customer history, and it has been quietly running the company since before anyone can remember deciding it would. Replacing it feels like changing the engines in flight, so the replacement keeps not happening, and every year the fear gets a little more expensive.
Replacing systems like that is ordinary work for us. It sits underneath most of the modernization and rescue engagements we take on, and the method is always some version of the same pattern. The trouble with writing about it is that client systems come with confidentiality, and the stories go vague exactly where a skeptical reader wants receipts. This article walks through the one migration we can open all the way up, because the system is ours: the operations platform that runs our agency had a rented scheduling tool sitting at its center, and we replaced it while the platform kept running, invoices included. The before and after is easy to state: forecasts that used to trail the schedule by however long it had been since the last sync now move the moment the schedule moves. The pattern has a memorable name, and the story includes one mistake worth telling on ourselves.
What a strangler fig knows about replacing things
A strangler fig starts life high in the canopy of a host tree. It puts roots down along the trunk, reaches the soil, and over the years builds a structure that can stand entirely on its own. By the time the host tree dies, the fig no longer needs it, and what remains is a living column in the shape of the tree it grew around.
The software version of the idea carries the same logic, and its name comes from the software author Martin Fowler, who described legacy replacement in exactly these terms. Build the new system around the edges of the old one. Let it take over one responsibility at a time. Keep the old system in place, doing its job, until the new one demonstrably carries the load. Then, and only then, take the old one out. Microsoft maintains a formal write-up of the pattern in its architecture guidance on incremental migration, and the idea applies to anything load-bearing, from a scheduling module to a thirty-year-old ERP.
What makes the pattern valuable is not the botany. It is that every step is small, checkable, and reversible, which is precisely what an all-at-once rewrite is not.
The rented tool at the middle of our platform
The platform in this story handles time tracking, project budgets, invoicing, and the schedule of who works on what for a professional services firm: ours. When we launched it in late January 2026, scheduling came from a rented resource-planning product, integrated from day one. That was the right call at the time. The product was mature, our team already knew it, and building a scheduler before the platform around it existed would have been backwards.
For most companies, renting is where this story correctly ends. A rented tool is someone else’s roadmap, someone else’s uptime, and a small fraction of what building costs. Three things changed the math for us. Our financial forecasts could only ever be as fresh as the last sync, so the money math trailed the schedule. The schedule itself now lived in two places, and two sources of truth is a polite phrase for none. And the tool, quite reasonably, knew nothing about our particulars: which allocations were confirmed and which were tentative, which days our company takes as holidays, how a fixed budget draws down as hours land. None of that is a flaw in the product. It is the ordinary gap between a general tool and one business’s rules, and every integration pays a tax to bridge it. Ours had grown to roughly 18,000 lines of code, nearly all of it glue, syncing records and reconciling the differences.
Our first cutover was too fast
In mid-February we built our own scheduler inside the platform. Building it was quicker than you might expect; modern tooling has made construction the easy part of this kind of work. The important decision was invisible: the new scheduler answered questions in exactly the shape the old integration answered them, so the rest of the platform could not tell which one was speaking. That interchangeable seam is the piece of engineering the whole pattern depends on.
Then we broke our own rule. The new scheduler looked right, the numbers matched on the days we spot-checked, and that same week we deleted the entire integration in one stroke.
Nine days later we put it all back. Nothing had visibly failed. The problem was what we could no longer do: with the old system gone, there was nothing to check the new numbers against, and the numbers in question fed invoices. “Looks right” is not a standard you can bill against. We had not deleted a dependency so much as deleted our own evidence. So the rented tool came back, this time behind a switch that let us choose, at any moment, which system fed the platform’s financial forecasts.
The code had been ready. The proof had not. Recognizing that distinction, a little late, is the most useful thing this migration taught us.
Five weeks of running both
From late February to early April, both schedulers ran side by side. The switch decided which one the forecasts believed. Data flowed from the rented tool into the native one on a schedule, and we compared their answers as the weeks accumulated real holidays and real changes of plan. Any disagreement got investigated to its root rather than averaged away, because a disagreement meant a defect in the new system or a misunderstanding of the old one, and both are cheaper to find before a cutover than after.
After about five weeks the comparisons had nothing left to say. In early April we deleted the integration a second time, and this deletion was boring, which is the point. The platform has scheduled our team, priced our forecasts, and fed our invoices from its own scheduler ever since.
Scheduling migration
Late January to early April 2026
- Late January 2026: the platform launches with scheduling from a rented resource-planning tool.
- Mid-February: an owned scheduler is built beside it, and a premature cutover deletes the rented integration.
- Nine days later: the rented tool returns behind a switch so both systems can run.
- About five weeks of parallel running compared the two systems’ answers.
- Early April: the integration is deleted for good, and the owned scheduler runs alone from then on.
Deletion is what the whole exercise was for. It bought forecasts that move with the schedule, scheduling that knows our holidays and our budget rules, one less subscription, one less nightly sync to worry about, and roughly 18,000 fewer lines of code to maintain. We hold bigger changes to the same standard the parallel run set: when we later reworked how the platform computes invoice balances, we exported every affected figure before and after the change and required the difference to be zero before it shipped.
The playbook, in five overlapping moves
The moves below are how the pattern generalizes to any load-bearing system, and they are the shape this work takes when we run it for clients: a modernization that has to stay compatible with a system still in daily use, a vendor product the business has outgrown, a rescue where the old build cannot simply be switched off. When we rebuilt the Lead Small app, the replacement ran against the backend still serving the old app until the switch was safe. Different system, same seam. The moves overlap in practice; each one begins before the previous one fully ends.
Find the seam.
Identify the boundary where the old system meets the rest of the business: the questions it answers and the exact shape of its answers. If no clean seam exists, cutting one is the real first phase of the project.
Build beside, not instead.
The replacement grows next to the running system and answers through the same seam, so nothing downstream can tell the difference. The old system remains in charge the entire time.
Run both and compare to zero.
Feed both systems the same live reality and compare their answers on a schedule. The comparison is the deliverable; the migration is ready when the differences run out rather than when the calendar does.
Cut over with a way back.
Move real work to the new system behind a switch that can move it back without drama. The way back stays open until the new system has carried real load through enough of its calendar, including a month end and at least one holiday.
Delete on purpose.
Set a date, remove the old code, close the old account, and record what the work taught. Deletion is the finish line; a migration without it never actually ends.
Questions that tell you whether a team can do this
These work on any partner proposing to replace a system your business runs on, ours included, and they pair well with the broader vetting in our guide to choosing a custom software development partner. What matters is less the vocabulary of the answer than whether it contains logistics.
How will we know the new system gives the same answers as the old one?
The weak answer is “we’ll test it thoroughly.” Testing checks the new system against expectations; a parallel run checks it against reality. A strong answer names the mechanics: both systems running on live data, a recurring report of their differences, and an agreed target of zero before anything switches.
If the cutover goes wrong, what is the way back?
“It won’t, we’ve done this many times” is confidence, and confidence is not a plan. A real answer sounds like logistics: the switch that routes work back, the data still flowing to the old system in the meantime, and the agreed point after which the way back closes.
What gets turned off, and when?
Beware the migration that never ends. “We can leave the old system running for a while, just in case,” with no date attached, means paying for two systems and trusting neither. A strong answer ties the shutdown to evidence: the comparison report coming back empty, rather than a feeling of comfort.
What will you deliberately leave behind?
“Everything comes across” usually means nobody has looked. Old systems accumulate dead features, unused fields, and records nobody has opened in years, and migrating all of it faithfully preserves cost without value. A credible plan names what will not make the trip, and why.
When the all-at-once rewrite is the right call
The strangler fig is a discipline, not a law, and honesty about its limits belongs in any article recommending it. A small system with a small blast radius is often better replaced outright; if a failed cutover costs an afternoon, a parallel run costs more than the risk it removes. The same goes when the old system is leaving on someone else’s schedule, because the platform underneath it is being shut down, or when its data model is a dead end that no adapter can bridge. Running two systems is also not free: for a stretch you pay for both, operate both, and explain both to your team.
Our scheduler was small as systems go. It got the full treatment anyway because of what sat downstream: the numbers we bill from. That is the test worth applying to your own inventory. Not “how big is this system,” but “what breaks, and what does it cost, in the week after this system quietly starts lying.” Systems that fail that test deserve the pattern. Systems that pass it can take the short road.
And some replacements begin after an all-at-once attempt has already gone wrong, with the old system half-off and the new one half-trusted. Stabilizing that situation is its own discipline, and it is the starting point for a meaningful share of our software project rescue work.
Frequently asked questions
What is the strangler fig pattern in software?
The strangler fig pattern is a way to replace a software system gradually rather than all at once. A new system is built alongside the old one and takes over its responsibilities piece by piece while the old system keeps running. When the new system carries the full load, the old one is decommissioned. The name, coined by the software author Martin Fowler, comes from fig trees that grow around a host tree until they can stand entirely on their own.
Is it safer to rewrite legacy software from scratch or replace it gradually?
For a system a business depends on daily, gradual replacement is usually safer. The old system keeps working while the new one proves itself against live data, and every step can be checked and reversed. A from-scratch rewrite concentrates all of its risk into a single cutover. Full rewrites still make sense for small systems, for software at the true end of its life, or when running two systems in parallel would cost more than the risk justifies.
How do you replace business software without downtime?
Build the replacement behind the same interface the rest of your software already uses, then run old and new side by side. Data flows into both, their answers are compared on a schedule, and real work moves to the new system only behind a switch that can move it back. Most migration downtime comes from one-way cutovers; a compared, reversible migration removes the moment where everything has to go right at once.
How long does it take to replace a system this way?
It scales with the system’s size and how tangled it is with the rest of the operation. As one real reference point, replacing the scheduling tool inside our own operations platform took about seven weeks from the first line of replacement code to the final deletion, and about five of those weeks were the two systems running side by side. A larger system stretches the calendar, but the phases stay the same.
How do you prove a new system matches the old one?
By measurement rather than assertion. During the parallel run, both systems answer the same questions from the same data, and a comparison report lists every disagreement. Each difference is investigated until the report comes back empty, and only then does the cutover happen. The same standard extends beyond migrations: when we rework how our platform computes financial figures, we export every affected value before and after the change and require the difference to be zero.
When is a full rewrite better than an incremental migration?
When the blast radius is small: if a failed cutover costs an afternoon rather than a week of revenue, the ceremony of a parallel run can cost more than the risk it removes. A rewrite also wins when the old system is being switched off on someone else’s schedule, when its data model is a dead end no adapter can bridge, or when no seam exists and creating one would cost more than the rewrite itself.
Replace the system, keep the business
The decision in front of most owners is rarely whether the old system goes; age settles that on its own schedule. The real decision is whether the replacement arrives as one large bet or as a sequence of small, checked, reversible steps. That sequence is how we replace systems for clients, where the stakes are someone else’s payroll, and it is how we replaced our own, mistake included. If a load-bearing system in your business is coming due, our application modernization practice is the team that does this for a living, and the four questions above are a fair way to test us.



