advanced 3 min answer

A financial calculation engine is being replaced and the results must be proven equivalent before cutover. How should a parallel run be designed, and how are discrepancies triaged?

parallel-runmigrationreconciliationfinanceverification
Show the full answer Hide the answer

Why a parallel run rather than testing

Test suites verify the cases someone imagined. A financial engine's risk is concentrated in the cases nobody imagined — historical records with unusual shapes, edge cases in rounding, accumulated data from previous system versions, and behaviours introduced years ago for reasons now forgotten.

A parallel run tests against reality, which is the only source of inputs that contains those cases.

The design

  • Both systems process the same real inputs, with the legacy result authoritative and used, and the new result recorded for comparison. Users are unaffected throughout.
  • Run for a full business cycle at minimum — month-end, quarter-end, and any annual process. The rare periodic calculation is where the differences concentrate, and a two-week parallel run systematically misses it.
  • Compare at multiple levels: the final figure, the intermediate components, and the inputs each system actually consumed. A matching total with differing components is a coincidence waiting to stop being one.
  • Define tolerance explicitly and by field. Floating-point differences in the last decimal place may be acceptable in an intermediate value and are not acceptable in a posted amount. A single global tolerance is always wrong in one direction or the other.
  • Automate comparison and triage, because at volume the differences must be classified by machine before a human can look at them.

Triaging discrepancies

Every difference falls into one of four categories, and assuming the first is the failure mode:

  1. The new system is wrong. The expected case; fix and re-run.
  2. The legacy system is wrong. It happens more often than teams expect, and it is the most difficult situation — because correcting it changes historical figures, which may have been reported, audited or used in decisions. The resolution is a business and possibly regulatory conversation, not a technical one.
  3. Both are defensible and the specification was ambiguous. This is where the real requirement is discovered, and the outcome should be a documented decision rather than a code change alone.
  4. The inputs differed, which is not a calculation difference at all and is frequently the largest category early on — different data feeds, timing, or filtering.

Rule: no discrepancy is closed without a category and an explanation. "Rounding" as an unexamined explanation is how a genuine defect is closed as noise, and it is the most common way a parallel run produces false confidence.

The exit criteria, agreed in advance

Written before the run starts, because they cannot be negotiated honestly afterwards under schedule pressure:

  • Zero unexplained differences in the authoritative outputs, for a defined number of consecutive cycles.
  • All differences categorised, with those in category 2 having a documented business decision.
  • Performance and operational readiness demonstrated at production volume.
  • A defined rollback available for a period after cutover.

The cutover and after

Switch authority, and keep the legacy system running and calculating in parallel for a further period. The first live period is when the remaining differences surface, and having the legacy result available makes an unexpected discrepancy diagnosable rather than alarming.

Then decommission with a date, in the same funded project. A parallel run that never ends is the most expensive possible outcome — two systems, two teams, two sets of changes forever — and it is a genuinely common one, because nobody wants to be the person who turned off the safety net.