The legacy system runs payroll, orders, or patient records right now, today, while you are trying to replace it. That single fact kills most replacement projects before they start. Teams scope the new build as if the old one will politely wait, then discover eighteen months in that the business cannot stop taking orders for a six-week cutover weekend.
The instinct is to build the whole new system first and flip a switch. That plan fails for a predictable reason: the switch never comes. Every week of delay adds new requirements discovered in the old system, and the two platforms drift further apart. We have migrated over a hundred tenant databases off a platform we then decommissioned, and the projects that worked were the ones that never staked the business on one big day.
This is a decision problem before it is an engineering problem. What order do you replace things in, what runs in parallel and for how long, and who is accountable when the two systems disagree about a number. Get those three answers wrong and the rewrite either stalls forever or breaks something customers were relying on.
The Trap of the Big-Bang Rewrite
A big-bang rewrite asks the business to accept zero improvements for the entire build, then a single high-stakes cutover at the end. Both halves of that deal are bad. Zero improvement for a year erodes sponsor confidence and budget. The single cutover concentrates every risk, every bug, and every trained-employee habit change into one weekend, with the old system as the only fallback if it goes wrong, and the old system is usually the thing you were trying to escape.
The tell that a project is heading toward big-bang is a plan with one go-live date and no intermediate milestones that ship to real users. If nothing customer-facing changes for six months, the project has stopped being agile and started being a bet.
Strangle the Legacy System Instead of Replacing It
The alternative is the strangler pattern: put a routing layer in front of the legacy system, then move traffic to the new system one slice at a time, by feature, by tenant, or by workflow, while the legacy system keeps handling everything not yet migrated. The legacy system dies gradually, starved of traffic, instead of being killed in one motion.
Slicing by tenant works well for multi-tenant SaaS, because each tenant's data and workflow moves as a unit and you get a clean before/after boundary per customer. Slicing by feature works better for a single large application, because you can move read-only reporting first and defer the risky write paths. Pick the axis that matches how your data is actually partitioned, not the one that looks cleanest on a slide.
A routing rule you can act on today
Order the slices by blast radius, not by engineering convenience. Rank every candidate slice on two axes: revenue impact if it breaks, and staleness risk if it is delayed. Migrate low-impact, low-risk slices first to prove the pipeline, then work up to the slice that actually matters.
-- one row per candidate slice, decide cutover order from the query, not a meeting
SELECT slice_name,
revenue_impact_if_broken,
staleness_risk_if_delayed,
revenue_impact_if_broken + staleness_risk_if_delayed AS priority_score
FROM migration_slices
ORDER BY priority_score ASC; -- migrate the lowest-score rows first
This is the same discipline we use scoping any MVP that ships in weeks: small, ordered, verifiable slices beat one large deliverable every time, and a legacy replacement is really an MVP with a hostile incumbent already in production.
A Cutover Checklist That Actually Protects Revenue
Every slice cutover, no matter how small, should pass the same gate before traffic moves. Skipping the gate because a slice looks trivial is exactly how a trivial slice takes down billing.
- Dual-write or dual-read the slice for a defined window before cutting traffic, not after.
- Produce a per-tenant or per-record reconciliation report comparing old and new output for that window.
- Set a numeric tolerance for acceptable discrepancy before you look at the report, not after you see it.
- Name one person who signs off on the reconciliation report before traffic moves, and hold them to it.
- Keep the legacy path live and reachable for a fixed rollback window after cutover, with a single switch to revert.
The reconciliation report is the part teams skip under deadline pressure, and it is the part that actually protects the business. When we moved tenant databases off a decommissioned platform, the report ran per tenant and gated every cutover; no report, no cutover, regardless of schedule.
The Parallel-Run Problem Nobody Budgets For
Running two systems side by side sounds simple until you ask which one is the source of truth for the period both are live. If both accept writes, you need a reconciliation job comparing them continuously, not just at cutover, because drift compounds silently. If only one accepts writes and the other mirrors, you need a clear replay mechanism for the mirror to catch up after any outage.
This is not free engineering. Dual-write logic, reconciliation jobs, and rollback switches are real code that gets deleted once the migration finishes, and estimates that leave this out are the same estimates we flag in signs your MVP quote is too low. Budget for throwaway code; it is cheaper than the incident it prevents.
A reconciliation report that gates the cutover is worth more than a rollback plan you hope you never use.
The honest tradeoff: parallel-run periods slow the migration down. If the legacy system is actively failing, security-exposed, or contractually forced to shut off by a vendor date, you may not have the calendar room to strangle it slice by slice, and a faster, riskier cutover with a hard freeze window is the more defensible choice. That is the exception, not the default plan.
Who Should Build This, and What to Put in the Contract
A legacy replacement is a different hiring problem than a greenfield build. You need people who have shipped the boring parts, routing layers, reconciliation jobs, rollback switches, not just people who can build the new feature set fast. Ask any studio you are evaluating for a specific story about a cutover that went wrong and what caught it; if the answer is vague, keep looking. Our own approach to this kind of work leans on the same reconciliation discipline described above, because we have run it against real tenant data, not a whiteboard.
Whatever you decide, the contract needs specific language before a line of migration code gets written. Require a defined rollback window with a stated maximum duration, require the reconciliation report as a contractual deliverable per slice rather than a verbal assurance, and require a named sign-off owner distinct from the engineer doing the migration. Our guide on what to require in a development contract covers the general version of this; a legacy cutover just makes every one of those clauses load-bearing instead of theoretical. If you are still narrowing down who to hire for this, the criteria in how to choose a development studio apply directly, weighted heavily toward migration experience over portfolio polish.
None of this requires stopping the business for a weekend. It requires accepting that the migration takes longer than the demo version of the plan, and that the extra time buys a rollback path you will be glad exists the one time a slice does not reconcile.
Frequently asked
How long does replacing a legacy system usually take?
It depends entirely on how many slices you need and how wide the parallel-run windows are, but plan in slices, not a single end date. A platform with a dozen major workflows and real reconciliation gating typically runs months, not weeks, if done without a shutdown.
Can we replace a legacy system without any downtime at all?
Yes, using a strangler pattern with a routing layer in front of the legacy system, moving traffic slice by slice with reconciliation gating each move. Full zero-downtime is achievable for most business software; it costs more engineering time upfront for dual-write and rollback code.
What is the biggest mistake teams make replacing legacy software?
Committing to one large cutover date instead of ordered slices. It concentrates every risk into a single event and leaves the legacy system, which you were trying to escape, as the only fallback if that event goes wrong.
Should we build the replacement in-house or hire a studio?
Weigh it the way you would any build-versus-buy decision on team capacity: in-house teams know the legacy quirks but often lack cutover experience; a studio brings that experience but needs ramp-up time on your data. Whichever you choose, require reconciliation reports as contractual deliverables.
How do we know the new system is actually correct before we fully cut over?
Run a reconciliation report comparing old and new output for every migrated slice, with a numeric tolerance agreed before you look at results, and get sign-off from a named owner. If the report does not run, the slice does not cut over, regardless of the schedule.