Parallel Run and Dual-Ledger Validation in Core Migration
Proving the New System Agrees Before You Trust It With the Bank
Parallel running is the control that makes core migration defensible, and it is routinely implemented as a comfort exercise. Both systems run, someone compares end-of-day totals weekly, the totals broadly agree, and the programme declares validation complete. Then cutover happens and the differences that were never at total level surface one customer at a time.
Done properly, parallel run core migration validation is a measurement programme with its own engineering, its own triage discipline, and its own exit criteria. It is also the single strongest piece of evidence you will have when a board or a supervisor asks how you know the new system is right.
What is a parallel run actually proving?
Four things, and it is worth naming them because they need different evidence.
| Question | Evidence required |
|---|---|
| Does the new system compute the same outcomes? | Field-level output comparison on real inputs |
| Does it perform within the available window? | Timed runs at production volume |
| Can operations actually run it? | Rehearsed procedures, incident handling, staffing |
| Does the data reconcile? | Balance and posting reconciliation, continuous |
What can a parallel run not prove?
That behaviour is correct, that rare paths are covered, or that customers will be unaffected by intended changes.
Equivalence means the new system matches the old one, including where the old one is wrong. If a legacy calculation has been quietly incorrect for a decade, a successful parallel run reproduces it, which is the right outcome for migration and a poor outcome for the customers affected. Track those discoveries separately as business decisions rather than defects. The run also cannot cover paths the period did not exercise, so maintain an explicit list of untested behaviour as residual risk at cutover.
Does your comparison operate at field level, or on end-of-day totals?
Which parallel run models exist?
Five, with shadow mode doing most of the work.
| Model | Description | Use |
|---|---|---|
| Shadow processing | Legacy authoritative, new system processes same inputs with no customer effect | The workhorse for core migration |
| Replay-based | Captured inputs replayed into the new system on demand | Good for logic translation and regression |
| Sampled comparison | A subset compared in detail | Only after full comparison has stabilised |
| Dual processing with legacy authoritative | Both process live, legacy serves customers | Same as shadow with tighter coupling |
| Dual authoritative | Both systems serve customers | Not a parallel run, avoid |
Why is shadow mode the workhorse?
Because it exposes the new system to real inputs and real volume with no customer risk.
Feed the new system the same transactions, the same reference data changes, and the same calendar events as production, then compare everything it produces against what the legacy system produced. Because nothing it computes reaches a customer, defects are free, which is exactly the condition you want while difference volumes are high. The operational cost is real, since you are running two estates, and that cost is the price of the evidence.
Why is dual authoritative not a parallel run?
Because divided authority produces divergence rather than evidence.
If both systems serve customers for different accounts or channels, you no longer have a comparison, you have two production systems and a reconciliation obligation. That may be a legitimate migration state under a strangler pattern with clear per-record ownership, as described in strangler fig core banking migration, and it is not validation. Keep the two ideas separate in planning, because conflating them is how programmes end up with neither clean evidence nor clean ownership.
How do you design the comparison?
Field level, across every output type, with zero tolerance and an explicit exception list.
| Output type | What to compare |
|---|---|
| Balances | Every balance type per account, at every boundary |
| Postings | Entry by entry, including narrative, date, and sequence semantics |
| Interest and fees | Amount, base, period, rounding, and accrual position |
| Statements and advices | Content, ordering, totals, and formatting where customer visible |
| Outbound files and interfaces | Byte-level where contracts are fixed, field level otherwise |
| Reports | Regulatory and management outputs, at the reported granularity |
| Events and notifications | Which events fired, with what payload and timing |
| Derived data | Delinquency staging, limits, status transitions |
Why does aggregate comparison mislead?
Because offsetting differences cancel and disappear from the total.
Two accounts wrong by equal amounts in opposite directions produce a perfect total. Compare at the finest granularity your data supports, then aggregate for reporting rather than for detection. Field-level comparison across a full core produces millions of comparisons per cycle, which is an engineering problem worth solving properly: hash-based pre-filtering to find changed records, then detailed comparison on differences only, with the harness itself under test since a broken comparator that reports agreement is the worst possible outcome. The reconciliation mechanics resemble those in this guide to payment reconciliation.
What tolerance is acceptable?
Zero, with a named exception list rather than a numeric threshold.
Blanket tolerances such as differences under a small amount being acceptable are how systematic rounding defects survive validation, because the defect is small per record and large in aggregate. Hold zero tolerance and handle legitimate variance through an explicit list of agreed exception types, each with a business owner, a rationale, and an expiry date. That distinction matters: a threshold hides unknown differences while an exception list documents known ones.
How do you handle legitimate differences?
Classify them, agree them individually, and report suppressed volume so the list stays visible.
| Difference type | Legitimate? | Handling |
|---|---|---|
| Technical identifiers and sequence numbers | Yes | Normalise before comparison |
| Processing timestamps | Yes | Exclude or compare within tolerance |
| Deliberate behaviour change agreed with the business | Yes | Documented exception with owner and sign-off |
| Formatting changes to internal outputs | Usually | Exception with owner |
| Rounding policy corrections | Only if agreed | Requires explicit business decision and impact analysis |
| Ordering differences with no financial effect | Sometimes | Verify no downstream dependency on order |
| Amount differences | No | Defect until proven otherwise |
| Missing or extra records | No | Defect, highest priority |
How do you stop the exception list becoming a suppression mechanism?
Ownership, expiry, and reporting the volume it hides.
Every exception needs a named business owner, a written rationale, and a review date. Report the number of exceptions and the volume of differences they suppress in every status update, because a list that grows quietly is how a programme reaches cutover with clean-looking comparison and an unmeasured defect population. Re-review the whole list before cutover with fresh eyes, ideally someone who was not involved in agreeing the items.
Do you report how many differences your exception list is currently suppressing?
Talk to Digiqt about difference triage and exception governance
How long should the run last?
Long enough to cover every calendar event that changes behaviour, and no longer.
| Event | Why it matters |
|---|---|
| Month end | Accrual, statement, and reporting cycles |
| Quarter end | Additional regulatory and management reporting |
| Year end | Annual processing, tax treatment, rollover logic |
| Statement cycles for each product | Cycle-specific logic and timing |
| A rate change | Repricing and recalculation paths |
| A holiday and weekend sequence | Business-date handling |
| Leap day where applicable | Date arithmetic |
| A production incident and recovery | Restart and reprocessing behaviour |
For a full core, that usually means a minimum of one clean quarter end and frequently a year end, which is why these programmes are measured in quarters rather than sprints. Note that the last row is often the most informative and cannot be scheduled, so treat any incident during the run as a validation opportunity rather than an interruption.
When is the run costing more than it proves?
When difference volume has plateaued low for weeks and the remainder are understood.
Parallel running consumes real capacity, real cost, and window time, and it delays the saving that motivated the migration. Once the burn-down has flattened, the remaining differences are classified and owned, and the required calendar events are covered, extending the run buys diminishing evidence. Write that judgment into the cutover criteria rather than leaving it to nerve, because otherwise the run continues until someone senior loses patience, which is a poor basis for a go-live decision.
How do you triage differences at scale?
By classifying automatically, grouping by root cause, assigning ownership, and reporting a burn-down.
Early cycles will produce enormous difference counts, most from a handful of causes. Classify automatically by output type, field, and signature, group into root causes rather than tracking individual differences, assign each cause an owner and a target date, and report the burn-down by cause count rather than by difference count, since one fix can remove millions of differences. A healthy burn-down falls steeply, then flattens with a small tail of hard cases; a burn-down that stays flat from the start usually means the comparison itself is misconfigured rather than the new system being uniformly wrong.
What operational load does parallel running create?
Double processing, double monitoring, difference triage, and pressure on an already tight window.
Plan for it explicitly: infrastructure for two estates, staff for triage during peak difference volumes, and window capacity for both runs. The window pressure is the constraint people underestimate, since running the new system's cycle inside the existing batch window frequently does not fit, which forces either window work or infrastructure separation. The interaction with change control also matters, because deploying fixes to the new system during the run needs to be fast and safe, which is the argument in change freeze and release management. The wider change risk framing is set out in this guide to managing change risk during core-system migration.
What should the cutover criteria be?
Written in advance, evidence-based, and signed by named people.
| Criterion | Evidence |
|---|---|
| Clean comparison across required calendar events | Comparison reports per cycle, per output type |
| Zero unexplained differences | Triage register with every cause closed or agreed |
| Exception list reviewed and approved | Signed list with owners and rationale |
| Performance within the available window | Timed runs at peak volume with headroom |
| Data migration reconciled | Record counts, balances, and control totals matched |
| Operations rehearsed | Runbooks executed, incident scenarios exercised |
| Rollback tested | Documented and demonstrated, not assumed |
| Regulatory reporting verified from the new system | Reports produced and reconciled |
Agree these before the run begins, because criteria written near cutover tend to describe the state you have reached rather than the state you needed. Name the accountable signatories per criterion, and require the evidence to be attached rather than asserted. The GAO's June 2019 review of critical federal legacy systems found most agencies lacked modernisation plans with milestones, work descriptions, and legacy disposition strategies, and cutover criteria are exactly the milestone definition that keeps a programme honest.
How do you plan rollback and post-cutover comparison?
With a tested rollback path and continued comparison for a defined period after go-live.
Rollback needs to be genuinely tested rather than documented, including what happens to transactions processed on the new system after cutover, since reversing a day of live posting is materially harder than switching a routing flag. Then keep comparison running after cutover: the legacy system continues to process in shadow for a defined period so any difference is caught while both are available. That post-cutover window is the cheapest insurance in the programme and the first thing cut when the schedule slips. The Basel Committee's Principles for operational resilience, published in March 2021, treat this as continuity of a critical service, which is a useful framing for defending the cost.
Which metrics matter?
Difference causes open, unexplained differences, calendar coverage, suppressed volume, performance headroom, and rollback test recency.
Report open difference causes rather than raw difference counts, since causes are what teams fix. Track unexplained differences separately and drive them to zero, as that number is the real gate. Report calendar event coverage against the required list. Publish the volume of differences suppressed by the exception list. Measure window performance headroom for the new system at peak volume. And record when rollback was last tested, because a rollback plan that has never been executed is a document rather than a capability. Delivery discipline throughout matters too, since the DORA research finds speed and stability correlate rather than trade off, and fast safe fixes are what keep the burn-down moving. The data migration side is covered in this guide to data migration to cloud-native platforms, and the logic equivalence side in COBOL to Java modernisation.
Parallel running is where a core migration either earns confidence or manufactures it. The difference lies in whether comparison happens at field level, whether zero tolerance holds with named exceptions rather than numeric thresholds, and whether the cutover criteria were written before anyone knew how the run would go.
Frequently Asked Questions
What is a parallel run actually proving?
That the new system produces the same outcomes as the old one on real inputs, that it performs within the available window, and that operations can run it.
Which parallel run model should you use?
Shadow mode, where the legacy system stays authoritative and the new system processes the same inputs without customer effect, with outputs compared continuously.
Why is running both systems authoritative a bad idea?
Because that is not a parallel run, it is two production systems with divided authority, which creates divergence with no arbiter rather than evidence.
What tolerance should comparison allow?
Zero, with an explicit list of agreed exceptions each carrying a business owner and rationale. Blanket tolerances hide the defects the run exists to find.
How do you stop the exception list hiding real defects?
Require named ownership and expiry per exception, re-review the list on a schedule, and report suppressed difference volume so the list cannot grow unnoticed.
How long must a parallel run last?
Long enough to cover every calendar event that changes behaviour, which usually means at least one clean quarter end and often a year end for a full core.
When is a parallel run costing more than it proves?
When differences have plateaued at a low level for weeks and the remaining ones are understood. Extending beyond that consumes capacity and window pressure for diminishing evidence.
What should cutover criteria contain?
Clean comparison across required calendar events, zero unexplained differences, performance within window, operations rehearsed, and a tested rollback path.



