The vendor is gone, the framework is out of support, and the system still runs the business.
Replacing a system that cannot be switched off, in slices, with old and new running together until the new path has earned the traffic. No big-bang cutover, no two-year rewrite, no freeze. The first slice is chosen for how easily it can be reversed, not for how small it is, and the undocumented behaviour is treated as a requirement until somebody proves it is not.
- Companies delivered for
- 20+
- Median to first production-grade artefact
- 6 weeks
- Software a real user can open
- By week 3
- Team on a build
- Pod of three
- Published case study for this pillar
- None yet
Signs you are past the point of another patch
Nobody books a call about modernisation. They book a call about a change that should have taken a day and is now in its third week.
The vendor is gone, or the framework is out of support
Nobody ships security patches for it any more. The upgrade path closed some time ago, and every audit question about it gets answered with a paragraph explaining why it is fine for now.
Every small change takes weeks, and most of that is testing
There is no test suite worth the name, so the only way to know a change is safe is to have several people click through the system by hand. The estimate is not the coding. The estimate is the fear.
A rewrite was attempted before and abandoned
There is a repository somewhere with months of work in it and nobody's name on it now. Why it stopped is more useful to us than the code, and it is usually the same reason: the old system kept changing while the new one was being written.
The system works, which is exactly why nobody will sign off touching it
It has run the business for years. The risk of leaving it is spread over the next few years and the risk of touching it lands on one person this quarter, so nothing happens. That asymmetry is the real problem to solve.
Onboarding a new engineer takes a quarter
There is no document that explains it, because the explanation is in the code and in the heads of the people who wrote it. Every new joiner learns the system by breaking part of it.
One person is the only one who understands it
Everybody knows who it is. Leave requests get quietly checked against release dates. Nobody has said out loud that this is a risk, because saying it out loud makes it somebody's job to fix.
Why the full rewrite is the version that gets cancelled
The rewrite does not fail because the team was weak. It fails because of a problem in the shape of the plan, and it is the same problem every time.
They live in the old code, not in a document
The specification for the system you are replacing is the system you are replacing. Years of decisions, exceptions and corrections are sitting in it, and most of them were never written down anywhere else.
And in two or three people's heads
The rest of the requirement is held by the people who have been there long enough to know why a rule exists. They can answer any specific question you ask. They cannot produce the list, because nobody can list what they have stopped noticing.
Both keep changing while you rewrite
The business does not pause for the rewrite. Regulation changes, a product launches, a large customer gets a special arrangement. Every one of those goes into the old system, because that is the one taking traffic, so the gap widens for the entire life of the project.
Everything depends on one weekend
A big-bang cutover has no partial success. If it fails, the only move is to roll all of it back. The cost of that failure is what makes people push the date, and pushing the date widens the gap, which makes the next date harder than the one before it.
Nothing is proved until the very end
You find out whether the new system is right in the last month of a project that has already spent its budget. Slicing exists to move that discovery to the third week, while being wrong is still cheap.
What each symptom says about where the work actually is
Modernisation is not one job. The complaint that gets you onto the call tells us which part of it has to come first.
- The vendor is gone, the framework is unsupportedA boundary in front of the old system
- Every change takes weeks, most of it testingTests that pin current behaviour
- A rewrite was tried and abandonedSlice order and sequencing
- Nobody will sign off touching itParallel run and reconciliation
- Onboarding takes a quarterA written inventory of behaviour
- One person understands the whole thingA written inventory of behaviour
Replacing a live system in slices, in the order we do it
The old system keeps taking traffic throughout. Nothing here needs a freeze, and you can stop after any step without leaving the operation worse than it was.
- 01
Draw the boundary before writing any replacement
An interface goes in front of the parts we intend to replace, and every caller goes through it. Nothing is rewritten yet. At the end of this step the old implementation is still doing all of the work, and it has become possible for something else to do some of it.
- 02
Write down what the system currently does, including the parts that are wrong
Behaviour is captured as it is, not as the documentation says it should be. Where the current behaviour is a defect that somebody downstream now depends on, that gets recorded as a decision to be made in the open rather than fixed quietly in passing.
- 03
Pin the behaviour with tests before changing anything
Tests are written against the old system to record what it returns today, so the replacement has something to be measured against. They are not tests of correctness. They are tests of sameness, and they are what makes every later step reversible.
- 04
Choose the first slice for reversibility, not for size
The first slice is one you can switch back off in a minute, that carries real transactions rather than a report, and whose blast radius is understood before it runs. Small and safe are different properties, and they get confused constantly.
- 05
Run both paths on the same traffic and compare the outputs
The new slice processes the same input as the old one while the old one stays the answer of record. Differences are logged and worked through one at a time. Most of them turn out to be the undocumented behaviour nobody could name in an interview.
- 06
Switch the slice over on evidence, then delete the old path
Switching is a configuration change with a way back, not a weekend and a war room. Once it has held, the old code path is removed rather than left dormant behind a flag. Dormant paths come back on at the worst possible moment, and they come back on with stale logic.
- 07
Repeat until the last release is the smallest one
The old system shrinks slice by slice until what remains is a shell nobody routes to. By then the operation has been running on the new system for months, and the final switch-off is an administrative task rather than an event.
Which slice goes first, and which one waits
The instinct is to start with the easiest thing. The right first slice is the one that teaches you the most and can be reversed the fastest, and those are rarely the same slice.
- Goes first
Reversible, real, and watched
A process that carries actual transactions, has a clear input and output we can compare, and can be routed back to the old path with a configuration change. It should be visible enough that people notice if it is wrong. Being noticed is the point of going first.
- Goes second
Everything the first slice taught us how to do
Once the boundary, the parallel run and the reconciliation exist, later slices reuse all three. This is where the pace picks up, because the second slice does not have to build any of that a second time.
- Goes last
Batch, month end, and anything with a regulator attached
Work that runs once a month gives you one chance to observe it per month, which makes it the worst possible thing to learn on. It moves after the pattern is proved and after the reconciliation has been trusted for several cycles.
What a slice has to prove before the old path is switched off
Switching a slice off is a decision with evidence behind it, and the evidence is agreed before the slice is built rather than assembled afterwards to justify a date somebody already announced.
The two paths agree on the same traffic, and the differences are explained
Not a sample. The full set of differences from the parallel run, each one either fixed or written down as a deliberate change with a name against it.
Money reconciles to the system of record
Balances, postings and totals tie back to the finance system itself, not to a convenient intermediate extract that both paths happen to read from.
The failure behaviour matches, not just the success behaviour
What the old system does with a bad input, a timeout or a duplicate submission is part of the specification. Most parallel runs compare the happy path and then discover the rest of it in production.
There is a way back that somebody has actually used
The rollback is exercised on purpose before the switch, not written down and hoped for. A rollback nobody has ever run is a plan, not a control.
The people who use it every day have run real work through it
The operators who will find the problem first get the new path before the switch. Their objections are the cheapest information available on the whole project, and they arrive unprompted.
Someone has agreed to own it after we leave
A named owner for the slice, with the runbook and the alerts pointing at them. A slice with no owner becomes the system nobody will touch again, only newer.
The undocumented behaviour, and what happens to each kind of it
Every parallel run surfaces behaviour nobody could describe in an interview. The work is not finding it. The work is deciding, out loud and with a name attached, which category each one belongs in.
- Rounds part-units down, alwaysLoad-bearing rule, carried across
- Retries a failed payment exactly onceLoad-bearing rule, carried across
- Accepts an order with no delivery dateDefect the business now depends on, decided in the open
- Back-dates a correction into the original periodDefect the business now depends on, decided in the open
- Silently truncates a field longer than the columnDefect, fixed, affected records listed
- Ignores the credit limit for two account typesNobody has relied on it in years, removed
The person who is the only one who understands the old system
The single point of knowledge is a familiar shape of problem, and it is usually handled badly by everyone involved, including the person themselves.
They are not the obstacle
It is tempting to treat the one person who knows the system as a risk to be routed around. They are not. They are the most valuable input the project has, and they have usually been asking for this work for years while being told it was not a priority.
The reason they cannot hand the knowledge over is not that they will not. It is that nobody can list what they have stopped noticing. Ask them for a document and you get the parts they find interesting. Show them a difference from a parallel run and you get the rule, in one sentence, immediately.
So the parallel run is also the interview
Every difference between the old path and the new one is a specific question with a specific answer, and it costs them a minute rather than a week. That is why the behaviour inventory gets built from running traffic instead of from a workshop. Workshops produce the behaviour people remember. Traffic produces the behaviour that exists.
What good looks like at the end
They stop being the only person who can answer, and they do not stop being the person who knows most. The tests carry the behaviour, the inventory carries the decisions, and they get their time back for the parts of the system that are genuinely hard. Nobody checks their leave against the release calendar any more.
What the first six weeks look like on a modernisation
Three phases, the same as every other engagement here. What differs is that week three has to produce a slice running against real traffic, not a screen somebody clicks through.
- Week 1
The audit, fixed fee
Two calls, and one real transaction followed end to end through the system you want to replace. We come back with where we would draw the boundary, which slice we would take first, and what we expect to go wrong. You get a one-pager and you keep it whether or not we go further.
- Week 2
The boundary goes in
A pod of three puts the interface in front of the part being replaced and gets the parallel-run harness working. Nothing is replaced yet. The old system is still answering every call, and it will keep answering them for weeks.
- Week 3
The first slice runs alongside
The new path processes real traffic in parallel while the old one remains the answer of record. This is the week the wrong assumptions surface, which is exactly why it is not week eight. Software a real user can open exists by week 3.
- Weeks 4 to 6
The differences close and the slice takes over
The list of differences shrinks, each one either fixed or recorded as a deliberate change. When the exit criteria are met the traffic switches, with a rollback that has already been exercised. Six weeks is our median time to a first production-grade artefact.
- Week 7 onwards
The next slices, and the operating arrangement
Quarterly reviews and on-call governance. Later slices reuse the boundary, the harness and the reconciliation, so they cost less than the first one did. You can stop at any point, and stopping leaves you with a smaller old system rather than a half-finished new one.
Why this attempt moves faster than the one that was abandoned
Two things changed. Some of this is scaffolding we have already run in production, and the reading that used to eat the opening months is now a first pass a person reviews.
- Already built
The harness, not just the patterns
Boundary adapters, parallel-run comparison, difference logging and reconciliation runners that have already run in production elsewhere. On an abandoned rewrite this is usually the first thing started and the first thing cut when the schedule slips.
- AI first pass
Reading the code nobody wants to open
Claude reads the legacy modules, the stored procedures and the exception handling, then drafts the inventory of what the system actually does and flags what it could not explain. The flags are where we start asking questions, and they are usually the interesting part.
- AI first pass
Drafting the tests that pin current behaviour
Tests recording today's behaviour are drafted from the code and from real inputs, so the thing that makes the work reversible exists before the replacement does, rather than after the budget has gone.
- Human call
Rule or defect, carry or fix, now or later
Which undocumented behaviour is load-bearing, what the first slice is, what the exit criteria are, and when to accept a difference rather than chase it. Those decisions are what the project is actually made of, and they stay with the engineer whose name is on the work.
- What you keep
Yours to run without us
The boundary, the harness, the inventory, the tests and the prompts, in your repositories, documented. If we build something only we can operate, we have replaced one system nobody will touch with a newer system nobody will touch.
What we have actually delivered
We have not published a named modernisation case yet, so these are firm-wide delivery figures. We will say on the call which of them came from work shaped like yours.
What this page does not cover, and what we have not published
Two things worth saying plainly before you book anything, because both of them would otherwise come out on the second call.
Building the system your team works in all day
If what you need is a system that does not exist yet, an internal tool, a field application, or integration between two systems that each hold part of the truth, that is the applications and automation practice. This page is specifically about replacing one that already runs the business and cannot be switched off.
Applications and automation →Firm-level figures, not a modernisation result
Woodfrog has delivered 50+ projects for 20+ companies since 2023, with a median of six weeks to a first production-grade artefact. Those are firm-wide numbers and we are not going to dress them up as the outcome of a legacy replacement.
Move a number across from another discipline
The cases we have published sit in analytics, data engineering and AI evaluation. A margin recovery figure from a grocery engagement tells you nothing about whether we can take your order system apart safely, so it is not on this page.
Read the case studies →Four questions with no rehearsed answer
Where would you draw the boundary in our system. Which slice would you take first, and why that one. What would the exit criteria be before it takes traffic. What would you refuse to carry across. The one-pager at the end of week one is where those answers have to hold up.
Questions engineering and operations leaders ask us
The ones that come up on almost every first call about a system nobody wants to touch.
We tried a rewrite before and it was cancelled. Why would this be different?
That is the normal outcome of a rewrite with a single cutover date, and the reason is structural rather than a failure of the team. The requirements live in the old code and in a few people's heads, and both keep changing while the rewrite is under way, so the gap widens for the whole duration. Here the old system keeps taking traffic, one slice moves at a time, and nothing depends on a single date.
Can you really do this without a freeze or a weekend cutover?
Yes, because the old path stays live while the new one runs beside it on the same traffic. The switch for each slice is a configuration change with a rollback that has already been exercised. Freezes and war rooms are what you need when there is no reconciliation, so nobody is willing to commit to the switch without stopping the world first.
How long does the whole thing take, not just the first slice?
Longer than a rewrite plan says on paper and shorter than a rewrite actually takes. The part we scope up front is the first slice: the audit in week one, the boundary in week two, the new path running alongside by week three. Six weeks is our median across engagements to a first production-grade artefact, which is a median rather than a promise about your first slice. After that it depends on how many slices there are, and each one costs less than the last because the harness already exists.
The old system has no tests at all. Does that stop this?
No, it is the usual starting position. We write tests against the current behaviour before changing anything, recording what the system returns today rather than what it ought to return. They are not a judgement about whether the behaviour is correct. They exist so that any difference between old and new is visible immediately, which is what makes each step reversible.
One of our engineers is the only person who understands it. How do you handle that?
With them, not around them. They are the most valuable input the project has, and usually the person who has been asking for this work for years. We do not ask them to write the system down, because nobody can list what they have stopped noticing. We show them differences from the parallel run and they explain each one in a sentence.
Is AI rewriting our system, then?
No. AI does first passes and we review every one. Reading a legacy module and drafting an inventory of what it does is transcription, and it is where the opening weeks used to go. Deciding which undocumented behaviour is a rule and which is a defect the business now depends on is not transcription, and that decision stays with the engineer whose name is on the work.
We only care about two parts of it. Do we have to replace the whole thing?
Then replace two parts. Nothing about this method requires finishing. Each slice is independently useful, and stopping after the second one leaves you with a smaller old system, a boundary in front of it, and tests that did not exist before. A rewrite has to be finished before it is worth anything, which is exactly why it is the riskier plan.
The system works. Why spend money on this now?
That is the right question, and sometimes the answer is not now. What we would ask back is how long a small change currently takes, whether anyone will still patch the framework next year, and how many people could restore the system if it fell over on a Sunday. If those answers are comfortable, leave it alone. If they are not, the cost of leaving it grows quietly while the cost of touching it stays visible, and that is why nothing has happened yet.
Who owns the new code, and can our own team maintain it?
You own it from the first commit, in your repositories, on a stack you can hire for. The boundary, the harness, the inventory and the tests are handed over with documentation and an on-call runbook. Week seven onwards is quarterly reviews and on-call governance because you want it, not because you are stuck with us.
What happens if we stop halfway?
You keep what has moved. The slices that switched over are running in the new system, the old one is smaller, and the boundary and the tests stay in your repositories either way. The week one one-pager is yours whatever happens next, including when it says the honest answer is to leave the system alone and spend the money somewhere else.
The rest of the practice
These are genuinely different jobs with different ways of failing. Most engagements start in one of them.
- Data engineeringJobs that finish, migrations that reconcile, and storage that stops paying for cold data.
- Data integration and governanceOne set of records the finance team and the operations team both accept.
- Data platforms and modernisationOff the platform you outgrew, without a twelve-month freeze on new reporting.
- Apache SupersetSuperset built and run by people who commit to the project, including embedding and Kubernetes.
- Command centresThe one screen an operations floor runs the day from, not another dashboard.
- AI evaluationA graded eval set, because an AI system cannot simply pass or fail a test suite.
- AI governanceGovernance you can defend in a board meeting and audit on demand.
- AI agentsOne reasoning agent on Claude, on your live data, with evidence and a kill switch.
- Data agentsAgents that watch the data, flag what moved, and explain what is driving it.
- AI use case, guaranteedOne production agent in eight weeks, or you do not pay for the build.
- Applications and automationThe system your team works in all day, built or replaced in slices.
- System integrationSystems that stop disagreeing about the same customer, order and item.
- Process digitisationThe process that still runs on paper, WhatsApp and one shared spreadsheet.
Start with the Week 1 audit
Two calls, a fixed fee, and one real transaction followed end to end through the system you want to replace. The one-pager names where we would draw the boundary, which slice we would take first and what we expect to go wrong. It is yours whether or not we build anything. NDA-friendly, fixed scope. Write to hello@woodfrog.tech.