Software & Applications · Service 13

Modernise the system without stopping the business.

Somewhere in most established companies there is a system everyone depends on and nobody wants to touch. It works. It also cannot be changed safely, cannot be handed to a new developer, and gets a little more expensive every quarter. Modernisation is the discipline of fixing that in stages, while it keeps running.

No big-bang rewriteBehaviour preserved Reversible at every stepDocumented as we go
Start at the symptoms
Replaced piece by piece

Recognition

Eight things people say before they call

Legacy is not about age. Plenty of ten-year-old systems are fine. A system is legacy when changing it has become frightening — when the cost of a small change is dominated by the risk of touching anything at all.

That fear is rational. It usually comes from a real history: a developer who left without documentation, a framework that stopped receiving updates, a database schema that grew organically for eight years, or a set of business rules that exist only in code nobody has read since they were written. None of that is anyone's fault. It is simply what happens to software that succeeds for long enough.

?
"Only one person understands it"

The bus factor is one. Every change queues behind a single calendar, and that person cannot take a holiday without the business slowing down.

?
"We are stuck on an old PHP version"

The host keeps warning you. Upgrading breaks the site, so it stays where it is — accumulating unpatched vulnerabilities each year.

?
"Every change breaks something else"

Fixing one thing reliably breaks another, because the logic is entangled and there are no tests to catch it before your customers do.

?
"We cannot find anyone to work on it"

The technology is unfashionable or obsolete. The developers who know it are expensive, retiring, or both.

?
"There is no staging environment"

Changes go straight to production because nobody ever built a safe place to try them. Every deployment is performed with held breath.

?
"It runs on a server we are afraid to reboot"

Something was configured by hand years ago and never written down. Nobody is confident it would come back up.

?
"The vendor stopped supporting it"

The platform, framework or plugin is abandoned. Security fixes are no longer coming and nobody is publishing patches.

?
"We were quoted a rewrite and lost our nerve"

Somebody proposed starting again, the number was enormous, and the project was shelved. Meanwhile the system got another year older.

The arithmetic of waiting

Doing nothing is a decision with a price

Deferring modernisation is often the right call for a year. It is rarely the right call for five. Drag the slider to see what typically changes as a system ages without investment.

The costs below are not hypothetical categories — they are the three things clients consistently report when they finally call. Development slows because every change requires archaeology first. Risk rises because unpatched software accumulates known vulnerabilities. And the eventual replacement gets more expensive, because the system has absorbed more undocumented business logic that somebody now has to rediscover.

2 years
Cost of a changeNormal

Changes take about as long as you would expect. The team can still estimate confidently.

Security exposureLow

Dependencies are current or close to it. Patches are still being published.

Cost to replace laterContained

The behaviour is still mostly understood and could be specified without excavation.

Directional, not a prediction — every system ages differently. The pattern is what matters: the curve is not linear, and the steepest part is usually years four to six.

Method

Replace it a piece at a time, in production

The pattern has a name — the strangler fig, after the plant that grows around a tree and gradually takes its place. New code is written alongside the old system, traffic is moved across one capability at a time, and the old part is removed only once nothing depends on it.

The advantage is not elegance, it is reversibility. At every point there is a working system. If a newly migrated component misbehaves, traffic goes back to the old path in minutes rather than requiring a rollback of an entire release. Business continues throughout, and value arrives continuously rather than in one terrifying weekend eighteen months from now.

It is slower on paper than a rewrite, and it is the reason these projects finish. Rewrites fail because the business keeps changing while the replacement is being built — so the new system chases a moving target and is out of date before it ships. Incremental replacement keeps up, because it is always in production.

Order management systemMigrated: 0 of 8

Scroll on — the migration runs as you read.

Options

Four honest routes, and when each is right

Not everything should be modernised. Part of the assessment is deciding which of these applies — including the one where the correct answer is to leave it alone.

Route one

Refactor in place

The architecture is sound; the code has simply accumulated mess. We add tests around current behaviour, then improve structure without changing what it does. Nothing visible changes for users.

Best whenThe design is fine, the implementation drifted
RiskLow — behaviour is pinned by tests first
Watch forRefactoring becoming endless without a target
Route two

