GuideIntermediate
Legacy Modernization And Migration
Learn to modernize a legacy system without rewriting it from scratch: the big rewrite almost always fails, and the path that actually works is incremental, measured, and reversible. This guide teaches you to put scary legacy code under a safety net with characterization tests, to divert traffic from the old system to the new one with the strangler fig pattern, and to migrate an implementation internally with branch by abstraction when there's no way to insert an external proxy. It covers extracting a bounded context from the monolith into a service with an anti-corruption layer, migrating data without turning the system off (dual-write, backfill, parallel-run), and measuring whether a migration is progressing and when it's actually done — so you avoid the endless migration that never turns the old system off. Everything is simulated and executed in Python: the monolith, the router, and the in-memory database. You work on Mercado, a legacy marketplace with catalog, orders, payments, and shipping living in a single untested monolith. It closes with a capstone project where you modernize a full slice of Mercado end to end, without turning off the business.
- 64
- lessons
- 8
- modules
- English · Spanish
- available in
- Yes
- certificate
- Free
- access
Outcomes
What you'll be able to do
- Understand why the big rewrite almost always fails, and the case for modernizing incrementally instead
- Write characterization tests that pin down a legacy code's current behavior (bugs included) before touching it, and find the right seam for the change
- Implement the strangler fig pattern: a facade that incrementally diverts traffic from the legacy system to the new one, with the old route as fallback
- Apply branch by abstraction to migrate an implementation from inside the code, with no external proxy and no long-lived git branch
- Extract a bounded context from the monolith into its own service using an anti-corruption layer that translates between the old and new models
- Migrate data without downtime using dual-write, backfill, and parallel-run, catching discrepancies before the final read-switch
- Measure migration progress with traffic metrics, legacy-call burn-down, and fitness functions that keep the legacy from growing back
- Run a capstone project: modernize a full slice of Mercado's monolith end to end (tests, strangler facade, service extraction, and data migration)
Before you start
What you need to bring
It's for you if...
- Backend developers and tech leads who inherited a legacy monolith and need to modernize it without stopping the business
- Teams considering a big rewrite who want to understand why it almost always fails before committing to it
- Devs who need to migrate production data without downtime
- Architects who need to measure and communicate the real progress of an ongoing migration
Requirements and materials
- Experience building backend APIs or services in production (any stack)
- Basic understanding of automated testing (unit tests)
- Python to follow and run the guide's simulations (monolith, router, and in-memory database)
- Recommended (not required): the Architecture Decisions and Trade-offs Guide, for the "why migrate" behind each case
Content
The syllabus, module by module
Open any of them to see its lessons.
- Module introduction: understand and pin the legacy
- Working with code that scares you and has no tests
- The characterization test: pin what it does TODAY
- Finding the seam
- Characterizing by sampling and the golden master
- When the legacy does something weird (and someone depends on it)
- Read and characterize before you change
- Mini-project: pin Mercado's catalog pricing
- Module introduction: the strangler fig pattern
- The facade in front of the legacy
- Building the new service alongside
- Diverting traffic by percentage
- Ways of diverting: by route, by percentage, by flag
- Fallback and observing both routes
- The final cutover and retiring the legacy
- Project: put Mercado's catalog behind a strangler facade
- Module introduction: branch by abstraction
- The abstraction layer as a seam
- Building the modern implementation behind the abstraction
- The feature flag as the switch point
- Parallel-run to prove the swap is safe
- Deleting the old implementation
- Without a long-lived branch: avoiding merge hell
- Project: modernize Mercado's ShippingCalculator
- Module introduction: migrating data without downtime
- Expand-contract: never a destructive change all at once
- Dual-write: writing to both stores
- Backfill: loading the historical data
- Parallel-run: comparing both stores
- Reconciling the discrepancies
- The read-switch and turning off the dual-write
- Project: migrate Mercado's catalog data without downtime
- Module introduction: measuring the migration's progress
- Measure the result, not the effort
- The legacy-call burn-down
- The migration fitness function
- Keeping the legacy from growing back
- Defining "done": when the legacy gets deleted
- Avoiding the eternal migration
- Project: measure and finish the Mercado migration
Common questions
What people usually ask
No limit. It's a free guide: come in whenever you like, as often as you like.
No. Modules run from easier to harder, but you can jump to the one you need. Progress is saved per lesson.
Whatever is needed is listed under “What you need to bring”, above. If nothing is listed there, you can start from zero.
In the Club's WhatsApp group, and every two weeks there's a live with an instructor where questions get worked through.
Yes. It's issued automatically once you finish every lesson, with a verifiable code you can share on LinkedIn.
Start whenever you like
What students say
These reviews are from enrolled students who completed at least 50% of the course. We moderate reviews only on content grounds (spam, offensive language, personal data), never for being critical or negative.
No approved reviews yet.
Be the first to share your experience!