
Ask why a legacy system is being modernised and you will often get a description of the system rather than an answer: it is old, it is hard to hire for, it runs on something the vendor no longer supports. All true, none of them an outcome.
Those facts explain why the system is uncomfortable to own. They do not explain what the business will be able to do afterwards that it cannot do now — and that gap is where modernisation programmes lose their way, usually around month nine, when the cost is visible and the benefit still is not.
Name the constraint
Useful modernisation cases are specific about what is currently blocked. A pricing change takes six weeks because the logic is duplicated in three places. A new market cannot be opened because the platform assumes one currency and one regulator. Month-end close takes four days because reconciliation is manual. Peak season requires capacity that sits idle for ten months.
Each of those is a constraint a business leader recognises, and each suggests a different scope. The pricing problem might be solved by extracting one service. The currency problem might require a data model change and nothing else. Without naming the constraint, scope defaults to “all of it”, which is the most expensive option and rarely the most valuable.
Sequence by value and risk, not by architecture diagram
The instinct is to modernise from the bottom up — platform first, then services, then the user-facing parts. It is architecturally tidy and it delays every visible benefit to the end of the programme, which is precisely when funding and attention are most fragile.
A more durable sequence alternates: something that demonstrably improves an outcome, then something that reduces risk or removes a dependency, then another visible improvement. Nobody outside the team can see a migrated message bus. They can see that a change which used to take six weeks now takes four days.
Be explicit about what you are not doing
Modernisation programmes accumulate adjacent work. Since we are rewriting it anyway, could we also fix the reporting, change the approval flow, redesign the interface? Each addition is individually reasonable and collectively fatal.
Writing down what is explicitly out of scope, and where those items go instead, is worth more than it sounds. It converts a series of small unrecorded expansions into a visible decision someone has to make deliberately.
Plan for the period when both systems exist
Very few migrations are a single cutover. For a period — usually longer than planned — old and new run together, and that period has its own real costs: duplicated data, synchronisation, staff who must know both, ambiguity about which system is authoritative for a given question.
Teams that plan this phase explicitly tend to get through it. Teams that treat it as a short gap between two steady states tend to find it becomes the steady state, because there is never a quiet quarter in which to finish.
Decide who owns it afterwards
A modernised platform needs operational ownership: someone accountable for its cost, its reliability, and the decisions about what it should do next. If that ownership is not established during the programme, the new system starts accumulating the same organisational debt as the one it replaced — undocumented changes, unclear priorities, no obvious person to ask.
Cloud makes this sharper, because cost becomes a continuous operational decision rather than a periodic procurement one. The FinOps practice that emerged around this exists for a reason: consumption-based infrastructure without ownership of consumption produces bills that nobody predicted and nobody can explain.
A test for readiness
Before committing, see whether the sponsoring leader can complete this sentence without mentioning technology: “When this is done, the business will be able to ___, which it cannot do today.”
If the sentence completes easily, there is a programme worth running and a way to tell whether it worked. If it does not, the honest next step is not a bigger business case — it is a smaller piece of work to find out where the real constraint is.
