All Articles
Digital Transformation
Architecture
Legacy Modernisation
Cloud Migration

Legacy Modernisation Without the Big Bang: The Strangler Fig Pattern at Scale

Rewriting a legacy system from scratch is one of the most dangerous projects a technology organisation can attempt. Here's how to modernise incrementally — safely, continuously, and without betting the business on a single rewrite.

MG
Mohamed Ghassen Brahim
October 15, 202510 min read

Every technology organisation eventually faces the legacy modernisation question. The system that launched the business — the one that processes your revenue, holds your customer data, or runs your core operations — has become a constraint. It's slow to change, expensive to operate, and impossible for new engineers to understand.

The natural response is to propose a rewrite. Start fresh. Build it right this time.

This is almost always the wrong answer.

The history of software development is littered with "big bang" rewrites that took three years instead of one, cost five times the estimate, and were eventually abandoned in favour of the legacy system they were meant to replace. Netscape 6. Microsoft Vista. The NHS National Programme for IT. The pattern is consistent: the rewrite takes longer than expected, the old system accretes new requirements during the rewrite, the new system launches with a different feature set than expected, and the migration of users is traumatic.

The alternative is incremental modernisation using the Strangler Fig pattern — and it's the approach I recommend for virtually every legacy modernisation programme.

What Is the Strangler Fig?

The name comes from a type of tropical fig tree that grows around an existing tree, gradually encasing it. Over years, the fig tree becomes self-supporting while the original tree rots away, leaving only the fig.

In software terms: build the new system alongside the old one, gradually migrate functionality and traffic, until the old system handles nothing and can be decommissioned.

🔍

Martin Fowler's framing

Martin Fowler coined the term "Strangler Fig Application" in 2004 to describe this pattern. The key insight is that you can incrementally replace a legacy system without ever needing to stop using it. The old and new systems coexist during the transition period, reducing risk dramatically.

How It Works: The Three Mechanisms

Mechanism 1: The Façade

The first step is to introduce a façade (proxy or API gateway) in front of the legacy system. This façade intercepts all traffic, initially routing 100% of it to the legacy system unchanged.

The façade is the key architectural element: it gives you the ability to selectively route traffic to either the old or the new system, based on rules you define (user segment, feature flag, endpoint, tenant).

On Azure: Azure API Management, Azure Front Door, or NGINX Ingress (on AKS) can serve as the façade. The implementation detail matters less than having the routing capability.

Mechanism 2: Selective Migration

With the façade in place, you can extract individual capabilities from the legacy system and build them in the new system. For each extracted capability:

  1. Build and test the new implementation
  2. Route a small percentage of traffic (5–10%) to the new implementation via the façade
  3. Monitor: do metrics match the legacy system? Are there errors?
  4. Ramp traffic progressively: 25%, 50%, 100%
  5. Keep the legacy implementation available for rollback during the ramp
  6. Once traffic is fully migrated, decommission the legacy code path

This cycle repeats for each capability until the legacy system handles no traffic.

Mechanism 3: Data Migration

Data migration is typically the hardest part of legacy modernisation. The approach:

Dual-write: During the transition period, writes go to both the legacy data store and the new one. This keeps both systems consistent and enables rollback.

Backfill: Migrate historical data from legacy to new data store. For large datasets, this is a background job that runs during the transition period.

Cut-over: Once all traffic is migrated and historical data is backfilled, stop writing to the legacy data store. Verify consistency. Decommission.


Planning a Strangler Fig Programme

1
Decompose the Legacy SystemWeeks 1–4

Map the legacy system into bounded domains. These become your migration units. A bounded domain is a set of related capabilities that can be migrated together without affecting other domains.

  • Document all capabilities (user journeys, not technical functions)
  • Map capabilities to data entities and dependencies
  • Identify the boundaries between capabilities
  • Score each domain: migration complexity vs. business value
2
Install the FacadeWeeks 4–8

