Cross-sector

Legacy modernization

A pattern for replacing critical systems that cannot be safely changed, without a cutover. It uses a facade over the existing platform, extracts one capability at a time, migrates data incrementally with reconciliation, and retires the original only when nothing depends on it.

Anti-corruption adapters over legacy interfaces Strangler facade with versioned contracts CDC or incremental batch replication with reconciliation Dual-run and shadow comparison against live behaviour
The situation

When this pattern is the right one.

The systems that matter most are usually the ones nobody dares touch. They carry the real business rules, run on infrastructure nobody can rebuild, and are understood only by a shrinking group of people. Change has become too risky, so improvement has effectively stopped.

01

Business logic is interleaved with storage, so neither can be replaced alone

02

Original knowledge is distributed across people, and documentation does not exist

03

A small change to shared code has an unpredictable blast radius across customers

04

Data volume and history make a single migration event the highest-risk step in the plan

05

There is no interface, so every integration is bespoke and every integration is fragile

The approach

How the work is done.

Before anything moves, we build an accurate functional picture with the people who operate the system, and wrap the riskiest paths in characterisation tests so behaviour is pinned down before it changes. A facade goes in front, and new capability is built behind it while the legacy path keeps serving traffic. Traffic shifts by measured segments, with reversal at every step. Data moves incrementally with reconciliation at each stage, and the old system is only decommissioned once nothing reads from it.

Functional and dependency map built with the people who operate the system

Characterisation tests around critical paths before any refactoring

Facade or gateway in front of the legacy platform, versioned from the start

One capability extracted at a time with traffic shifted gradually and reversibly

Incremental data migration with reconciliation checks at every stage

Explicit decommissioning plan, owned by someone with authority to sign it off

Indicative stack

What this is usually built with.

Chosen per problem rather than run as one stack for everything. The list below is representative, not a commitment.

Representative componentsselected per constraint
Anti-corruption adapters over legacy interfaces
Strangler facade with versioned contracts
CDC or incremental batch replication with reconciliation
Dual-run and shadow comparison against live behaviour
Consumer-driven contract tests for each extracted capability
Parallel run infrastructure and traffic splitting
Infrastructure as code for the replacement platform
Structured logging introduced alongside the legacy path
What it supports

The outcome this pattern is chosen for.

This pattern is designed to support a business that keeps operating throughout. Its purpose is to reduce the cost and risk of change without requiring the old system to be switched off on a particular date.

01

Allows change to resume in a system that had become too risky to modify

02

Removes the single irreversible cutover as the only path to progress

03

Produces a versioned interface that makes the system replaceable in future

04

Keeps legacy scope shrinking measurably, phase by phase

05

Leaves the replacement on ordinary, understood infrastructure rather than a bespoke foundation

Watchouts

The parts that tend to go wrong.

Written down because they are the same parts that go wrong everywhere, and knowing them up front is cheaper than discovering them halfway through.

Rewrites are almost always the wrong instrument; the value is in the facade and the extraction sequence

Data migration is the part most likely to be underestimated, particularly history and reconciliation

Running the old and new paths in parallel has real operating cost and needs funding agreed up front

Stalling before decommissioning leaves two systems running indefinitely, which is its own kind of failure

If the operational knowledge is not captured while those people are still present, it is usually lost

Note

These are solution patterns, not client case studies. Each one describes a reusable engineering approach and the problem shape it addresses. No client is named and no result is claimed.

Note

Nothing here reports a measured outcome. The outcome sections describe what each pattern is designed to support, and what a team should expect to be able to do once it is in place.

Note

Named references, implementation detail and engagement history can be discussed directly on request, subject to client confidentiality.

Note

This page is structured so that verified case studies can be added alongside these patterns without changing the underlying format.

Recognise your situation in this one?

Patterns are general. The engineering decisions are not, and they are worth discussing against your actual constraints.

Start a conversation All patterns