All terms

Glossary

Strangler fig

Also: Strangler fig pattern

A pattern for replacing a legacy system step by step: new functionality grows around it, the old system shrinks, until nothing of it is left.

The name comes from the strangler fig, which grows up a tree, encloses it and in the end stands there alone. Applied to software that means: a router sits in front of the legacy system and sends individual calls to new code. Few at first, more over time, and at some point nothing runs through the old path any more.

The alternative is the big rebuild: develop in parallel for two years, then switch over. That sounds cleaner and regularly goes wrong, because the old system keeps living and changing in the meantime. Every change to the old side has to be reproduced in the new one, and the gap grows instead of shrinking.

In practice the pattern needs three things: a place where traffic can be redirected, clarity about which data belongs to whom, and the discipline to actually delete the old path after the switch.

The router can take different forms. With HTTP traffic a reverse proxy or a rule in the load balancer that sends one path to a new service is often enough. In an application without a network boundary of its own it is a switch in the code that picks between the old and the new implementation. With asynchronous processing the new consumer reads along on the same queue.

The genuinely hard part is rarely the router, it is the data. As long as old and new write to the same database, nothing has been replaced, only additional code has been created. That is why an area is only cut out once it is clear who owns which data and how the other side gets to it: through an interface, through events, or through a mirror with one unambiguous direction of writing.

The order follows value, not architecture. Start with the area that is changed most often or causes the most trouble, not with the one that looks easiest. The first cut also has a second job: it builds the tooling everything after it needs, meaning the router, the comparison run, the rollback and the measurement.

Being able to roll back is what makes the procedure low risk. Every step runs in shadow mode first, then for a small share, then fully, and it can be turned back within seconds at every stage. If you need a deployment after each step to get back, you have given away the advantage.

How you notice it

  • There is a place where traffic can be redirected, such as a load balancer.
  • Individual functional areas have clear data boundaries.
  • A rebuild would take longer than the market gives you.
  • The system must not stand still during the rebuild.

Not to be confused with

Big bang migration
One cut-over date, one attempt, no intermediate state. Strangler fig swaps that single large block of risk for many small ones, each of which can be reversed on its own.
Refactoring
Changes structure inside the same system. Strangler fig moves functionality into a new system and switches traffic over.
Branch by abstraction
The same idea inside one codebase: introduce a layer of abstraction and replace what sits behind it. Strangler fig works across system boundaries.
Anti-corruption layer
Not a replacement pattern but a protective layer. It keeps the vocabulary and quirks of the legacy system out of the new code, and with strangler fig it is usually needed on top.

When it fits

  • The system has to keep running throughout the rebuild.
  • There is a place where traffic can be redirected, such as a load balancer, a proxy or a switch in the code.
  • The functional scope is too large to specify in full.
  • The project has to be interruptible, because budget or priorities may change.

When it does not

  • Very small systems, where the router is more effort than the rebuild.
  • When old and new sit inseparably on the same data model and no cut can be found.
  • When the legacy system is being switched off anyway and nobody has to take over its behaviour.

How to approach it

  1. Look for the cut along the business domainDo not split by technical layer, split by responsibility. An area that owns its data can be lifted out; a layer running across everything cannot.
  2. Add the router and roll it out without changing behaviourPut the redirection into production first while it still sends a hundred per cent to the old side. If you roll out the router and the first piece of functionality together, an error leaves you unsure which of the two is to blame.
  3. Settle data ownership before any code is writtenWho writes, who reads, how does the other side get the data. Without that answer you end up with a second writer on the same table, and that is not a replacement.
  4. Run in shadow modeThe new path processes real traffic, but the result does not go to the user, it goes into a comparison. Deviations show up before they hit anyone.
  5. Switch over by shareOne per cent, ten, fifty, a hundred, with a metric at every stage. The rollback has to be a switch, not a deployment.
  6. Delete the old path in the same taskNo follow-up ticket. Otherwise the dead code stays around as a safety net, keeps being maintained and makes the rebuild more expensive rather than cheaper.

Frequently asked

How long does a replacement with the strangler fig pattern take?

Longer than a rebuild on paper and shorter in reality, because parts are in production from the first month. For the publishing platform in my case studies the modernization ran over twelve months without a day of downtime. What matters is not the total duration but that every step has value on its own.

What do you do about the shared database?

That is the real test. As long as both sides write into the same tables, nothing has been replaced. Three routes are workable: the new service takes over one area of data completely and exposes it through an interface, or the old side publishes events and the new one keeps a view of its own, or there is a mirror with exactly one permitted direction of writing. Two writers on the same table are not an intermediate state, they are a new permanent one.

Where do you start?

With the area that is changed most often or causes the most incidents, not with the easiest one. The first cut costs disproportionately, because it builds the router, the comparison run and the rollback along the way. If that effort goes into an edge piece, the tooling exists but the benefit is invisible, and projects without visible benefit do not get finished.

How do you prove the new path does the same thing?

Through shadow mode: both paths process the same real traffic, the old result is what gets delivered, and both are compared. After a few days you know the deviations and which of them are bugs and which are intended corrections. Only then do you switch over, and by share.

What if the project is stopped halfway?

Then the value of the parts already replaced is there regardless, and the intermediate state can be operated. That is exactly what separates the pattern from a rebuild, where stopping after eighteen months delivers nothing. The price: the intermediate state must not become permanent, so every paused cut needs a date on which continuation or reversal is decided.

Read moreWhy full rewrites fail