Architecture

Strangler Fig Pattern

Incrementally replacing a legacy system by routing traffic to new code while the old system lives alongside it.

Overview

The Strangler Fig Pattern incrementally replaces a legacy system by intercepting calls to it and routing them to new code. The new system grows around the old one, handling more routes over time, until the old system can be switched off. The name comes from the strangler fig tree that grows around a host tree until the host dies.

Origin

Coined by Martin Fowler in 2004 in a blog post, inspired by the strangler fig tree. It became the dominant migration strategy for breaking up monoliths into microservices, especially after Sam Newman's "Building Microservices" (2015).

Examples

Strangling a Rails monolith route by route

# Phase 1: Proxy in front of the monolith intercepts traffic
# nginx.conf (simplified)
# location /api/users { proxy_pass http://new-user-service; }
# location /          { proxy_pass http://legacy-rails-app; }

# Phase 2: New service handles User routes; legacy still handles everything else
# New service (Node.js, Elixir, or a new Rails app)

# Phase 3: Redirect monolith's user-related requests to the new service
# In the monolith, for routes being migrated:
class UsersController < ApplicationController
  MIGRATION_COMPLETE = Rails.env.production? && FeatureFlag.enabled?(:user_service)

  def show
    if MIGRATION_COMPLETE
      redirect_to "#{ENV['USER_SERVICE_URL']}/users/#{params[:id]}", status: 307
    else
      @user = User.find(params[:id])
      render json: @user
    end
  end
end

# Phase 4: Remove the monolith route entirely once confidence is high

Use Cases

  • 01Migrating from a monolith to microservices without a big-bang rewrite
  • 02Replacing a legacy language or framework incrementally while keeping the system live
  • 03Extracting a bounded context from a shared database to an independent service
  • 04Validating that the new service is correct by running both in parallel and comparing responses (dark launching)

When Not to Use

  • //If the legacy system is so tangled that identifying clean seams is impossible, refactor first
  • //Short-lived systems where a direct replacement is faster
  • //When the team cannot maintain two systems simultaneously without degrading both

Technical Notes

  • The proxy or anti-corruption layer (ACL) is the key mechanism. It translates between old and new contracts
  • Dark launching: route a percentage of production traffic to the new service without showing the result to users. Compare outputs to validate correctness
  • Database strangling is the hardest part: the old and new services often need to share a database initially, then migrate to separate stores
  • Feature flags (see below) are a natural companion: gradually roll the new route to increasing percentages of traffic