|7 min read

Enterprise Migration: Lift-and-Shift vs. Refactor

When to move workloads to the cloud as-is and when to redesign them, learned from real enterprise migration decisions

Four months into my role as an Enterprise Cloud Architect, I have been involved in enough migration planning sessions to notice a recurring argument. It goes something like this:

One group says: "Let us just move the application to EC2 as-is. It works fine. We will optimize later."

Another group says: "If we are going to move to the cloud, we should do it right. Refactor the application to be cloud-native. Use managed services. Design for elasticity."

Both groups are right, and both groups are wrong. The answer is not one or the other. The answer is knowing which approach to use for which workload, and having a framework for making that decision.

The Migration Strategies

AWS talks about the "6 Rs" of migration: Rehost, Replatform, Refactor, Repurchase, Retire, and Retain. In practice, most enterprise migration conversations boil down to two main strategies:

Lift-and-shift (Rehost). Take the application running on physical or virtual servers in your data center and move it to EC2 instances in AWS. Same operating system, same application code, same architecture. You are essentially renting servers from AWS instead of running your own.

Refactor (Re-architect). Redesign the application to take advantage of cloud-native services. Break the monolith into microservices. Replace self-managed databases with RDS or DynamoDB. Use SQS for message queuing instead of RabbitMQ on EC2. Use Lambda for event-driven workloads. Design for horizontal scaling and failure.

Between these extremes is Replatforming, which I think of as "lift-and-shift with optimizations." Move to EC2 but switch from a self-managed database to RDS. Keep the monolith but put it behind an Application Load Balancer. Small changes that reduce operational burden without requiring a full rewrite.

When to Lift-and-Shift

Lift-and-shift gets a bad reputation in cloud architecture circles. It is often dismissed as a lazy approach that fails to capture the real benefits of cloud computing. But there are legitimate scenarios where it is the right call:

Data center exit deadline. If your lease is expiring or your hardware is end-of-life, you may not have time for a full refactoring effort. Moving to EC2 quickly gets you out of the data center. You can optimize once you are in the cloud.

Stable, low-risk workloads. An application that has been running reliably for years, requires minimal changes, and does not need elastic scaling is a prime candidate for lift-and-shift. The risk of a refactoring effort (introducing new bugs, missing edge cases, breaking integrations) may not be justified.

Vendor-supported applications. Commercial off-the-shelf software that the vendor supports on specific operating systems and configurations should typically be lifted-and-shifted. Refactoring someone else's software is not an option, and deviating from supported configurations voids your support agreement.

Quick wins for organizational buy-in. Sometimes you need to demonstrate that cloud migration works before the organization will invest in larger efforts. Lifting and shifting a few workloads quickly builds confidence and momentum.

The key insight about lift-and-shift is that it is not a permanent state. It is a stepping stone. You move to the cloud, stabilize the workload, and then incrementally modernize. The migration and the modernization are separate projects with separate timelines.

When to Refactor

Refactoring makes sense when the benefits of cloud-native architecture are significant enough to justify the investment:

Variable traffic patterns. If your workload has significant peaks and valleys, a cloud-native architecture that scales horizontally can save substantial money compared to provisioning for peak load 24/7. An e-commerce application that sees 10x traffic during holiday sales is a classic example.

Rapid development velocity. If the application is under active development with frequent deployments, a microservices architecture with independent deployment pipelines can dramatically improve team velocity. But only if you have the organizational maturity to manage distributed systems.

Operational burden. If a significant portion of your team's time is spent managing infrastructure (patching databases, managing message brokers, tuning JVMs), replacing that infrastructure with managed services frees engineering time for feature development.

Technical debt. If the application is already struggling under its own weight, poorly structured, hard to test, difficult to deploy, a migration is a natural forcing function for addressing technical debt. Moving a broken architecture to the cloud just gives you a broken architecture in the cloud.

The Decision Framework

We developed a simple scoring framework for evaluating each workload. It is not perfect, but it provides a structured starting point for conversations:

Business criticality. How important is this application to revenue and operations? High-criticality applications warrant more investment in architecture.

Rate of change. How frequently is the application modified? Rapidly evolving applications benefit more from cloud-native architectures. Stable applications can be lifted and shifted.

Scalability requirements. Does the application need to scale elastically? If it runs at constant load, the scaling benefits of cloud-native architecture are less relevant.

Team capability. Does the team have experience with cloud-native patterns? Refactoring to microservices requires skills in distributed systems, container orchestration, and service mesh patterns. If the team does not have these skills, the refactoring effort will be slower and riskier.

Dependency complexity. How many other systems depend on this application? Refactoring a core system that dozens of other applications integrate with is significantly riskier than refactoring a standalone application.

Each factor gets a score, and the aggregate helps determine the migration strategy. High business criticality, high rate of change, high scalability needs, and a capable team point toward refactoring. Low scores across the board point toward lift-and-shift.

The Mistakes I Have Seen

Refactoring everything. The engineering team gets excited about microservices and Kubernetes and wants to refactor everything at once. This leads to massive projects that take forever, cost more than projected, and delay the data center exit. Not every application needs to be cloud-native. Some applications just need to run on a server.

Lifting and shifting everything. The operations team is risk-averse and wants to minimize change. Everything gets moved to EC2 with no optimization. The result is a cloud bill that is higher than the data center costs, because you are paying on-demand prices for infrastructure that was previously amortized. Without any optimization, the "cloud is expensive" narrative takes hold and erodes organizational support for the migration.

Ignoring the database. Teams focus on the application tier and treat the database as an afterthought. But the database is often the hardest part of any migration. Moving from Oracle on-premises to Oracle on EC2 is straightforward but expensive. Moving to RDS reduces operational burden but requires careful testing. Moving to a different database engine entirely (say, from Oracle to PostgreSQL) is a major undertaking that should be planned as its own project.

Underestimating network complexity. On-premises applications communicate over fast, reliable, low-latency networks. Moving to the cloud introduces new network variables: VPN or Direct Connect latency, inter-region communication, VPC peering limits, DNS resolution differences. Applications that are chatty between tiers suffer the most.

A Pragmatic Approach

After four months of migration planning, my perspective has settled into something pragmatic: start with lift-and-shift for speed and momentum, but design the landing zone for cloud-native evolution.

This means:

  • Set up your AWS Organizations, networking, and security foundations as if you were going to run cloud-native workloads (because eventually you will)
  • Migrate stable, low-risk workloads first via lift-and-shift to build experience and confidence
  • Identify two or three high-value applications for pilot refactoring efforts
  • Use the pilot results to build a business case for broader modernization
  • Accept that some workloads will live on EC2 for years, and that is fine

The worst outcome is not choosing the wrong migration strategy. The worst outcome is spending so long debating the strategy that you never start migrating. The cloud is not a destination; it is a capability. The sooner your organization starts using that capability, even imperfectly, the sooner you learn what works and what does not.

Move first. Optimize continuously. That is the pattern.

Share: