Logo von nextlevels
DEEN
Request a project

Strangler fig pattern

Last updated on

In short

Strangler fig pattern refers to a software modernisation approach in which a legacy system is not replaced in one go but is grown around and replaced function by function by a new system. A facade routes each request either to the old or to the new code, so that both systems run side by side for months or years.

In the end, the new system takes over all tasks and the old one is switched off.

The term comes from Martin Fowler. In 2001, he had seen strangler figs in the Queensland rainforest: plants that germinate in the crown of a tree, grow their roots downwards and over the years enclose the host so completely that it dies and only the fig remains standing. On 29 June 2004, Fowler published the bliki entry "StranglerApplication" on this. Because the name "strangler" sounded violent without the botanical context, he later renamed the entry "Strangler Fig Application", last revised in August 2024. The image stayed the same: the new grows around the old until the old is superfluous.

For managing directors and IT managers in mid-sized companies, the pattern is above all an answer to an uncomfortable question: what do you do with a system that carries the business but that nobody wants to touch any more? This entry explains how the pattern works, where it applies to monoliths and to mobile apps, what risks it brings and how it differs from a big-bang rewrite and from refactoring.

How the strangler fig pattern works

The pattern has a simple basic idea and four phases. Microsoft's architecture documentation describes them as introducing the facade, incremental decomposition, decommissioning the legacy system and removing the facade. In practice, it looks like this.

Phase 1: facade and routing

First, you place a layer in front of the legacy system that receives all calls. For a web back end, this is a reverse proxy, an API gateway or a routing layer in the application itself. Initially, this facade changes nothing; it passes every request unchanged to the old code. Its value lies in the fact that from now on you can decide per route, per endpoint or per screen who answers. Without this interception point there is no strangler fig pattern; Microsoft explicitly names the inability to intercept as an exclusion criterion.

Phase 2: incremental replacement

Then you choose a first function, rebuild it in the new system and switch the facade over for exactly this function. Everything else continues to run via the legacy system. The first slice should be small, well defined and valuable in business terms: an area the business wants to change anyway, or one that frequently produces errors. Each further function follows the same cycle of rebuilding, switching over and observing. Fowler emphasises that the great advantage of this approach lies in the reduced risk, because each step is small and the legacy system remains as a fallback.

Phase 3: coexistence of old and new

The longest phase is the one in which both systems are in production at the same time. This is where it is decided whether the project succeeds. The new system needs access to data that is still in the old one, and vice versa. For this, AWS recommends in its Prescriptive Guidance an anti-corruption layer, i.e. a translation layer that mediates calls between the old and new data models, as well as synchronisation via message queues if both systems hold their own databases. The more cleanly these boundaries are drawn, the fewer surprises appear later.

Phase 4: dismantling

When the last function has moved, the legacy system no longer receives requests and can be switched off. After that, the facade is also removed or deliberately kept as a permanent gateway. This step is forgotten in many projects. A legacy system that no longer does anything but is still running costs licences, hosting and attention and remains a security risk.

Application: from monolith to microservices

The classic use case is breaking down an organically grown monolith into microservices. The AWS documentation on the strangler fig pattern describes exactly this route: an API gateway is placed between the user interface and the monolith, then individual services such as user management, basket or customer account are extracted one after another and operated as independent services with their own data storage. The monolith shrinks with every step until it can be decommissioned.

For a mid-sized company with an ERP-related back end, old shop software or a self-developed customer portal, this specifically means: you do not have to decide whether to do "everything new". You decide which area is extracted first. Often this is an area with a high frequency of change and clear interfaces, such as price calculation, order status or authentication. The interface to the rest of the system is then often a REST API that remains in place even when the monolith has long gone.

A side effect that many underestimate: the pattern forces you to really understand the legacy system. When rebuilding a function, the undocumented special cases that the business has been silently relying on for years come to light. Fowler names precisely this problem as the main reason why complete rewrites fail: nobody knows the complete behaviour of the old system any more, and in the rewrite a large part of it is unintentionally rebuilt.

