0
0
Microservicessystem_design~7 mins

Strangler fig pattern in Microservices - System Design Guide

Choose your learning style9 modes available
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.