Bird
Raised Fist0
Microservicessystem_design~7 mins

Strangler fig pattern in Microservices - System Design Guide

Choose your learning style10 modes available

Start learning this pattern below

Jump into concepts and practice - no test required

or
Recommended
Test this pattern10 questions across easy, medium, and hard to know if this pattern is strong
Problem Statement
Legacy monolithic applications become hard to maintain and update because all features are tightly coupled. Any change risks breaking unrelated parts, and rewriting the entire system at once is risky and costly.
Solution
The strangler fig pattern solves this by gradually replacing parts of the old system with new microservices. New features and components are built as separate services that intercept requests, while the legacy system continues to run. Over time, the old system is 'strangled' and fully replaced without downtime.
Architecture
Client
API Gateway
Legacy Monolith
Legacy Monolith

This diagram shows client requests routed through an API Gateway that directs some requests to new microservices and others to the legacy monolith, enabling gradual replacement.

Trade-offs
✓ Pros
Allows incremental migration reducing risk of full rewrite failures.
New features can use modern technologies without disrupting legacy code.
Minimizes downtime by running old and new systems in parallel.
✗ Cons
Requires maintaining two systems simultaneously, increasing operational complexity.
Routing logic can become complex as more services replace legacy parts.
Data consistency between old and new systems can be challenging.
When a large legacy system needs modernization but cannot be rewritten at once, especially if downtime must be minimized and incremental delivery is possible.
When the legacy system is small or simple enough for a full rewrite, or when the team lacks resources to maintain dual systems during migration.
Real World Examples
Netflix
Used the strangler fig pattern to migrate from a monolithic DVD rental system to a microservices architecture for streaming, enabling gradual feature migration.
Amazon
Applied the pattern to break down its monolithic retail platform into microservices, allowing independent scaling and faster feature deployment.
Spotify
Migrated from a monolithic backend to microservices incrementally, improving deployment speed and system resilience.
Code Example
This code shows how an API Gateway routes requests to either the legacy system or new microservices based on request type. This routing enables incremental replacement of legacy features with new services.
Microservices
### Before: Monolithic code handling all requests
class LegacySystem:
    def handle_request(self, request):
        if request.type == 'old_feature':
            return self.old_feature(request)
        # All features handled here

    def old_feature(self, request):
        # Implementation of old feature
        return f"Handled {request.type} in legacy system"

### After: Strangler fig pattern with routing
class APIGateway:
    def __init__(self):
        self.new_service = NewMicroservice()
        self.legacy = LegacySystem()

    def handle_request(self, request):
        if request.type == 'new_feature':
            return self.new_service.handle(request)
        else:
            return self.legacy.handle_request(request)

class NewMicroservice:
    def handle(self, request):
        # New feature implementation
        return f"Handled {request.type} in new service"

### Explanation:
# Before, the legacy system handled all requests in one place.
# After, the API Gateway routes new feature requests to the new microservice,
# while legacy requests continue to the old system, enabling gradual migration.
OutputSuccess
Alternatives
Big Bang Rewrite
Replaces the entire legacy system in one go instead of incrementally.
Use when: When the legacy system is small or outdated beyond repair and downtime is acceptable.
Branch by Abstraction
Introduces an abstraction layer to switch between old and new implementations without changing client routing.
Use when: When you want to hide migration complexity behind an interface and avoid routing changes.
Summary
The strangler fig pattern helps replace legacy systems incrementally by routing requests between old and new components.
It reduces risk by allowing gradual migration without downtime or full rewrites.
This pattern requires managing two systems simultaneously and careful routing logic.

Practice

(1/5)
1. What is the main goal of the Strangler fig pattern in microservices architecture?
easy
A. To build all new services from scratch before replacing the old system
B. To merge all services into a single monolithic application
C. To run the old and new systems completely separately without integration
D. To gradually replace parts of a legacy system with new services

Solution

  1. Step 1: Understand the pattern's purpose

    The Strangler fig pattern is designed to replace legacy systems gradually, not all at once.
  2. Step 2: Compare options with the pattern goal

    To gradually replace parts of a legacy system with new services matches the gradual replacement approach, while others describe different strategies.
  3. Final Answer:

    To gradually replace parts of a legacy system with new services -> Option D
  4. Quick Check:

    Gradual replacement = B [OK]
