The most common mistake in modernization planning is treating the system as the unit of decision. Almost no real system deserves a single verdict. Different capabilities inside it have different value, different decay and different coupling — and they deserve different answers.
Separate two independent questions
For each capability, ask them separately and the answer usually presents itself:
- How valuable is the behaviour? Does the business depend on it, does it differentiate you, and does the roadmap want to change it?
- How costly is the current implementation? What does it cost to change safely, to operate, to staff and to secure?
| Behaviour value | Implementation cost | Usual answer |
|---|---|---|
| High | Low | Retain — and resist the urge to touch it |
| High | Moderate | Refactor in place; improve boundaries and tests |
| High | High, but logic is sound | Re-platform — preserve the logic, change the substrate |
| High | High, and logic no longer matches the business | Replace, capability by capability |
| Low | Any | Retire it, or buy it — building is rarely justified |
Retain is a real answer
A stable component that does its job, changes rarely and costs little to run does not need modernising because it is old. Age is not a defect. Spending the budget where change is actually blocked is a better use of it, and "we deliberately left this alone" is a sign of a considered plan.
Re-platform: change the substrate, keep the logic
Where the domain logic is sound but the runtime, database or hosting is the constraint, moving the same behaviour onto a modern platform can unlock most of the operational benefit at a fraction of the risk of a rewrite. The discipline that makes it work is refusing to redesign behaviour at the same time — that combination is what turns a contained migration into an open-ended programme.
Refactor: improve from the inside
Refactoring earns its place when the system is worth keeping but hard to change safely. Establish characterisation tests that capture existing behaviour — including the behaviour nobody intended — before changing structure. Without them, refactoring is just editing.
Replace: only where the business has moved on
Replacement is justified when the implementation encodes a business model you no longer operate. Even then, replace capability by capability behind a routing layer rather than as a single event. The goal is a sequence of small, reversible replacements, not one large irreversible one.
Buy versus build
For low-differentiation capabilities — authentication, billing mechanics, notification delivery, document generation — a mature product is usually cheaper than the fully loaded cost of building and maintaining your own. Build where the capability is genuinely part of why customers choose you.
