A rebuild is a discontinuity. A live migration is a discipline. The difference shows up in the P&L six months later, and in the runbook eighteen months later.
The rebuild fallacy.
A team is asked to modernise a platform. They look at the legacy code, judge it irredeemable, and propose a rebuild. The new system will be cleaner, faster, fully observable. Nine months later the rebuild is 70% complete and the legacy system has accreted six new features the rebuild does not yet handle. Cutover slips. Confidence drains. The platform is now two platforms, the one earning revenue and the one consuming engineering capacity, and neither team trusts the other.
We have inherited two of these. In both cases the rebuild was abandoned and the legacy system was modernised in place, on the same hardware, with the same database, while it served production traffic. That is not a heroic act. It is the normal state of a serious platform.
The discipline: small, reversible, observable.
Every modernisation step we ship satisfies three properties. It is small enough to review in a single sitting. It is reversible by a single feature flag or a single deploy. It is observable: the metric that proves it worked is in place before the change ships, not after.
Concretely, on the live .NET 4.8 → .NET 10 migration that anchors our practice, every service crosses the boundary in this order: parallel-run on the new runtime behind a percentage shadow; A/B compare on the operational metrics that matter to the business (latency, error budget, settlement reconciliation); ramp from 1% to 100% over a week, with the previous binary still hot; deprecate the previous binary only after a full quarter-end has passed on the new one. No exceptions. No "this one is simpler, we can skip the shadow." Skipping the shadow is how you find out at 02:30 that the new runtime serialises decimals with one more place of precision than the gateway expected.
What the customer feels.
Nothing. That is the point. Customers do not buy modernisation; they buy the platform that hosts their commerce, their payments, their settlement. The migration is invisible to them, and that invisibility is the proof that the engineering is precise.
When a rebuild is correct.
Rarely. The hard cases: a runtime that has lost vendor support and is mathematically unmovable forward (e.g. a deprecated language version with no compiler upgrade path); a data model so wrong that every new feature pays a tax to it; a regulatory change that invalidates the old design end-to-end. In all three cases the rebuild is still preceded by a modernisation that buys time. The rebuild itself is a separable later step, not the answer to "we want it cleaner."
The brief that survives this rule.
When we engage on a modernisation, the first artefact is not a design document. It is a list of the next twelve reversible transitions, in dependency order, with the metric that gates each one. Anything that cannot be expressed that way is not yet ready to ship.
The platform never stops earning. The discipline is to keep it that way while replacing every part beneath it.