Strangle it gradually

New capabilities are built outside the old system, and traffic moves across one route at a time behind a facade. The legacy code shrinks until what remains can be retired quietly.

Best whenThe system is large, critical and must stay running
RiskLow — reversible at every step
Watch forStalling half-done and running two systems forever
Route three

Replatform

Same behaviour, modern foundation. Often the answer for a bespoke system doing something an existing platform now does well — the value was never in the plumbing.

Best whenOff-the-shelf has caught up with your custom build
RiskMedium — data migration is the hard part
Watch forLosing the few genuinely bespoke rules that mattered
Route four

Leave it alone

Stable, rarely changed, not exposed to the internet, and not blocking anything. Then the honest recommendation is documentation, backups and a contingency plan — not a project.

Best whenIt works, it is isolated, and nobody needs to change it
RiskLow, provided the contingency plan is real
Watch for"Rarely changes" quietly becoming "cannot change"

Safety

How we avoid breaking what already works

Modernisation goes wrong in predictable ways. These are the controls that prevent each of them, and they are in place before any existing code is touched.

First

Characterisation tests

Before changing anything, we write tests that capture what the system currently does — including the odd behaviour, because something probably depends on it.

Second

A staging environment

Often the first deliverable, because you cannot safely modernise a system you can only test in production.

Third

Version control and history

If the code is not already in Git, it goes in first. Modernisation without the ability to see what changed is guesswork.

Fourth

Feature flags

New paths ship switched off, are enabled for a small share of traffic, and can be turned back off in seconds without a deployment.

Fifth

Parallel running

For critical calculations, old and new run side by side and their outputs are compared on real data before the old one is retired.

Sixth

Documentation as output

What we learn about the system gets written down as we go. Often this is worth more than the code changes — it is what ends the bus-factor problem.

Questions

Legacy modernisation, answered

Should we rewrite from scratch instead?

Occasionally, but far less often than it is proposed. Rewrites are seductive because the new system is imaginary and therefore perfect. In practice they take longer than estimated, the business keeps changing during the build, and the old system's undocumented behaviour has to be rediscovered anyway — usually by an angry customer after launch.

A full rewrite makes sense when the system is small, when the platform is genuinely dead, or when the business rules have changed so completely that preserving current behaviour has no value. In every other case, incremental replacement gets there with far less risk.

Can you work on our system without disrupting the business?

That is the whole point of the approach. Work happens alongside the running system, changes go through staging, and new paths are introduced behind switches that can be turned off instantly. The system stays live throughout.

The one thing we will ask for is a window to establish the safety net — staging, version control, backups — before touching anything. Skipping that step is what turns modernisation into an outage.

What if there is no documentation at all?

That is the normal case rather than the exception. The assessment includes reading the code, tracing the important paths, and talking to whoever uses the system daily — users usually know the behaviour better than any document would have captured.

What comes out of that is written down, and it is frequently the most valuable single deliverable, because it is what makes the system survivable when the one person who understands it is unavailable.

How long does this take, and can we stop partway?

It is deliberately structured so you can. Work proceeds in stages that each leave the system in a better and fully working state, which means you can pause after any of them — when budget changes, when priorities shift, or simply when the pain has reduced enough.

That is a real difference from a rewrite, where stopping halfway leaves you with two incomplete systems and nothing to show.

Will this make the system faster?

Often, though it is a side effect rather than the goal. Old systems tend to accumulate inefficient queries and duplicated work, and those surface during the process. If performance is the primary concern, say so early — it changes which parts we prioritise.

What does the assessment involve?

A fixed-price piece of work with a written deliverable. We review the codebase, dependencies, hosting, data model and deployment process, then produce a plain-language report: what you have, what the real risks are, which route we recommend and roughly what each option costs.

It is yours regardless of whether you continue with us — you can take it to another developer, and some clients do.

Do you work with older technologies?

Yes. Older PHP, legacy WordPress and Joomla builds, classic ASP-era systems, jQuery-heavy front ends, procedural codebases without frameworks. The technology matters less than whether the behaviour can be understood and pinned down before it is changed.