Why Strangler Fig Projects Stall

ModernLift · ·10 min read
Part 6 of 8

Strangler fig migrations stall in recognizable ways. The strangle never finishes and the program settles into running two systems forever. The facade is never retired and becomes its own piece of legacy. Slice boundaries are drawn through entangled state so slices cannot be promoted or rolled back alone. Legacy paths are never decommissioned. And organizational stamina runs out before the last slice. Each is avoidable, and each is about discipline and decommissioning, not the pattern itself.

Part 5 laid out the implementation loop, and it reads cleanly: map seams, stand up the facade, prove each slice, ramp, retire, repeat. Run faithfully, it strangles the legacy system on schedule. But programs do not always run it faithfully, and strangler fig migrations fail in a handful of recognizable ways. None of them is a flaw in the pattern. Each is a discipline that lapsed, and naming them is how you see them coming. The general failure modes of modernization have their own treatment in Why Legacy Modernization Projects Fail. This part is about the ones specific to the strangler shape.

The five failure modes at a glance

Every stall below has an early tell, usually visible months before the program admits it is stuck. Use this as a self-diagnosis. If any warning sign in the middle column sounds like your program, the discipline in the right column is what puts it back on track.

Failure modeEarly warning sign you can watch forThe discipline that prevents it
The strangle never finishesSlice velocity drops off after the easy wins, the gnarly core keeps sliding down the backlogSequence the hard slices into the plan, define an explicit end state
The facade becomes permanent legacyThe routing layer keeps growing, nobody fully understands it, it is now load-bearingRetire facade routing per seam as each seam completes
Boundaries drawn through entangled statePromotions stop being small, you cannot roll back one slice without touching threeRedraw the boundary along a clean seam, do not push through
Legacy paths never decommissionedDead branches and stale flags accumulate, “just in case” code piles upMake decommissioning the last step of each slice, not a later project
Organizational stamina runs outThe program goes quiet, sponsors change, early wins fade from memoryShip and surface visible value every few weeks so it funds itself

Failure 1: the strangle that never finishes

This is the signature failure of the pattern, and it grows directly out of its signature strength. The whole appeal of the strangler fig pattern is that old and new can coexist safely and indefinitely. That same property makes it dangerously easy to stop halfway.

A program ships its first few slices, usually the easy, high-visibility ones, feels the relief, and then loses momentum. The hardest slices, the gnarly core nobody wants to touch, sit unmigrated. Traffic still routes to legacy for the parts that matter most. And the organization quietly settles into a steady state of running both systems forever: the legacy system, the modern system, and the facade between them, three things to maintain where there used to be one.

A strangler fig that never finishes strangling is just a second system you now also maintain. The fix is structural. Define the end state explicitly, no production traffic to legacy and legacy code removed, and sequence the hard slices into the plan rather than letting them accrete at the bottom of the backlog. “We’ve modernized the easy 80%” is not a finish line. It is the most expensive place to stop.

Failure 2: the facade becomes permanent legacy

The facade exists to enable the strangle. It is migration infrastructure, and like the anti-corruption layers around retired slices, it is meant to collapse away as the seams it served complete. When it does not, it ossifies into a new piece of legacy, an undocumented routing layer that everything passes through, that nobody fully understands, that is now load-bearing precisely because it was never cleaned up.

This is the migration eating its own tail. You set out to escape an unmaintainable system and built a new unmaintainable choke point on the way. The discipline is to retire facade routing per seam as each seam’s slices finish, so the facade shrinks over the program rather than calcifying. A facade that is as complex at the end as it was in the middle is a sign the strangle stalled.

Failure 3: slice boundaries drawn through entangled state

Part 5 warned that slicing is the hard part, and bad slicing is where the loop quietly seizes. A slice boundary drawn through entangled state produces a slice that cannot stand alone. Its data is interwoven with several neighbors, so its traffic cannot be routed independently, its parity is hard to prove, and a problem in it forces you to touch the slices around it.

The symptom is that promotions stop being small and reversible and start being coordinated, anxious events, the very thing the pattern exists to eliminate. When you find yourself unable to roll back one slice without unwinding three, the boundary was wrong, and the cure is to redraw it, not to push through. Slice boundaries are a discovery-phase decision for exactly this reason. A boundary chosen well makes every later step cheap, and a boundary chosen badly makes every later step fight you.

Failure 4: legacy paths that are never decommissioned

Even programs that keep migrating can fail to keep removing. A slice reaches full traffic, everyone moves on to the next, and the dead legacy path is left wired in “just in case.” Do that across many slices and the codebase fills with dead branches and stale routing flags, each an untested path, each a config change away from accidentally resurrecting a bug you fixed.

The discipline, from Part 5: a slice is not done when the new code works. It is done when the old code is gone. Decommissioning is the last step of each slice, not a cleanup project for the end, because the cleanup project for the end never gets funded, and the debt compounds until the “modern” system carries as much dead weight as the one it replaced.

