DEV Community

Geminate Solutions
Geminate Solutions

Posted on

Legacy Application Modernization: Prove Old and New Systems Agree

The safest way to finish a legacy application modernization is to run the old and new systems on the same real requests, compare every answer, and switch over only when every difference has been explained and signed off. If your team can't show you that comparison, they're asking you to trust the rewrite on faith.

You're probably here because a team has rebuilt something that matters, such as an order engine, a billing run or a pricing service, and now they want a date to switch off the old one. The demos look good and the test suite passes. But nobody can show you evidence that the new system gives the same answers on a normal Tuesday's real traffic.

How do parallel runs and shadow traffic actually work?

Shadow traffic copies each live request to the new system while the old system keeps serving the user. The new system's answer is recorded and compared, but never sent back to the user. A parallel run is the batch version of the same idea: the same input file or nightly job goes through both systems and the outputs are compared line by line.

The copying usually happens at the edge. Envoy's request mirroring, the NGINX mirror module or an API gateway can duplicate HTTP calls. Event-driven systems can send each queue message to both consumers. A comparison service then normalises both answers, which means it ignores field order, timestamps, generated IDs and whitespace, and logs whatever is left as a mismatch.

Writes are the hard part. In shadow mode, the new system must write to its own isolated database, and every side effect has to be stubbed out: emails, payment calls, partner APIs. Skip this and you will charge customers twice.

Why isn't the test suite enough? Tests check what the team thinks the old system does. Real traffic shows what it actually does: edge cases added fifteen years ago, records created before a validation rule existed, and the rounding quirk your finance team has quietly worked around for years.

What does it cost to cut over without this proof?

When a migration goes wrong, the system usually doesn't crash. It gives answers that are quietly wrong. An invoice total is slightly off, a customer lands in the wrong tier, or a report that finance relies on shifts without anyone noticing. Customers or auditors find it weeks later.

A crash gets fixed in an hour. A quietly wrong answer can run for a month.

By then the new system has accepted writes and the two data stores have drifted apart, so rolling back is no longer simple. The business loses confidence, someone insists the old system stays on "just in case", and you end up running and maintaining two systems with no end date. The legacy system modernization guide covers how this risk shapes which modernization path you pick in the first place.

Who doesn't need a full shadow run?

Not every system needs this. If the tool is internal, used by a few people and mostly reads data, a staged rollout behind a feature flag plus user acceptance testing is enough. The same applies when the new version is meant to behave differently, for example a redesigned workflow, because comparing outputs that are supposed to differ proves nothing.

The test is simple. If a wrong answer would be noticed within minutes and you can undo it cheaply, skip the shadow run. If a wrong answer could go unnoticed and affect money, compliance or another system, do the shadow run.

What mismatch rate should you accept?

Don't accept a single overall percentage. Group outputs by what happens if they're wrong. Fields that touch money, compliance or data another system consumes need zero unexplained mismatches. For display-only fields, you can accept differences as long as they are known and written down.

Ask the team to put every mismatch into one of four groups:

  • Bug in the new system. Fix it, then rerun.
  • Bug in the old system that the new one corrects. This needs sign-off from the business owner, because downstream reports or people may depend on the old wrong answer.
  • Expected difference (precision, formatting, ordering). Add it to the normaliser with a written reason.
  • Unexplained. If it's in a critical field, it blocks cutover. No exceptions.

The number that matters is unexplained mismatches, not total mismatches. A run with hundreds of differences that are all explained is safer than a run with a handful that nobody has investigated.

Also check the denominator. An overall rate can look clean while rare request types, such as refunds, year-end adjustments or one region's tax rules, were barely tested. Require a minimum number of compared requests for each category before that category counts as proven.

How long should the shadow run last?

Run it long enough to cover a full business cycle: at least one billing cycle, one month-end close and one peak day. If the system has a yearly event, such as tax season, renewals or enrolment, either wait for it or replay captured traffic from the last one.

Compare speed and errors as well as answers. If the new system gives the right result but its slowest responses take twice as long, it's not ready for peak traffic.

What should the team report before a legacy application modernization cutover?

Ask for this list before you sign anything. Each item covers a specific way cutovers fail.

  1. Coverage by request type, plus a list of types never seen. Code paths that real traffic never reached haven't been tested.
  2. A grouped mismatch log, with every critical-field mismatch explained. This turns trust into evidence you can audit.
  3. Every normalisation rule, with its reason and who approved it. The normaliser can hide real bugs. A rule that ignores a total or a balance field is a red flag.
  4. Old-system bugs the new system corrects, each signed off by the business owner. Someone downstream may rely on the old behaviour.
  5. Proof that shadow mode caused no real side effects, and that real side effects were tested separately. Both halves matter.
  6. Slowest-response times and error rates at peak, compared side by side. Correct but slow still fails users.
  7. A reconciliation of the migrated data: record counts and checksums for key tables. This catches data lost or changed during the move.
  8. A rehearsed rollback, with the point of no return named. Everyone should know the moment rollback stops being cheap.
  9. A decommission plan: how long the old system stays read-only, where its data is archived, and who owns it. Switching off too early removes your only reference for checking answers.

Once the shadow run is clean, move a small slice of real users to the new system, then increase it in steps. Keep the old system warm until one more full cycle has passed.

Where to go from here

If your team has a cutover date but not this evidence, start by asking for items 1, 2 and 3 above. Those three answers will tell you how close you really are.

If you want an outside view of your cutover plan, Geminate Solutions will review it for free and reply within 24 hours, under NDA before we talk. For the wider question of how to choose and sequence a modernization, see the legacy system modernization guide.

Top comments (0)