Deploy the routing facade in front of the legacy system. At this stage, 100% of traffic passes through to the legacy system unchanged. This establishes the mechanism for gradual migration.

  • Choose and deploy the facade technology (APIM, Front Door, NGINX)
  • Validate no latency degradation with full legacy pass-through
  • Implement traffic routing rules and feature flags
  • Establish monitoring for both systems via the facade
3
Extract High-Value, Low-Risk Domains FirstMonths 2–6

Start with domains that deliver quick wins: high business value, relatively low complexity, limited data coupling. This builds confidence, validates the approach, and delivers value early.

  • Prioritise domains with clear API boundaries
  • Avoid domains with complex shared data or transactional coupling in early waves
  • Validate new implementation against legacy in shadow mode before traffic migration
4
Migrate Core DomainsMonths 6–18

Tackle the complex, high-coupled core domains. This is the hardest phase — core domains often have the most technical debt, the most data coupling, and the highest operational risk.

  • Implement the strangler incrementally within each domain
  • Manage data migration with dual-write and careful consistency validation
  • Run the old and new implementations in parallel until confidence is high
5
Decommission the Legacy SystemFinal phase

When all traffic has been migrated and new systems are stable, decommission the legacy system. This requires confidence in the new system and a clear process for handling edge cases discovered post-decommission.

  • Gradually reduce legacy system capacity as traffic migrates
  • Keep the legacy system available (read-only) for an agreed period post-cutover
  • Formal decommission with data archival and access log retention

Common Failure Modes

1. Never finishing

The strangler fig can become a permanent two-system state. Teams extract the easy domains, leave the hard ones in the legacy system, and declare victory. Two years later, 70% of functionality is in the new system and 30% is still in the legacy system — which is now unmaintained but still running.

The fix: Define a clear decommission date for the legacy system and hold to it. The hard domains need migration timelines, not indefinite deferral.

2. Scope creep in the new implementation

As teams build the new system, they're tempted to add features that weren't in the original scope: "while we're rebuilding this, let's also add X." This delays completion and creates moving targets.

The fix: Strict scope control. The new implementation must be feature-equivalent to the legacy system it replaces. New features go in the backlog and are built after migration, not during.

3. Data consistency problems during dual-write

Dual-write creates windows of inconsistency between old and new data stores. If a write to the new store succeeds but the legacy write fails (or vice versa), the systems diverge.

The fix: Implement write-through to the legacy system as the primary and new system as the secondary, making the legacy system the source of truth during transition. Only after all reads have been migrated to the new system does the new system become primary.

4. Performance degradation from the façade

Adding a proxy layer in the hot path introduces latency. If not implemented correctly, the façade can become a performance bottleneck.

The fix: Deploy the façade close to the application layer (same region, same VNet), implement connection pooling, and monitor façade latency separately from application latency. A well-implemented NGINX or API Management façade should add < 5ms.


When NOT to Use the Strangler Fig

The Strangler Fig is the right default for most legacy modernisation programmes, but there are situations where it doesn't apply:

  • Tightly coupled systems with no clean boundaries — if the legacy system is one enormous ball of mud with no discernible domain boundaries, the decomposition step fails and you need a different approach (domain-driven refactoring first, then Strangler Fig)
  • Externally hosted systems — if you don't control the legacy system (e.g., a SaaS product you're replacing), the migration is a data migration and user cutover, not a Strangler Fig
  • Systems with extreme compliance requirements — some regulated environments cannot tolerate dual-write periods or traffic splitting during transitions

In these cases, a parallel run (build the new system completely before cutting over) or a phased big-bang (migrate one business unit at a time) may be more appropriate.

💡

The decision test

Ask: Can I migrate 10% of users or traffic to the new system tomorrow, with rollback capability? If yes, the Strangler Fig works. If the answer is no — because you can't decouple the data, the APIs, or the user experience — you have a different problem to solve first.


Legacy modernisation is one of the most complex and high-stakes programmes a technology organisation undertakes. If you're planning a modernisation programme and want an experienced perspective on the approach, let's talk.

Ready to put this into practice?

I help companies implement the strategies discussed here. Book a free 30-minute discovery call.

Schedule a Free Call