top of page

Strangler Pattern Refactor — Refactoring Patterns, Part 10

Shawn West
Jul 30
2 min read
Refactoring Patterns · Part 10

The instinct with a legacy system everyone hates is to rewrite it from scratch — and that big-bang rewrite is where projects go to die, because you're rebuilding a moving target while it keeps changing underneath you. The strangler pattern replaces it piece by piece instead, routing traffic to new code one boundary at a time until the old system can be retired. This walks through doing it without a risky flag day.

Big rewrites die. Strangler replaces a system piece by piece while it keeps running.

Step 1: The Metaphor (15 min)

Strangler fig grows around tree; eventually tree dies; fig remains.

In code:

  • New system grows alongside legacy

  • Pieces migrate over time

  • Legacy shrinks

  • Eventually retired

Step 2: Why Not Big Bang (15 min)

Rewrite from scratch:

  • Long time without value

  • Risk: never finishes

  • Risk: misses old features

  • Business halts during transition

Most big rewrites: fail or hugely delayed.

Step 3: Identify Boundaries (15 min)

Find seams in legacy:

  • HTTP endpoints

  • Module boundaries

  • Database tables

  • User-visible features

Each becomes potential migration unit.

Step 4: Route Per Boundary (15 min)

Proxy / router decides:

Request → router →
  /api/v1/users → legacy
  /api/v1/orders → new system
  /api/v1/products → legacy

Migrate route by route.

Step 5: Feature Flag Approach (15 min)

if (flag('new-order-flow', user)) {
  return newOrderService.create(req)
}
return legacyOrderService.create(req)

Gradual rollout per user. A/B test old vs new.

Step 6: Database Strangling (15 min)

Two systems writing same data:

  • Dual-write (both DBs)

  • Backfill old data

  • Verify consistency

  • Cut over reads

  • Stop writes to old

Slow. Careful. Months.

Step 7: Parity Tests (15 min)

For each migrated piece:

  • Same input to both old + new

  • Compare outputs

  • Investigate differences

  • Promote new when matched

Tools: shadow mode.

Step 8: Don't Drift (15 min)

Legacy still in use; bug fixes / features needed?

  • Apply to both

  • Or hold features until migration done

  • Don't let legacy diverge from new while migration in flight

Step 9: Track Progress (15 min)

Visible:

  • % of traffic on new

  • % of features migrated

  • Lines of code in legacy (going down)

  • Time-to-completion estimate

Without visibility: migration drags forever.

Step 10: Retire (15 min)

When 100% on new:

  • Delete legacy code

  • Drop old DB tables (after grace period)

  • Decommission infra

  • Celebrate

  • Document learnings

Many migrations stop at 95%. Push to 100%.

What You Just Did

Strangler pattern refactor: the metaphor, why not big bang, identify boundaries, route per boundary, feature flag approach, database strangling, parity tests, don't drift, track progress, retire.

Common Failure Modes

Big bang anyway. Often fails.

No boundaries identified. Where to start?

Diverging legacy + new. Drift accumulates.

Stop at 95%. Two systems forever.

No parity testing. Quality regression.

Continue the Refactoring Patterns path

Part of the Refactoring Patterns learning path.

bottom of page