Define the evidence needed before making a legacy decision

When a business decides to move a legacy system off ageing servers or an unsupported platform, two terms come up repeatedly: lift and shift, and refactoring. They describe fundamentally different approaches, and choosing the wrong one can waste budget and delay the benefits the business actually needs.

Lift and shift means taking the existing application—its code, database structure, and configuration—and deploying it onto new infrastructure with minimal changes. The software itself stays essentially the same; only the environment around it changes. A system running on a physical server in a cupboard might be moved to a cloud virtual machine, or an application tied to an old version of a database engine might be moved to a managed hosting service running that same version.

Refactoring means changing the internal structure of the code without altering what the system does for its users. The external behaviour stays the same, but the code is reorganised to be easier to maintain, faster, or compatible with modern platforms. In practice, refactoring a legacy application often involves breaking a monolithic codebase into clearer modules, updating libraries, replacing deprecated functions, and adjusting the database schema where the old design creates ongoing problems.

The distinction matters because lift and shift addresses where the software runs, while refactoring addresses how the software is built. A business whose primary problem is a server that is being decommissioned may solve it with a lift and shift. A business whose primary problem is that every small change takes weeks and breaks unrelated features will not solve anything by moving the same code to a new server.

These approaches also sit on a spectrum. Some projects involve lifting an application to a new environment and then refactoring specific modules once the immediate infrastructure risk is removed. Others involve partial refactoring before the move, where certain components are rewritten to be compatible with the target platform. Understanding where a specific project falls on that spectrum is more useful than treating the two options as purely binary.

When lift and shift is the more sensible path

Lift and shift is most appropriate when the application works correctly, the codebase is stable, and the driving problem is infrastructure-related. Common scenarios include:

  • The current hosting environment is being shut down or is no longer supported by the vendor.
  • The business needs to meet a compliance requirement that dictates where data is stored or how infrastructure is managed.
  • The application is rarely changed and the business simply needs it to keep running reliably.
  • There is a hard deadline—such as a lease ending or a support contract expiring—and there is no time for a code-level project.

In these situations, lift and shift delivers a clear outcome: the system continues to function in a supported environment. The total cost is usually lower and the timeline shorter because the scope is limited to infrastructure and deployment, not code changes.

When refactoring is the more sensible path

Refactoring becomes the better option when the problems are rooted in the code itself rather than the infrastructure. Signs that refactoring is likely needed include:

  • Changes to business rules or workflows consistently introduce defects in unrelated parts of the system.
  • Only one or two people understand the codebase, creating a key-person risk.
  • The technology stack is so outdated that finding developers willing to work on it is difficult.
  • The system cannot integrate with newer tools or services the business now relies on.
  • Performance issues persist regardless of how much hardware is thrown at them.

Refactoring does not mean rewriting everything from scratch. A scoped refactoring project might target the most problematic modules, update the data access layer, or separate the background processing from the user-facing application. The key is that the scope is defined by specific, measurable problems rather than a vague desire to "modernise."

Comparing the two on practical dimensions

Dimension Lift and Shift Refactoring
Primary risk Infrastructure misconfiguration during migration Unintended changes to business logic
Testing focus Environment parity, data integrity, performance in new setup Behavioural equivalence, regression across affected modules
Typical timeline Weeks to a few months Months, depending on scope
Ongoing benefit Supported infrastructure, potential reliability gains Easier maintenance, faster future changes, reduced defect rate
Key dependency Accurate documentation of current environment Clear understanding of current business rules and edge cases

Mistaking a lift and shift for modernisation

The most common error is describing a lift and shift as a modernisation project. Moving an application built fifteen years ago onto a cloud server does not make it a modern application. It still carries the same technical debt, the same maintenance difficulties, and the same constraints on future development. If the business case presented to stakeholders promises improved agility or lower maintenance costs, a pure lift and shift will not deliver those benefits. Be precise about what the project will and will not change.

Refactoring without clear boundaries

Refactoring projects drift when the scope is not tied to specific problems. A brief that says "improve the codebase" gives no basis for deciding when the work is done. Before starting, document which modules will be touched, what problems each change is expected to solve, and how you will verify that the system still behaves correctly afterwards. Without these boundaries, refactoring gradually becomes a rewrite, with the associated cost and risk but without the controlled approach a deliberate rebuild would have.

Assuming the code is worth saving

Not all legacy code is a candidate for refactoring. If the codebase has been patched extensively over many years with inconsistent patterns, no tests, and little documentation, the cost of refactoring may approach or exceed the cost of a controlled replacement. An honest assessment of code quality should happen before committing to either path. This assessment does not need to be exhaustive—a focused review of the most critical and most frequently changed modules is usually enough to indicate whether refactoring is viable.

Overlooking data migration within a lift and shift

Even a straightforward lift and shift involves moving data, and data migration carries its own risks. Database versions may differ slightly, character encodings may not match, and scheduled jobs or triggers may behave differently on the new platform. Verify that a full data migration has been tested in a non-production environment before the cutover, and confirm that record counts, checksums, or sample spot-checks pass after the move.

Key checks before committing to either approach

  • Is the problem infrastructure or code? If the system works well and only the hosting is the issue, lift and shift is sufficient. If the system is difficult to change, slow, or fragile, refactoring or replacement should be on the table.
  • What is the actual deadline? A genuine hard deadline narrows the options. An artificial deadline driven by a preference for speed should be challenged if it forces a lift and shift that does not solve the underlying problem.
  • Is there a test baseline? Both approaches require confidence that nothing is broken during the move. If there are no existing tests and no clear record of current behaviour, building that baseline becomes the first phase of work regardless of which path is chosen.
  • What does the supplier actually mean by "refactor"? The term is used loosely. Ask specifically which modules will change, what the acceptance criteria are for each, and how behavioural equivalence will be verified. Get this in writing before work begins.
  • What is the exit position after this project? A lift and shift should leave the business in a position where future refactoring or replacement is easier, not harder. A refactoring should leave the codebase in a state that the internal team or a new supplier can work with. If either approach leaves the business more dependent on the current supplier than before, the terms need to be examined.

Neither lift and shift nor refactoring is inherently the right choice. The decision follows from a clear diagnosis of what is actually wrong with the current system, what the business needs the system to do in the near term, and what constraints—time, budget, risk tolerance—govern the project. Where the diagnosis is unclear, investing in a focused audit before committing to either path usually costs less than choosing the wrong approach and correcting it later.