Application to mobile apps: brownfield integration

Less well known, but more topical for many companies, is the application of the pattern to mobile apps. An existing native app in Swift or Kotlin that has been in the store for years cannot simply be replaced by a facade on the server side. Here the interception point lies in the app itself: the navigation decides per screen whether a native view or a new module is displayed.

Technically, this works via so-called brownfield integration. React Native and Flutter can be embedded as a module in an existing native app. The native shell remains in place, with log-in, push notifications, hardware access and store configuration. Individual screens or entire areas are gradually replaced by cross-platform modules that serve iOS and Android at the same time. In the best case, the user notices nothing, because the app works completely at all times and is updated via the same store listing.

For companies that need to modernise an existing app, this approach has a practical advantage: it can be reconciled with the app stores' deadlines. Anyone who has to ship a release anyway because of new target SDK requirements can use this release as the first step of the replacement instead of waiting twelve months for a completely new app. Which technology makes sense for the new modules depends on the team and the existing code; an overview is given in the entry on cross-platform development. In app development at nextlevels, React Native or Flutter are used for this depending on the starting point, even when a native core is retained.

A real-world example: Shopify and the iterative porting of the Shopify app

A well-documented public example is the migration of Shopify's mobile apps to React Native. In January 2020, Shopify announced that it would build all new mobile apps in React Native, but explicitly answered the question of a rewrite of the existing native apps with "No" and left the decision to each app team. At the end of 2022, staff developer Mauricio de Meirelles described in the Shopify Engineering blog what this looked like in practice: for the Shopify app, with around 300 screens per platform, the team decided against a new development and in favour of a gradual takeover. At first only the root screen was ported, which took about four months, while the inner feature screens remained native. After that, the rule was "all new features in React Native, existing features are migrated in parallel", internally called "iterative porting". That is the strangler fig pattern at app level.

The contrast within the same company is remarkable. For the point-of-sale app, Shopify by its own account opted for a complete rewrite, because the problems could not be solved with incremental changes. The same company thus used both strategies, depending on the state of the legacy system. In January 2025, Mustafa Ali, Director of Engineering, took stock: after five years, all mobile apps ran on React Native, with screen load times under 500 milliseconds (P75) and over 99.9 per cent crash-free sessions; he explicitly described "100 per cent React Native" as an anti-goal, because hardware access and background processes remained native. InfoQ summarised this retrospective in April 2025.

The story has a twist that fits the pattern: in September 2026, Shopify announced that it would build the apps natively in Swift and Kotlin again, because AI coding agents now greatly reduce the effort for two platforms. The Shop app was completely rebuilt for this in twelve weeks. For you, this does not mean that either direction was wrong. It means that technology decisions for apps have a half-life and that an approach that keeps the app runnable at all times helps with every change of direction.

Advantages and risks

The pattern is not self-propelling. It exchanges one large, one-off risk for many small, ongoing efforts. Whether this exchange pays off depends on the starting point.

Strangler fig pattern: advantages and typical risks compared
AspectAdvantageRiskCountermeasure
Risk per stepEach switch-over is small and can be reversedMany small steps add up to a long durationPrioritise slices by business value, measure progress
Two stacks in parallelNew knowledge builds up while the old system is still runningDouble maintenance, double builds, double sources of errorClear responsibilities, no new features in the legacy system
End dateNo hard cut-over day, no weekend of fearWithout an end date, the legacy system stays half alive for everPlan the switch-off date and dismantling from the start
Data consistencyData can be migrated step by stepTwo truths for the same record, synchronisation errorsExactly one leading system per entity, anti-corruption layer
FacadeCentral point for routing, logging, feature flagsBottleneck or single point of failureKeep the facade lean, load testing, resilience

