Modernising Legacy Web Platforms: A Technical Debt Roadmap
Rewrites fail at a famously high rate. Incremental strangulation, sequenced by business risk, is how legacy platforms actually get modernised.
Every legacy modernisation conversation eventually reaches the same fork: rewrite or refactor. The rewrite is emotionally appealing — clean slate, modern stack, no compromises — and it is also where most of these programmes go to die, typically 18 months in, with feature parity unreached and the business increasingly unwilling to fund a system it cannot yet use.
Incremental modernisation is less satisfying and far more likely to finish.
Inventory the debt before proposing solutions
"The platform is old" is not a diagnosis. Produce a specific register across five categories, and score each item on business impact and remediation cost.
| Category | Examples | Primary risk |
|---|---|---|
| Runtime debt | Unsupported language, framework, or database versions | Security exposure, no vendor support path |
| Architectural debt | Shared database across domains, no seams, circular dependencies | Change amplification and coupled release risk |
| Delivery debt | Manual deploys, no test coverage, long-lived branches | Slow, unpredictable releases |
| Knowledge debt | Undocumented business rules, single-owner subsystems | Key-person dependency, unquantifiable change risk |
| Data debt | Duplicated records, no lineage, inconsistent definitions | Unreliable reporting and integration failures |
Knowledge debt is usually the binding constraint and is almost always omitted from modernisation plans. Undocumented business rules are what turn a six-month migration into an eighteen-month one.
Sequence by risk, not by architecture elegance
Order the work by three factors: business risk if unaddressed, change frequency of the area, and coupling difficulty. That combination naturally produces a sensible sequence.
- First: unsupported runtimes and dependencies with known vulnerabilities. This is non-negotiable, unglamorous, and buys time for everything else.
- Second: delivery capability — automated tests around the highest-risk paths, one-command deploys, and observability. You cannot safely change a system you cannot deploy or observe.
- Third: extract the highest-change domain behind a clean interface. Frequently changed code returns the modernisation investment fastest.
- Fourth: the remaining domains, in decreasing order of change frequency, leaving stable, rarely touched subsystems for last or forever.
Not every legacy component must be modernised. A stable module that changes twice a year and works correctly is not a priority regardless of how dated its implementation looks.
Strangle, do not replace
Put a facade — a proxy, gateway, or routing layer — in front of the legacy system. Route one capability at a time to a new implementation while everything else continues to be served by the incumbent. Each increment ships to production, delivers value, and can be rolled back independently.
Two practical constraints make this work. Avoid dual writes wherever possible; nominate one system as the writer per data domain and use events for propagation. And define a completion condition per increment, because half-migrated capabilities running in both systems indefinitely are the worst possible end state — double the maintenance, none of the benefit.
Guardrails for the migration window
- Characterisation tests. Before changing behaviour, write tests that capture current behaviour, including the bugs users depend on.
- Traffic shadowing. Send production traffic to the new implementation without serving its responses, and compare outputs.
- Feature flags per route. Percentage rollouts with an immediate revert path.
- SEO parity checks. URL structure, redirects, rendering of body content, and structured data validated before each cutover. Organic revenue loss is the most common unplanned cost of replatforming.
- Data reconciliation. Automated comparison of record counts and key aggregates during any parallel-run period.
Making the business case
Executives do not fund debt reduction; they fund outcomes. Translate accordingly: cycle time for revenue-affecting changes, incident frequency and cost, engineering time consumed by maintenance versus new capability, security exposure from unsupported components, and the named opportunities the platform currently blocks. Then request funding in quarterly increments tied to observable milestones rather than as a single multi-year programme, which is both easier to approve and easier to course-correct.
Frequently asked questions
What is the strangler pattern?
Replacing a legacy system incrementally by routing individual capabilities to new implementations behind a facade, while the legacy system serves everything else, until it can be retired without a big-bang cutover.
Rewrite or refactor?
Refactor incrementally in almost every case. Rewrite only when the runtime is unsupported with no upgrade path, regulatory requirements cannot be met, or the business domain model itself is fundamentally wrong.
How long does modernisation take?
Meaningful risk reduction within two quarters if sequenced correctly. Full modernisation of a large platform is a multi-year programme — which is precisely why it must deliver value incrementally.
How do we avoid losing SEO during migration?
Freeze URL structure where possible, maintain a tested redirect map, verify server-rendered body content and structured data on the new stack, and cut over by template with monitoring rather than all at once.