Failure 5: organizational stamina runs out

The strangler fig pattern trades a single dramatic cutover for a long series of small ones. That is a risk trade, and a good one, but it is also a duration trade. The program runs over a longer calendar than a rewrite’s notional timeline, and it demands sustained executive sponsorship, protected funding, and team continuity across that whole span.

The failure mode is attrition of will. A sponsor changes, priorities shift, the visible early wins fade from memory, and the program loses the air cover it needs to finish the hard slices. The structural defense is the pattern’s own best feature. It ships visible value every few weeks, so it can fund and defend itself continuously rather than asking for years of faith. But that only works if someone keeps surfacing the value. A strangler program that goes quiet about its progress is a strangler program about to lose its budget.

Already stalled? How to restart

Most of this article is about prevention, but plenty of readers arrive here because a program is stalling right now. Recovery is possible, and it follows a specific order. Trying to “just push harder” without diagnosis is how a stalled program becomes an abandoned one.

  1. Name the failure mode. Match your symptoms against the table above. The recovery is different for a boundary problem than for a stamina problem, so guessing wastes the credibility you have left.
  2. Stop opening new slices. A stalled program almost always has too much work in flight and nothing finished. Freeze new starts and drive the closest-to-done slice all the way through, including decommissioning its legacy path.
  3. Repair the worst boundary before continuing. If any slice cannot roll back on its own, redraw that seam now. Continuing on top of a bad boundary compounds the problem with every slice.
  4. Shrink the facade you already have. Retire routing for every seam that is genuinely complete. A smaller, understood facade is worth more than more slices layered onto a growing one.
  5. Re-establish the end state and re-sequence the hard slices. Put “no traffic to legacy, legacy removed” back on the roadmap with dates, and move the gnarly core up rather than leaving it at the bottom.
  6. Make progress visible again. Report the shrinking legacy surface every few weeks. A stalled program that starts showing real decommissioning is how you win back the funding to finish.

If steps 1 through 5 reveal that the remaining work costs more than the legacy remnant does, the right recovery may be to stop deliberately, which is the next section.

Sometimes the right move is to stop

Not every stall is a failure to push through. Occasionally a program discovers, partway in, that the remaining legacy capability is stable, under no real pressure, and genuinely cheaper to keep than to migrate, and that the honest call is to stop deliberately, retire the facade routing for the finished seams, and leave a well-bounded legacy remnant in place. That is a legitimate end state, if it is a decision rather than a drift. The danger is not a small, owned, intentional remnant. It is the unowned, unbounded, “we’ll get to it” remnant that the organization stops thinking about while it quietly costs money forever. The difference between the two is whether anyone decided.

Where this leads

Most of these failures trace back to a single root: a step in the loop done without discipline, a slice promoted without proof, a path left un-retired, a rollback that turned out not to work. Part 7, Validating Each Slice: Parallel Run, Flags & Rollback, is about the discipline that keeps each strangle-step safe and reversible, the parallel run that earns the right to route traffic, the flag that ramps it, and the rollback that contains a bad slice, and where each of those connects to the deeper validation machinery.

Frequently asked questions

What is the biggest risk in a strangler fig migration?
Never finishing. The pattern's greatest strength, that old and new can coexist indefinitely, is also its greatest trap. A program can ship a few slices, declare partial victory, and settle into running two systems forever, paying to maintain the legacy system, the modern system, and the facade between them. A strangler fig that never finishes strangling is just a second system you now also maintain.
Why do slice boundaries cause strangler fig projects to stall?
Because a boundary drawn through entangled state produces a slice that cannot be promoted or rolled back on its own. If a slice's data is interwoven with several others, routing its traffic independently becomes unsafe, parity is hard to prove, and a problem in one slice forces you to touch its neighbors. Bad boundaries turn the pattern's small, reversible steps back into a tangle of coupled ones.
How do you restart a stalled strangler fig migration?
Start by naming which failure mode you are in, because the fix differs. If you stopped after the easy slices, re-plan with the hard slices sequenced in and an explicit end state. If the facade has grown into a choke point, retire its routing seam by seam. If a slice will not roll back cleanly, the boundary is wrong and needs redrawing rather than pushing through. Then pick one finishable slice, decommission its legacy path fully, and make the progress visible again so the program earns back its funding.
How do you keep a strangler fig migration moving?
Treat decommissioning as part of finishing each slice, not as cleanup for later. Delete the legacy path and collapse the facade routing the moment a slice settles. Protect the funding and stamina by shipping visible value continuously. Draw slice boundaries along clean seams during discovery. And set an explicit end state, no traffic to legacy and legacy code removed, so "done" is defined and the program cannot quietly stop halfway.
All 8 parts of The Strangler Fig Pattern & Incremental Migration →