In our view, the most dangerous risk is not technical but organisational. A strangler fig project without a binding switch-off date becomes a permanent construction site in which two systems, two deployments and two states of knowledge are maintained side by side. The running costs of this state belong in every total cost of ownership analysis. Anyone choosing the pattern should therefore plan not only the first slice but also the last.

The second major risk is data storage. As long as both systems write to the same database, the problem is manageable, but the coupling remains. As soon as the new system gets its own database, you need a rule about which system is leading for which data and a mechanism that reliably transfers changes. Microsoft also points out that for legacy systems whose code can no longer be changed, change data capture at database level can be a way out.

Distinction from big-bang rewrite and refactoring

The strangler fig pattern is often described as a middle way between two extremes. That is only partly accurate, because it is less a compromise than a route of its own with its own rules.

With a big-bang rewrite, the new system is developed in parallel and switched over completely on a set date. That sounds clean but has two structural weaknesses. First, the business gets no new features during the development period, or the legacy system is developed further and the new one has to catch up. Second, on the set date the new system has to be able to do everything the old one could, including the special cases that nobody has documented any more. Fowler writes that he has seen this seemingly simple plan "go up in flames" most of the time. There are situations in which the rewrite is nevertheless right: when the legacy system is so small that the replacement succeeds in weeks, when requests cannot be intercepted or when the architecture is so tangled that no slice could be cleanly extracted. Shopify's POS rewrite is an example of such a deliberate decision.

Refactoring improves the internal structure of a system without changing its external behaviour, staying within the same technology stack. It reduces technical debt but does not replace the system. The strangler fig pattern replaces it. The two are not mutually exclusive: often a function in the legacy system is first refactored so that it gets a clear interface, and only then extracted. Refactoring is therefore often the preparation for a slice, not its alternative.

A third distinction concerns replatforming, i.e. changing the platform, for example from one shop system to another or from your own data centre to the cloud. Replatforming describes the goal; the strangler fig pattern describes one possible route there. Not every replatforming runs incrementally, and not every strangler fig project changes the platform.

When the pattern fits and when it does not

The strangler fig pattern is the right choice when the legacy system is business-critical, when it can continue to run for a longer period and when its calls can be intercepted at one point. It is the wrong choice when the system is small enough for a quick complete replacement, when the legacy system has to be switched off at short notice for licensing or security reasons, or when the source code and the database are not accessible. Before deciding, it is worth taking brief stock of the interfaces, the data model and the business areas that are suitable as first slices. What comes out of this is usually more honest than any estimate for a rewrite.

Frequently asked questions about the strangler fig pattern

How long does a migration using the strangler fig pattern take?

That depends on the size of the legacy system and the number of slices. Shopify needed around five years for its entire app landscape; porting the root screen of the Shopify app alone took about four months. For a mid-sized back end, six to 24 months are realistic depending on scope. What matters is that a switch-off date is set from the start and that progress is measured in migrated functions.

Does the strangler fig pattern also work for a mobile app?

Yes, via brownfield integration. React Native or Flutter are embedded as a module in the existing native app, and the navigation decides per screen whether an old native view or a new module is displayed. The app remains fully runnable at all times and can be updated via the same store listing. The Shopify app was migrated exactly this way.

What is the difference between the strangler fig pattern and refactoring?

Refactoring improves the internal structure of a system in the same technology stack without replacing it. The strangler fig pattern replaces the system function by function with a new one, usually in a different stack. In practice, refactoring often precedes a slice, so that the function gets a clean interface before it is extracted.

You can find the original description of the pattern at Martin Fowler's site, and detailed architecture guidance with facade, anti-corruption layer and data synchronisation in the Microsoft Azure architecture documentation.

Next step

Does the strangler pattern suit your legacy system?

Answer a few short questions about your legacy system and get a risk score plus a recommended route: refactor, strangle or rebuild.

Changelog

  1. · Created · Jan Schumann