Legacy System Modernisation: Choosing What to Change and How to Get There

A practical approach to improving an established system while preserving the work the organisation depends on.

  • Architecture
  • Legacy Systems
  • Delivery
Legacy System Modernisation: Choosing What to Change and How to Get There

Key takeaways

  • Start with a measurable constraint, such as unsupported infrastructure, slow changes, or difficult recovery.
  • Rehosting, replatforming, refactoring, rearchitecting, rebuilding, and replacement solve different problems.
  • Incremental migration needs explicit decisions about routing, data ownership, coexistence, and rollback.
  • Modernisation includes operational ownership and retirement of the old capability, alongside delivery of its successor.

An invoicing application still produces the documents customers expect. It also takes several weeks to change a pricing rule, depends on a runtime the team struggles to support, and needs one particular engineer whenever the overnight job fails. Replacing it sounds attractive until someone asks how it handles credits for customers on older agreements.

The answer is buried in code, a spreadsheet, and the memory of the accounts team. Those details are part of the system the organisation relies on, even if they never appeared in its architecture diagram. Modernising the application requires discovering that behaviour while deciding which constraints are worth removing first.

Name the Problem Before Choosing the Destination

The age of an application is a weak basis for deciding how much to change. An older system may be stable and well understood. A newer one may already be difficult to deploy, recover, or modify. The useful starting point is the work the organisation cannot do reliably with the system it has.

For the invoicing application, the team could separate three concerns: keeping the runtime supported, reducing the effort required for pricing changes, and making overnight failures recoverable without one person's intervention. Each has a different measure of success and may need a different intervention.

Establish a baseline before selecting an architecture. Record how a representative change moves through development and review, how recovery is performed, and where manual work occurs. Include the time spent investigating failures and correcting invoices. A project that reduces hosting costs while increasing reconciliation work may have moved the expense to another team.

Understand the Behaviour People Depend On

Begin with a map of the application and its consumers: user screens, scheduled jobs, exports, direct database readers, identity systems, and operational procedures. Ask the people doing the work which exceptions they handle and which steps happen outside the software.

For invoicing, representative cases should include ordinary charges, credits, cancelled accounts, and historical agreements. Capture observed results in tests where practical. These tests document what the system does today; the business still needs to decide whether that behaviour should be preserved or corrected.

That distinction prevents an existing defect from becoming a permanent requirement. It also makes intentional changes reviewable. If the new implementation rounds a value differently, the team should be able to explain whether this is a correction, an agreed policy change, or an error in the migration.

Choose the Intervention for the Constraint

Microsoft's cloud migration strategy guidance distinguishes several approaches, including retaining and retiring workloads. These categories are useful vocabulary, although terminology varies between frameworks. They describe choices that can be combined across an application.

ApproachMain changeQuestion to resolve
RehostMove the existing application to different infrastructure.Does this address the immediate infrastructure constraint?
ReplatformChange a hosting or platform component with limited application changes.Are its behaviour and operational requirements compatible?
RefactorImprove internal code structure.Which changes will make the next modification safer?
RearchitectChange major boundaries or interactions.Does the new structure justify its operating cost?
RebuildImplement the capability again.How will required behaviour be discovered and verified?
ReplaceAdopt another product for the capability.Can the organisation use it without recreating extensive custom logic?
Retain or retireKeep a workload deliberately, or remove it when no longer needed.Is its continuing cost justified by an active need?

In the more precise software-design sense, refactoring preserves observable behaviour while improving internal structure. A project that also changes pricing rules should distinguish those functional changes from the restructuring, so reviewers can assess each against the right evidence.

For the invoicing team, moving to supported infrastructure might address an urgent maintenance problem while a later refactor isolates pricing logic. Neither step requires distributing the application across multiple services. A separate service becomes useful when its boundary supports a concrete need, such as independent ownership or scaling, and the team can operate the resulting network dependency.

Replace a Capability Through a Clear Boundary

An incremental migration can begin by directing one capability to a new implementation while the existing application continues handling the rest. Microsoft's Strangler Fig pattern describes using an intermediary to route requests as functionality is gradually replaced. The routing layer itself needs attention because it can become a bottleneck or a point of failure.

For invoicing, a first slice might be retrieving issued invoices. A stable interface could let the customer portal use that capability without knowing which implementation supplies it. Contract tests can help preserve the portal's expectations as the implementation changes.

The team should still map callers that bypass the interface. A reporting job reading tables directly will not automatically follow the new route. Incremental replacement is only as complete as the team's understanding of the ways the old capability is used.

Decide Who Owns Writes During Coexistence

Reading historical invoices is a different migration problem from creating new ones. Once two implementations can change the same business records, the team needs explicit rules about which system is authoritative and how the other learns about those changes.

Writing independently to both databases can leave them inconsistent if one write succeeds and the other fails. A migration design needs a recovery mechanism for that situation, whether it uses a single writer, replicated changes, or a durable process for transferring updates. The right choice depends on how current each view must be and what inconsistencies the business can tolerate.

For this application, a reconciliation plan should examine invoice identifiers, monetary values, status transitions, and relationships to credits. Matching row counts alone would not show that each credit still belongs to the correct invoice. The team also needs to decide how records changed during an initial data copy will reach the destination before the new system takes over.

Treat Rollback as a Data Decision

A deployment switch can return requests to an older application. It cannot automatically make that application understand records written in a new format. Before moving writes, establish what returning to the old system would require and which changes would make that return impractical.

The invoicing team should rehearse the transition with representative data. That rehearsal needs to include reconciliation, a recovery attempt, and the actions expected from accounts staff if processing pauses. Define the evidence that permits the cutover to continue and the conditions that require it to stop.

Comparing old and new calculations before accepting the new result can provide useful evidence. Such comparisons need controlled side effects: running two implementations must not send duplicate invoices or collect payment twice. Disagreement should lead to investigation, with enough context retained to explain the result.

Give the New System an Operational Owner

A managed database can reduce some maintenance work while leaving decisions about access, recovery, capacity, and cost with the team. Moving an application changes the environment in which those responsibilities are exercised. Someone needs to understand the resulting arrangement and have the access required to support it.

Clear roles and escalation routes belong in the delivery plan. The new invoice service needs tested recovery procedures, useful alerts, and a handover that allows more than one engineer to respond. Otherwise the project may reproduce the original dependency on a single person using a different technology stack.

New interfaces also deserve a review of permissions and data access. An internal operation exposed to another application needs an explicit account of who may invoke it and which records they may see. The human and operational parts of security remain relevant after the infrastructure has changed.

Finish by Removing the Old Dependency

Coexistence has a cost: two deployments, two sets of operational knowledge, and additional reconciliation. Each migrated capability needs retirement criteria that identify remaining consumers, scheduled work, historical access requirements, and the components that can eventually be switched off.

For invoicing, completion might mean the new implementation handles the agreed cases, recovery has been demonstrated, all known consumers use the supported interface, and accounts staff can retrieve historical records without the old application. Only then can the team remove the redundant jobs, access paths, and infrastructure.

Return to the original measures when evaluating the result. Can pricing changes be delivered with less uncertainty? Can another engineer recover the overnight process? Has the unsupported runtime actually disappeared? Those outcomes give the organisation a defensible basis for the next investment, while leaving it with a system it can understand and continue to change.

Modernisation becomes credible when the organisation can name the constraint it removed and show that the business still works without the component it retired.
Julia Norton

© 2026 Julia Norton.