Why legacy migration is hard
Legacy systems survive because they work. They handle edge cases nobody documented, enforce business rules nobody remembers writing, and support workflows that the organisation has built around over years or decades.
The risk of migration isn't building the new thing. It's losing the accumulated knowledge embedded in the old thing. Hidden business logic, undocumented integrations, workarounds that became processes. Every migration project discovers these surprises, and the ones that succeed are the ones that planned for them.
Migration strategies
There are three main approaches. Each trades off risk against speed.
Strangler fig pattern
Named after the fig tree that gradually wraps around and replaces its host. You build new functionality alongside the old system and route traffic to it incrementally. Over time, more and more of the old system gets replaced until there's nothing left.
How it works
- Identify a self-contained module or function in the legacy system.
- Build the replacement in the new system.
- Route traffic/requests for that function to the new system.
- Verify it works correctly in production.
- Repeat with the next module.
Advantages
- Low risk. You migrate piece by piece, and you can roll back any individual piece.
- The old system keeps running throughout. No "dark period" where nothing works.
- You learn as you go. Each migrated module teaches you something about the next one.
Disadvantages
- Slower. A full migration via strangler fig can take 12-24 months for a complex system.
- You maintain two systems simultaneously, which means extra operational overhead.
- The boundary between old and new needs careful management, especially for shared data.
Parallel run
Build the entire new system, then run both systems simultaneously for a period. Compare outputs to verify the new system behaves correctly before switching over.
When it works
Parallel runs are good for systems where correctness is critical and verifiable: financial systems, payroll, billing engines. You can compare the outputs of both systems and investigate any discrepancies before committing to the switch.
When it doesn't
Parallel runs are expensive. You're paying for two full systems plus the effort to compare their outputs. For large, complex systems, the comparison itself can become a significant project.
Big bang replacement
Build the new system, pick a date, switch everything over at once.
When it works
Small systems with limited integrations. Simple applications where the risk of failure is manageable and rollback is straightforward.
When it doesn't
Complex systems with many dependencies. If something goes wrong on cutover day and you can't roll back, you're in serious trouble. Big bang migrations fail more often than they succeed for complex systems, and the failures tend to be spectacular.
Choosing a strategy
| Factor | Strangler Fig | Parallel Run | Big Bang |
|---|---|---|---|
| Risk | Low | Medium | High |
| Duration | Long | Medium | Short |
| Cost | Spread over time | High peak cost | Concentrated |
| Best for | Complex, critical systems | Financial/accuracy-critical | Simple, isolated systems |
| Rollback | Per module | Switch back to old | Difficult |
For most business-critical legacy systems, the strangler fig is the safest bet. It's slower, but the risk profile is dramatically better.
Data migration
Data migration is where most legacy projects get into trouble. The application code is the part everyone focuses on. The data is the part that actually hurts.
Common challenges
- Schema differences. The old system stored data one way. The new system expects it differently. Every field needs mapping, and many mappings aren't one-to-one.
- Data quality. Legacy systems accumulate bad data over years. Duplicates, missing fields, inconsistent formats, orphaned records. You'll need to clean this during migration.
- History preservation. Do you migrate all historical data or just active records? Historical data is often in formats or structures the new system can't handle directly.
- Referential integrity. Records that reference other records. Migrating one table at a time can break these relationships if not managed carefully.
- Volume. Large datasets take time to migrate. A database with millions of records might take hours or days to move, transform, and validate.
Best practices
- Map every field before writing a single migration script.
- Run test migrations on a copy of the data. Multiple times.
- Validate migrated data automatically: record counts, checksums, sample verification.
- Plan for the delta. Data created in the old system between migration start and cutover needs to be captured.
- Keep the old database accessible (read-only) for months after migration. You will need to reference it.
Common failures
- Underestimating hidden business logic. The code that handles the "weird case" that only happens twice a year. Nobody documents it, nobody remembers it, and it surfaces three months after go-live.
- Not involving the people who use the system. IT migrates the system. Users discover it doesn't work the way they need it to. Adoption fails.
- No rollback plan. "It'll be fine" is not a rollback plan. Define exactly how you'll revert if things go wrong, and test it.
- Migrating everything at once. Trying to replicate every feature of the old system on day one. Start with the core 80%. The remaining 20% can come later, or might not be needed at all.
- Losing institutional knowledge. The person who understands the legacy system leaves before the migration is complete. Document what they know early, not when they hand in their notice.
FAQ
How long does a legacy migration typically take?
For a medium-complexity business system, 6-18 months using the strangler fig approach. Simpler systems can be faster. Large enterprise migrations can take 2+ years. The biggest variable is data migration complexity, not the application code.
Can I modernise without a full rewrite?
Yes. Sometimes the best approach is to wrap the legacy system with modern APIs, improve the front end, and fix the most painful pain points without replacing the core. This "modernise in place" approach works when the core system is fundamentally sound but the interface and integrations are outdated.
What if nobody understands the old system?
This is more common than you'd expect. Start with a code review and system audit. Document what the system does by observing its behaviour, not just reading the code. Interview users to understand how they actually use it. Budget extra time for discovery.
Should I use the same technology for the new system?
Not necessarily. The migration is an opportunity to choose appropriate technology for the next 10 years. But don't pick trendy tech for its own sake. Choose boring, well-supported tools that your team can maintain. See software architecture patterns for guidance on structuring the new system.
Key takeaways
- The strangler fig pattern (incremental replacement) is the safest approach for most legacy migrations.
- Data migration is usually harder than the application migration. Plan for it early.
- Never migrate without a rollback plan. Things will go wrong.
- The biggest risk is not technical. It is organisational: losing the knowledge of how the old system actually works.