Application modernisation

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.

If several of these are true, the question has stopped being whether the system gets replaced. It is whether it gets replaced in slices or in one attempt with a single date on it.

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.

The requirements01

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.

The other half02

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.

The moving target03

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.

The single date04

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.

The verdict05

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.

  1. The vendor is gone, the framework is unsupportedA boundary in front of the old system
  2. Every change takes weeks, most of it testingTests that pin current behaviour
  3. A rewrite was tried and abandonedSlice order and sequencing
  4. Nobody will sign off touching itParallel run and reconciliation
  5. Onboarding takes a quarterA written inventory of behaviour
  6. One person understands the whole thingA written inventory of behaviour
Left is how the problem gets described on the first call. Right is the piece of work it turns into. They rarely arrive one at a time, which is why the order of the work matters more than the choice of tooling.

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.

  1. 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.

  2. 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.

  3. 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.

  4. 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.

  5. 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.

  6. 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.

  7. 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.

  1. 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.

  2. 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.

  3. 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.

Our sequencing rules, stated plainly so you can argue with them during the audit week rather than after the first slice has been chosen.

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.

This list gets written against your systems specifically during the Week 1 audit. Two calls, a fixed fee, and you keep the one-pager whether or not the rest of the work goes ahead.

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.

  1. Rounds part-units down, alwaysLoad-bearing rule, carried across
  2. Retries a failed payment exactly onceLoad-bearing rule, carried across
  3. Accepts an order with no delivery dateDefect the business now depends on, decided in the open
  4. Back-dates a correction into the original periodDefect the business now depends on, decided in the open
  5. Silently truncates a field longer than the columnDefect, fixed, affected records listed
  6. Ignores the credit limit for two account typesNobody has relied on it in years, removed
An illustration of the shape, not a real client system. The specific behaviours change every time. The two hard rows do not: the rule nobody wrote down that turns out to be load-bearing, and the defect a downstream team has quietly built a process around.

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.

  1. 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.

  2. 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.

  3. 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.

  4. 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.

  5. 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.

  1. 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.

  2. 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.

  3. 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.

  4. 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.

  5. 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.

20+Companies delivered forAcross India, APAC and the US, from Pune.
50+Projects deliveredSince the firm was founded in 2023.
6 weeksMedian to first production artefactA pod of three, fixed scope, and no bench sitting behind it.
Week 3Something works byYou react to running software with your own traffic going through it, not to a plan.

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.

Adjacent work01

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
What we can say02

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.

What we will not do03

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
What to ask instead04

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.

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.