Hint: Strangler fig means gradual replacement, not all at once [OK]
Common Mistakes:
  • Thinking it replaces the whole system at once
  • Confusing it with parallel running without integration
  • Assuming it merges services into one
2. Which of the following is the correct way to route requests in the Strangler fig pattern?
easy
A. Send requests randomly to either legacy or new system without control
B. Direct all requests to the legacy system until the new system is fully ready
C. Route requests step-by-step from the legacy system to new microservices
D. Stop the legacy system completely before routing any requests

Solution

  1. Step 1: Identify routing strategy in Strangler fig

    The pattern routes requests gradually from old to new components, not all at once or randomly.
  2. Step 2: Match options with routing approach

    Route requests step-by-step from the legacy system to new microservices describes step-by-step routing, which fits the pattern best.
  3. Final Answer:

    Route requests step-by-step from the legacy system to new microservices -> Option C
  4. Quick Check:

    Step-by-step routing = A [OK]
Hint: Route requests gradually, not all or random [OK]
Common Mistakes:
  • Routing all requests to legacy until full switch
  • Routing requests randomly causing inconsistency
  • Stopping legacy before new system ready
3. Consider this simplified request flow in a Strangler fig pattern:
Legacy system handles requests for features A, B, C.
New microservice replaces feature A.
Requests for A go to new service; B and C go to legacy.
What happens when a request for feature B arrives?
medium
A. It is routed to the new microservice handling feature A
B. It is routed to the legacy system since B is not replaced yet
C. It causes an error because feature B is missing in new service
D. It is dropped and not processed

Solution

  1. Step 1: Analyze routing rules for features

    Only feature A is replaced by the new microservice; B and C remain in legacy.
  2. Step 2: Determine routing for feature B request

    Requests for B still go to legacy system as it is not replaced yet.
  3. Final Answer:

    It is routed to the legacy system since B is not replaced yet -> Option B
  4. Quick Check:

    Feature B not replaced = legacy route = C [OK]
Hint: Unreplaced features stay on legacy system [OK]
Common Mistakes:
  • Routing all requests to new service regardless of feature
  • Assuming missing features cause errors
  • Dropping requests instead of routing properly
4. A team tries to apply the Strangler fig pattern but routes all requests to the new microservice before it fully supports all features. What is the main problem with this approach?
medium
A. It leads to inconsistent behavior as new service lacks some features
B. It causes downtime because legacy system is stopped too early
C. It improves performance by forcing early migration
D. It simplifies deployment by removing legacy dependencies

Solution

  1. Step 1: Identify issue with premature routing

    Routing all requests early means new service may not handle all features yet.
  2. Step 2: Understand impact on system behavior

    This causes inconsistent or failed responses for unsupported features.
  3. Final Answer:

    It leads to inconsistent behavior as new service lacks some features -> Option A
  4. Quick Check:

    Premature routing = inconsistent behavior = A [OK]
Hint: Route only supported features to new service [OK]
Common Mistakes:
  • Thinking early routing improves performance always
  • Assuming legacy can be stopped immediately
  • Ignoring feature support gaps
5. You are designing a migration plan using the Strangler fig pattern for a large monolithic app with features X, Y, and Z. Feature X is critical and must have zero downtime. How should you apply the pattern to ensure smooth migration?
hard
A. Replace feature X first with a new microservice and route only X requests there, keep Y and Z on legacy
B. Replace all features at once to avoid partial routing complexity
C. Stop the legacy app and start new microservices for all features simultaneously
D. Keep all features on legacy until new system is fully ready, then switch all at once

Solution

  1. Step 1: Prioritize critical feature migration

    Feature X requires zero downtime, so migrate it first carefully.
  2. Step 2: Apply gradual routing for feature X only

    Route requests for X to new microservice while Y and Z remain on legacy to reduce risk.
  3. Step 3: Avoid full switch or stopping legacy abruptly

    The other options risk downtime or complexity by switching all features at once.
  4. Final Answer:

    Replace feature X first with a new microservice and route only X requests there, keep Y and Z on legacy -> Option A
  5. Quick Check:

    Gradual critical feature migration = D [OK]
Hint: Migrate critical features first, route requests gradually [OK]
Common Mistakes:
  • Trying to replace all features at once
  • Stopping legacy before new system ready
  • Delaying critical feature migration