Greyquill

Modernisation

The parallel run

Replacing a legacy system without a big-bang rewrite. Both systems process the same work until the evidence says the new one is right.

One page, the whole method.

Where the risk lands

A big-bang rewrite puts all of its risk on one night. A parallel run spreads the same risk across months, while the old system is still there to catch it.

Risk over time, big bang against parallel run In a big-bang rewrite risk stays flat during the build and spikes sharply at cutover. In a parallel run, risk is discovered and resolved in small amounts throughout the parallel period, so the cutover itself is a small step. Big bang cutover build, nothing proven risk Parallel run parallel period cutover found and fixed here

You cannot prove a rewrite is correct until it processes real work, and a big-bang cutover switches off the only thing that could have told you.

Five stages

01

Map the estate

What exists, who owns it, where the risk sits.

02

Pick the seam

One capability. Small blast radius.

03

Build alongside

Behind a facade. Legacy untouched.

04

Run in parallel

Both process the same work.

05

Retire and repeat

Cut over on evidence, switch the old one off.

Stage four is where most of the work sits, and it is the stage that usually gets the least attention.

Picking a seam

Good first seam

  • Output you can compare: a file, a ledger entry, a number
  • Enough volume to establish a divergence rate
  • Somebody actually wants it fixed
  • Few downstream consumers, and you can name them
  • An owner who will answer questions

Not first

  • Output is a side effect you cannot observe
  • The component with the worst reputation, usually the most coupled
  • Anything that has to change behaviour at the same time
  • Four runs a month, so a year before it tells you anything
The mistake that voids the exercise

Improving the logic while you are in there. Every difference then has two possible causes and the comparison proves nothing. Freeze behaviour, prove equivalence, cut over, then change what the system does.

Stage four, in one picture

The parallel run Inbound work is sent to both the legacy system and the replacement. The legacy output goes downstream and is the one used. The replacement output goes to a comparator, which classifies each pair as match, tolerable divergence, real divergence, or legacy defect, and writes the result to an evidence store. Inbound work Legacy still live, untouched Replacement output not used yet Downstream the real result Comparator 1 · Match 2 · Tolerable divergence 3 · Real divergence 4 · Legacy defect Evidence store Solid line: the path in use. Dashed: observation only.

The replacement sees production work from day one and carries none of the production risk. Compare the output, not the internals. It is allowed to reach the answer differently.

Four outcomes, four responses

ClassMeaningWhat you do
MatchSame result within the agreed tolerance.Count it.
TolerableDiffers in a way that is understood and does not matter: ordering, formatting, an always-arbitrary rounding step.Encode the rule in the comparator. Never wave one through twice by hand.
RealThe replacement is wrong.Fix it, add the case to the harness, keep running. Expect this to dominate early and approach zero.
Legacy defectThe replacement is right and the legacy has been wrong, possibly for years.Stop. This is a business decision, not an engineering one.

The awkward one

Class four arrives in almost every parallel run of any length, and the instinct is to make the replacement match so the run can finish. That silently bakes a known defect into a new system.

01

Quantify

How many records, over what period, in which direction.

02

Ask the outcome owner

Not the system owner. What should the answer be?

03

Record the ruling

In writing, dated, attributed.

04

Implement and mark

The comparator now expects this difference.

Teams find this uncomfortable at first. It is also one of the more useful things a parallel run turns up, because you end up with a written decision on something that had been running unexamined for years.

When to stop, and when to cut over

Real divergences at zeroStable across a full business cycle, including month and quarter end.
Differences explained in codeEvery tolerable one is a comparator rule, not a person reading a report.
Rulings closedEvery legacy defect has a dated, attributed decision.
Coverage statedIf sampled, the sampling rule is written down and the approver has seen it.
Runbooks usedBy somebody outside the build team, while there is still time to fix what they find.
Rollback testedA configuration change that has been exercised, not a plan on a slide.
Then make the cutover dull

Flip which implementation the facade routes to. Keep the comparator running with the roles reversed for a while, so the legacy is now the one being observed. That costs almost nothing and catches the difference that only appears under real load.

Retiring, for real

01

Set the date at cutover

Dates negotiated after the fact tend to keep moving.

02

Cut the inputs first

Anything still calling it will fail loudly while the system is up and you can still look.

03

Archive the data

Readable without the application. Data is usually the reason an old system stays switched on.

04

Decommission

Licences, credentials, network, jobs, monitoring nobody will act on.

What it costs, and when not to

You reach the first cutover later than you would with a big bang. Every seam after it goes faster, because the harness, the comparator and the facade pattern already exist.

No observable outputThe method has no grip. Find a different boundary.
A one-shot migrationThat is a migration with reconciliation. Different method, similar words.
Volume too lowYou will never establish a divergence rate. Use a designed test suite and a staged rollout.
Behaviour must change on day oneEquivalence is not the goal, so there is nothing to prove.

The parallel run, at a glance

Replacing a legacy system without a big-bang rewrite.

Five stages

01

Map the estate

What exists, who owns it, where risk sits.

02

Pick the seam

Observable output, real volume, small blast radius, an owner.

03

Build alongside

Behind a facade. Regression harness first. Legacy untouched.

04

Run in parallel

Both process the same work. Only legacy output is used.

05

Retire and repeat

Cut over on evidence. Switch the old one off on a set date.

Classify every difference

ClassMeaningAction
MatchSame result within tolerance.Count it.
TolerableUnderstood, and does not matter.Encode the rule in the comparator. Never wave one through twice by hand.
RealThe replacement is wrong.Fix it, add the case to the harness, keep running.
Legacy defectThe replacement is right, the legacy has been wrong.Quantify, ask the outcome owner, get a written ruling, then implement.

Stop when all three hold

  • Real divergences at zero, stable across a full business cycle
  • Every tolerable one encoded as a rule
  • Every legacy defect closed with a dated ruling

Do not use this when

  • The seam has no observable output
  • It is a one-shot data migration
  • Volume is too low for a divergence rate
  • Behaviour must change on day one

Cutover gates

  • Zero real divergences over a full cycle
  • All differences explained in code
  • All rulings closed in writing
  • Sampling rule stated, if sampled
  • Runbooks used by someone outside the build team
  • Rollback tested, not planned
The mistake that voids the whole exercise

Changing behaviour and implementation at the same time. Every difference then has two possible causes and the comparison proves nothing. Freeze behaviour, prove equivalence, cut over, then change what the system does.

Greyquill Software builds AI and data systems that can be audited, and modernises the ones that cannot. greyquill.io