Modernizing Legacy Systems Without Halting Your Business
The big-bang rewrite that replaces everything at once almost always fails. Here is the migration strategy that keeps your operations running while the new system takes shape.

Every organization that has been running the same core software for ten or more years is managing a legacy system. Not always by that name — it might be called "the main system," "the old platform," or, with affectionate frustration, "the thing only Dave knows how to restart." But the characteristics are the same: the system was built for a world that no longer exists, it carries business logic that is not fully documented, it is expensive and slow to change, and no one in leadership wants to talk about the rewrite because the last time someone proposed it, the project ran eighteen months over budget and still was not finished.
The reason most legacy rewrites fail is that they are treated as software problems when they are actually business continuity problems. The business cannot stop operating while the new system is being built. The data that lives in the old system is production data. The workflows that run on the old system are live workflows. A strategy that replaces everything at once assumes a clean cutover that almost never happens — and when it does not happen, the organization is left running two systems simultaneously, which is worse than the original situation.
The strangler fig: the migration pattern that works
The strangler fig pattern — named by Martin Fowler after the tropical tree that grows around a host and eventually replaces it — is the migration strategy that most successful legacy modernizations use. Rather than building the new system in parallel and attempting a cutover, you incrementally replace specific capabilities of the legacy system with modern equivalents, routing traffic to the new system for replaced capabilities and the old system for everything else. Over time, the new system handles more and more functionality; the old system handles less and less. Eventually it can be decommissioned without a single moment of complete cutover.
The mechanics: an API gateway or routing layer sits in front of both the legacy system and the new system. When a request comes in, the routing layer determines which system should handle it based on which capabilities have been migrated. For migrated capabilities, requests go to the new system. For everything else, requests go to the legacy system. Data flows between the systems through a synchronization layer that keeps both up to date during the transition period.
Identify and prioritize capabilities: not all parts of the legacy system are equally worth modernizing. Start with the capabilities that are blocking business value — the ones that are slow to change, expensive to run, or limiting growth.
Build the routing layer first: the infrastructure that routes between old and new must exist before the first capability migrates.
Migrate one capability at a time: each migration is a testable increment. If a migrated capability has problems, route back to the legacy system while you fix them.
Never break the old system while migration is in progress: the legacy system is production; keep it running and current throughout.
The API wrapper: making legacy systems interoperable
Legacy systems were frequently built before APIs were a standard part of system design. They expose functionality through proprietary protocols, flat-file interfaces, database connections, or green-screen terminal interactions — none of which are compatible with modern integration patterns. Before you can apply the strangler fig pattern (or integrate the legacy system with modern tooling while migration is in progress), you often need to wrap the legacy system in an API layer that exposes its functionality in a standardized format.
API wrappers for legacy systems range from straightforward (wrapping REST calls around a well-structured database) to complex (screen-scraping a terminal application via RPA, parsing flat-file output from a COBOL batch process, or reverse-engineering a proprietary binary protocol). The complexity and fragility of the wrapper depends entirely on the legacy system's architecture. In all cases, the wrapper should be treated as temporary infrastructure — present for the migration period, deprecated when the capability it wraps has been migrated to the new system.
Data migration: the part everyone underestimates
Data migration is consistently the most underestimated component of legacy modernization projects. The data in a legacy system is not clean. It accumulated over years, sometimes decades, through user entry, integration feeds, batch processes, and manual corrections. Field semantics shift over time — a field called "status" might have meant three different things to three different teams over fifteen years. Records exist that violate business rules that were added five years after the records were created. Duplicates exist that were never cleaned because the old system made deduplication impractical.
The correct approach to legacy data migration runs in three phases: assessment (profile the actual data, not the schema — count the nulls, identify the constraint violations, find the semantic ambiguities), transformation design (write the rules for how the legacy data maps to the new data model, including what to do with records that do not fit), and iterative migration (run the migration repeatedly against production data as the new system develops, not once as a final step). Running the migration repeatedly allows the transformation rules to be validated against real data rather than assumptions, and ensures the final migration is a well-tested procedure rather than a terrifying one-time event.
Testing: you cannot test a legacy system with modern tools without preparation
Legacy systems were not built with automated testing in mind. Most do not have a test environment that faithfully replicates production, do not have documented expected behavior for all code paths, and cannot be run in isolation from their dependencies (shared databases, mainframe connections, external services with no sandbox). Before the migration begins, establish a baseline: capture the actual outputs of the legacy system for a representative set of inputs, and use those outputs as the acceptance criteria for the migrated capabilities. This is the most pragmatic form of characterization testing for legacy code where unit tests do not exist.
The organizations that have modernized successfully are the ones that treated the migration as a multi-year program of work, not a project with a go-live date. There is no cutover. There is only steady progress until the old system has nothing left to do.
How TTGC approaches legacy modernization
Ravve Jay Prevendido and the TTGC engineering team have led legacy modernization programs in professional services, manufacturing, and healthcare — the same industries covered in custom software for manufacturing and custom software for healthcare. The consistent approach: define the target architecture first, build the routing and synchronization infrastructure second, and migrate in priority order of business value. Modernization that keeps operations running at every step, with no big-bang moments. Connect at /growth-assessment to assess your legacy situation.
Legacy system limiting your growth? TTGC migrates without the cutover risk — one capability at a time.
Book a free Brand and Growth Assessment and see exactly how Through The Glass Creatives would approach it.
Sources
- Martin Fowler — "StranglerFigApplication" (martinfowler.com, 2004; updated methodology 2019).
- Gartner — "Modernizing Legacy Applications: Strategy and Decision Framework" (2024).
- McKinsey & Company — "The true cost of legacy software modernization" (2024).
- IEEE Software — "Characterization testing for legacy systems before migration" (2023).

