You've inherited a system nobody fully understands. The original architects left two years ago. Documentation exists, but it describes the application as it was in 2019, not as it runs today. Now leadership wants it moved to the cloud by Q3.
Application migration is the process of moving an application from one environment to another: on-prem to cloud, one data center to another, or legacy infrastructure to a modern platform. It covers everything from rehosting to full re-architecture. And it is almost never the clean technical exercise that vendor slide decks suggest. It's a multi-phase operational problem involving dependency mapping, cutover risk, data architecture decisions, cost modeling, and team capability gaps that surface at the worst possible time.
What you'll find here:
- A working definition of application migration and when it actually makes sense
- How to choose between rehost, replatform, and refactor, with trade-offs rather than just definitions
- A step-by-step application migration process from discovery through post-cutover validation
- Concrete patterns for legacy monolith decomposition (strangler fig, CDC, shared database splitting)
- An honest look at the most common application migration challenges and how to avoid them
What is application migration?
Application migration moves an application, including its code, runtime, dependencies, configuration, and data, from one computing environment to another. That move could be from an on-prem data center to public cloud, between cloud providers, or from legacy infrastructure to a modern platform.
This differs from data migration, which moves only the data layer. Application migration is a specific technical and operational undertaking that can involve rehosting (moving as-is), replatforming (making targeted modifications), refactoring (re-architecting for the target environment), or decomposing a monolith into separate services.
Types of application migration: the 6 R's (and when each applies)
Most migration planning frameworks classify applications using the "6 R's." Here's what each means in practice, along with the trade-off vendors skip.
Rehost (lift-and-shift) moves the application as-is to new infrastructure. Fastest time-to-cloud, but you inherit every architectural problem and likely pay more for compute that isn't right-sized for cloud pricing models.
Replatform (lift-tinker-and-shift) makes targeted modifications during the move, such as switching to a managed database. Moderate effort with real gains, but requires enough understanding of the application to know what's safe to change.
Refactor or re-architect rebuilds parts or all of the application to use the target environment. Highest long-term ROI potential, highest effort and risk. Teams underestimate both.
Repurchase replaces the application with a SaaS or commercial product. Good for commodity workloads. Bad when teams treat it as simple and skip data migration planning.
Retire turns the application off. More applications qualify for this than most organizations admit.
Retain leaves the application where it is for now.
The 2024 Accelerate State of DevOps Report (DORA, 2024) found that migrating to cloud without adopting its inherent flexibility can produce worse outcomes than staying on-prem. Rehosting without right-sizing, auto-scaling, or adopting managed services means paying cloud prices for on-prem architecture.
Use this decision heuristic: if the application is stable, low-business-value, and scheduled for retirement within 18 months, Retain or Retire. If it's core with growing demand, Refactor or Re-architect. If speed-to-cloud matters and architecture debt is manageable, Replatform.
| Strategy | Also Known As | Migration Effort / Risk | Long-Term Optimization Value | Key Trade-Off |
|---|---|---|---|---|
| Rehost | Lift-and-shift | Low | Low | Fastest to cloud; inherits all architectural debt and cloud pricing inefficiencies |
| Replatform | Lift-tinker-and-shift | Medium | Medium | Real gains with moderate effort; requires enough app knowledge to know what's safe to change |
| Refactor / Re-architect | Re-architect | High | High | Highest long-term ROI potential; teams consistently underestimate effort and risk |
| Repurchase | Drop-and-shop | Medium | Medium | Good for commodity workloads; risky when data migration planning is skipped |
| Retire | Decommission | Low | Low | Most cost-effective option; more applications qualify than organizations admit |
| Retain | Revisit | Low | Low | Valid short-term decision; avoid using it as a permanent avoidance strategy |
Application migration process: step-by-step
Step 1: discovery and dependency mapping
Every failed migration has the same origin story: the team didn't know what was actually running.
- Use automated discovery tools to inventory all running services, APIs, data flows, and integration points. Don't rely on architecture diagrams that may be years out of date.
- Collect at least 30 days of utilization data before any migration decision. Shorter windows miss batch jobs, month-end processing, and seasonal traffic patterns.
- Document inter-service dependencies, shared databases, and integration touchpoints. Pay special attention to applications sharing a database.
- Flag undocumented workflows and shadow IT as risk items, not exceptions. They will break during cutover if ignored.
- Output: a dependency map and risk-tiered application inventory.
Step 2: assess and classify applications (apply the 6 R's)
With the inventory in hand, score each application on four dimensions: business criticality, technical debt, migration complexity, and cloud-native fit.
- Assign a migration strategy (one of the 6 R's) per application. Validate each with both engineering and business stakeholders.
- Conduct financial and TCO assessment alongside technical assessment. Cloud economics must be an architecture input.
- Identify shared databases early. Any application sharing a database with another migration candidate is high-complexity. This single factor derails migration timelines more often than any other technical issue we see.
- Flag applications with unclear ownership or missing business sponsors as escalation items.
Step 3: build the application migration plan
Planning turns the inventory into a sequenced execution roadmap.
- Define migration waves. Start with two or three non-critical, low-dependency applications as a pilot. The pilot teaches your team more about the target environment than any amount of pre-reading.
- Assign a migration architect accountable for cross-wave consistency in architecture decisions, naming conventions, networking patterns, and security controls.
- Set performance baselines (latency, error rates, throughput) before migration begins. These become your rollback triggers.
- Align stakeholders on acceptable downtime windows, rollback criteria, and escalation paths in writing. Verbal agreements evaporate when an incident hits at 2 AM.
- Output: a phased migration roadmap with wave sequencing, owners, and go/no-go criteria.
Planning a migration? Start with a discovery assessment.
Techstack's cloud migration team maps dependencies, sizes complexity, and builds wave-sequenced migration plans before any workload moves. No surprises at cutover.
Book a discovery callStep 4: design the target architecture
Architecture design must happen before infrastructure provisioning.
- For rehost: Map existing compute, storage, and networking to cloud equivalents. Document every difference, even minor ones.
- For replatform and refactor: Define the target state explicitly. A sensible AWS starting point: ECS on Fargate for request/response workloads, Lambda for event handlers, EKS only where Kubernetes is required.
- For legacy monolith migrations: Choose a decomposition pattern before writing infrastructure code. The pattern drives networking, data replication, and observability requirements.
- Address security and compliance requirements during design. Adding them after migration creates rework and audit risk.
- Define your observability stack (logging, tracing, alerting) as part of the target architecture.
Step 5: execute migration by wave
Each wave follows a repeatable sequence to prevent ad-hoc decision-making that causes outages.
- Pre-migration validation confirms the source environment matches the dependency map and replication is healthy.
- Start continuous data replication (AWS DMS or equivalent) well before cutover. Validate daily.
- Deploy the application in the target environment. Run functional, performance, security, and smoke tests before any traffic moves.
- Cut over during a low-traffic window using DNS or load-balancer-based routing (ALB rules, API Gateway). Phased traffic shifting (10% to 50% to 100%) reduces blast radius.
- Keep the on-prem environment live as a rollback target for one to two weeks. Define rollback triggers explicitly: error rate thresholds, latency degradation percentages, data inconsistency signals.
Step 6: post-migration validation and cost review
Migration doesn't end at cutover.
- Compare live metrics against pre-migration baselines. Investigate any regression immediately.
- Review cloud cost against TCO projections at 30 and 90 days. Right-size compute based on actual usage.
- Decommission on-prem resources only after the extended validation period passes with no rollback triggers hit.
- Conduct a migration retrospective: what broke, what slowed the wave, what tooling gaps appeared. Use findings to improve the next wave.
- Begin the next wave only after retrospective findings are addressed.

Legacy application migration: handling monoliths and shared databases
This is where most generic guides stop being useful. Legacy monoliths often have no complete dependency documentation, shared databases serving multiple workloads, and tightly coupled business logic not designed for extraction.
The strangler fig pattern is the most battle-tested approach for incremental monolith decomposition. A routing layer (facade or proxy) sits in front of the existing monolith. New or refactored functionality routes to new services. Old functionality stays in the monolith until extracted. The monolith shrinks over time. You never attempt a big-bang rewrite.
Branch by abstraction works when you can't put a network proxy in front of the monolith. Create an abstraction layer in the codebase, implement new behavior behind it, switch traffic at the code level, then remove old code. AWS Migration Hub Refactor Spaces supports this pattern (AWS .NET Modernization Blog, 2023).
The shared database problem is the hardest part. Extracting services that read and write to the same database requires:
- Identify bounded contexts through domain-driven design or event storming with domain experts.
- Introduce read replicas to reduce primary database load.
- Set up change data capture (CDC) to stream change logs to Kafka.
- Build an anti-corruption layer translating database changes into domain events.
- Give each service its own schema progressively, one bounded context at a time.
This process takes months.
A modular monolith is a valid end-state. If your team lacks distributed systems experience or scale doesn't justify microservices, a well-structured modular monolith with clear domain boundaries beats a premature microservices architecture. Microservices increase operational complexity that unprepared teams cannot manage.
Techstack's 9-dots menu pattern demonstrates this approach: multiple monoliths were unified through an integration layer without rewriting each system, keeping individual monoliths stable while creating a coherent user experience.
Application migration checklist
Pre-migration
- Automated discovery inventory completed
- 30+ days of utilization data collected
- Dependency map created and reviewed with engineering and business stakeholders
- Applications classified by migration strategy (6 R's)
- TCO and financial assessment completed
- Security and compliance requirements documented
- Performance baselines established (latency, error rate, throughput)
- Rollback criteria and triggers defined with explicit thresholds
- Migration architect assigned
- Stakeholder alignment on downtime tolerance confirmed in writing
During migration (per wave)
- Pilot wave (2-3 non-critical applications) completed and retrospected
- Continuous data replication active and validated daily
- Target environment smoke tests passing
- Functional, performance, and security tests completed
- Cutover window scheduled during low-traffic period
- On-prem environment kept live as rollback target
- DNS or load-balancer cutover tested in staging
Post-migration
- Post-cutover metrics compared to pre-migration baselines
- Cloud cost vs. TCO projection reviewed at 30 and 90 days
- On-prem decommission delayed until extended validation period passes
- Retrospective conducted and findings documented
- Next wave sequenced based on previous wave's lessons
Application migration challenges (and how to handle them)
Legacy complexity and missing documentation
Say you're a VP of Engineering at a 500-person company running a 12-year-old order management system. The original team is gone. The wiki has outdated documentation. Three undocumented batch jobs run nightly and feed data to finance.
This is normal. Treat documentation gaps as a discovery task, not a blocker. Use automated tooling to surface runtime dependencies. Build a living dependency register during discovery and update it as each wave reveals something new.
Lift-and-shift cost and performance regressions
Cloud is not a data center with different billing. Right-sizing, reserved instances, auto-scaling, and managed services cannot be easily retrofitted after a naive lift-and-shift.
The DORA 2024 report shows cloud without elasticity can produce worse outcomes than staying on-prem. Use this as a forcing function for architecture review before migration (DORA, 2024).
Shared databases and tight coupling
Don't split a shared database before bounded contexts are clearly defined. You'll cut in the wrong places and create harder integration problems.
Use CDC and anti-corruption layers to decouple incrementally. Full schema separation can take months and should run alongside the first wave, not block it.
Cutover risk and downtime
Every cutover needs a tested rollback plan with explicit triggers. "We'll figure it out if something goes wrong" is not a plan.
Phased traffic shifting (10% to 50% to 100%) reduces blast radius. Use ALB weighted routing or API Gateway canary deployments. Techstack's high-performance fundraising platform on AWS Lambda demonstrates architecture designed for low-downtime deployment and reliable scaling.
Team skill gaps
Identify capability gaps during planning, not mid-wave.
Consider external support for the first one or two waves. Internal teams build expertise by doing the work alongside experienced practitioners. If the team isn't ready for microservices, a modular monolith is a better intermediate target.
Facing a legacy migration your team hasn't done before?
Techstack runs discovery, plans waves, and executes alongside your engineers so they own the system after handoff.
Let's talkWhen application migration isn't the right answer
Some applications should be retired. Some should be replaced with SaaS. Some should stay where they are.
Signs that migration may not be right: the application is scheduled for retirement within 18 months; lift-and-shift TCO is higher than current on-prem cost without refactoring justifying it; the team lacks skills and no external support budget exists; compliance requirements make cloud more complex than on-prem without proportional business benefit.
Migration is a means to an outcome: better scalability, higher reliability, lower cost at scale. If the outcome isn't achievable given current architecture and team, the plan needs to change before migration begins.
How Techstack approaches application migration
Techstack's cloud migration consulting is built around discovery before commitment and architecture decisions serving the team's actual capabilities.
Two recent examples:
Multiple legacy monoliths needed to operate as a unified product without a full rewrite. Techstack designed an integration layer using the 9-dots menu pattern that connected the systems into a single ecosystem. The monoliths stayed stable. User experience became coherent.
A fundraising platform required high throughput under unpredictable traffic spikes. Techstack built the system on AWS Lambda, delivering serverless architecture that scaled with demand.
The methodology follows this structure: discovery-first assessment, wave-based execution, architecture decisions driven by application and team rather than preferred vendor stack, and explicit rollback planning in every wave.