Recommended resources
The freely available resources this lesson will direct you to.
- The Strangler Pattern | Designing Event-Driven Microserviceswww.youtube.com
- Strangler Fig Pattern | System Design | Migrate Monolithic Application to Microservices Architecturewww.youtube.com
- The Strangler Fig Pattern: A CTO's Guide to Legacy System Modernization - | WireApps Blogwww.wireapps.co.uk
- Move Your Monolithic Projects to Microservice Structures with the Strangler Design Pattern | by İnci KÜÇÜK | Stackademicblog.stackademic.com
Introduction
In our last lesson, we established a crucial safety net for working with legacy code: characterization testing. You learned how to capture the existing behavior of a system, bugs and all, to ensure that any refactoring doesn't introduce unintended regressions. With that foundation in place, we can now move from safely changing code within a legacy system to safely replacing it piece by piece.
This lesson introduces the Strangler Fig pattern, a powerful architectural strategy for incrementally modernizing a monolithic application. Coined by Martin Fowler, the pattern is inspired by a type of fig tree that grows around a host tree, eventually replacing it entirely. Similarly, this software pattern allows you to build a new system around the edges of an old one, gradually routing functionality to modern services until the legacy monolith can be retired. For a developer on the path to senior roles, mastering this pattern is key to tackling large-scale technical debt and leading modernization initiatives.
1. The Problem with the "Big Bang" Rewrite
Before diving into the Strangler Fig pattern, it's essential to understand the approach it replaces: the "big-bang" rewrite. This is the intuitive but often disastrous strategy of trying to replace an entire monolithic application in one go.
The Strangler Fig Pattern: A CTO's Guide to Legacy System Modernization - | WireApps Blog
This guide from WireApps clearly articulates the common pitfalls of large-scale rewrites, setting the stage for why an incremental approach is often superior.
Please read the section titled The Problem with Big-Bang Rewrites. As you read, reflect on the business and technical risks described. Why might a project that aims to deliver all its value at the very end be prone to failure?
The core issue with a big-bang rewrite is that it postpones value delivery and accumulates risk. The business can't stand still while a new system is being built, so the legacy system continues to evolve, making the new system a constantly moving target. The Strangler Fig pattern offers a more pragmatic, iterative alternative.
2. The Strangler Fig Pattern: A Conceptual Overview
The Strangler Fig pattern allows you to de-risk modernization by breaking it into small, manageable steps. You build new, modern services around the existing legacy system, and a routing layer directs traffic to either the new service or the old monolith, one feature at a time.
This video from Confluent provides an excellent visual and conceptual introduction to the pattern.
The Strangler Pattern | Designing Event-Driven Microservices
This video effectively explains the botanical analogy and contrasts the Strangler pattern with the risky "wholesale replacement" approach.
Watch from the beginning of the video. Pay close attention to how the "facade" is introduced and how it enables features to be reimplemented and rerouted incrementally, causing the monolith to "shrink" over time.
The process can be visualized in three distinct phases: an initial state where all traffic hits the monolith, an incremental migration phase where traffic is split, and a target state where the monolith is fully decommissioned.

3. The Mechanics of the Strangler Fig Pattern
Executing this pattern successfully involves a systematic process and several key implementation techniques. Let's break down the steps.
Step 1: Identify a Seam and Choose a Capability
The first step is not to write code, but to analyze the legacy system. You need to find a "seam"—a logical boundary where you can intercept calls to a specific piece of functionality. Once you've identified potential seams, you must choose the first capability to migrate.
The Strangler Fig Pattern: A CTO's Guide to Legacy System Modernization - | WireApps Blog
This part of the guide provides a clear framework for selecting a good first candidate for migration.
Read the sections The Strangler Fig Alternative and Choosing What to Migrate First. The criteria listed—clear boundaries, limited dependencies, high value, and low risk—are crucial for gaining initial momentum and proving the pattern's value to stakeholders.
Step 2: Implement and Verify the New Service
With a candidate capability chosen, you build its replacement as a new, independent service (e.g., a Spring Boot microservice). The critical challenge is proving that this new service behaves identically to the legacy implementation. This is where your work from the previous lesson becomes invaluable, alongside a technique called "shadow mode."
- Characterization Tests: The characterization tests you designed to put a safety net around the legacy code now serve as the contract for your new service. The new implementation is "correct" when it passes the same set of characterization tests as the old one.
- Shadow Mode: This powerful technique involves modifying the routing layer to send incoming requests to both the legacy system and the new service in parallel. The response from the legacy system is returned to the user, so their experience is unaffected. In the background, you compare the responses from both systems and log any discrepancies. This allows you to test the new service with real production traffic without any risk.
This sequence diagram illustrates the flow of a request in shadow mode.

You can run in shadow mode for days or weeks, fixing bugs in your new service until the logged discrepancies fall to zero. This gives you extremely high confidence before you switch any real user traffic.
Step 3: Gradual Rollout with Feature Flags
Once you have verified the new service's correctness, you can begin to strangle the old functionality. Instead of a hard cutover, you use feature flags in the routing layer to control the flow of traffic.
The Strangler Fig Pattern: A CTO's Guide to Legacy System Modernization - | WireApps Blog
This section of the guide details the verification and rollout strategies.
Read the subsections Shadow Mode and Feature Flags for Gradual Rollout. This phased approach is the key to minimizing risk during the migration.
A typical rollout strategy might be:
- Internal Team Only: Route requests from your own team to the new service.
- Canary Release: Route 1% of public traffic to the new service.
- Incremental Increases: Gradually increase the percentage (10%, 50%) while closely monitoring performance and error metrics.
- Full Rollout: Route 100% of traffic to the new service.
- Strangle: Once the new service is stable, you can safely delete the old code from the monolith.
You then repeat this entire process for the next capability, incrementally strangling the legacy system feature by feature.
4. A Practical Example in Spring Boot
Given your background in Java and Spring Boot, let's look at how these concepts translate into a concrete implementation. An API Gateway, such as Spring Cloud Gateway, typically serves as the routing layer.
This article from Stackademic provides a practical walkthrough that aligns directly with your technical expertise.
First, read the section Application in a Spring Boot Project, which describes the key components: microservices, an API gateway, feature toggles, and data migration. Next, carefully review the code example under Step-by-Step Implementation. This demonstrates how Spring Cloud Gateway can be configured with routing rules to direct traffic to a legacy service (/api/legacy/products) and a new microservice (/api/new/products). This is the "facade" in action.
This example provides a clear blueprint. In a real-world scenario, the gateway configuration would be more dynamic, likely controlled by a feature-flagging service to enable the gradual rollout we discussed.
5. Practical Application: Plan a Strangler Migration
It's time to create another "paper trail of competence." You will draft a high-level plan for migrating a single feature from a hypothetical (or real) monolithic application using the Strangler Fig pattern. Create a new document in your personal knowledge base (Notion, Obsidian, etc.).
Task: Create a Strangler Fig Migration Plan
For a feature of your choice (e.g., "User Profile Management," "Product Search," "Order Validation"), create a document with the following sections:
-
Capability Analysis:
- Feature: Name the feature you've chosen to migrate.
- Justification: Explain why this feature is a good first candidate, using the criteria from the WireApps guide (clear boundaries, low risk, high value, etc.).
-
Technical Strategy:
- Routing Layer: Propose a tool for the facade (e.g., Spring Cloud Gateway, Nginx, Zuul). Briefly describe how you would configure an initial rule to proxy traffic for this feature's endpoint(s) (e.g.,
/api/users/{id}) to the legacy monolith. - Data Strategy: Will the new microservice share the legacy database directly, or will it have its own database? If it has its own, how might you keep data synchronized during the transition? (A brief, high-level thought is sufficient here).
- Routing Layer: Propose a tool for the facade (e.g., Spring Cloud Gateway, Nginx, Zuul). Briefly describe how you would configure an initial rule to proxy traffic for this feature's endpoint(s) (e.g.,
-
Verification and Rollout Plan:
- Verification: Describe how you would use Shadow Mode to validate the new service. How would the characterization tests from our previous lesson be used as a contract to ensure behavioral equivalence?
- Rollout: Outline a phased rollout plan using feature flags. List the stages (e.g., Internal users -> 5% of traffic -> 50% -> 100%) and the key metrics you would monitor at each stage (e.g., error rates, response latency, business KPIs).
-
"Strangle" Step:
- What is the final step once 100% of traffic is successfully served by the new microservice? What happens to the old code in the monolith?
Completing this plan will solidify your understanding of the entire lifecycle of migrating one piece of a system, giving you a repeatable blueprint for future modernization efforts.
Conclusion
Today you've moved beyond refactoring in a monolith to a strategy for escaping it altogether. The Strangler Fig pattern is a cornerstone of modern software architecture, enabling teams to pay down technical debt and innovate without the immense risk of a big-bang rewrite.
Key Takeaways:
- Avoid Big-Bang Rewrites: They are high-risk projects that often fail due to moving business requirements and delayed value delivery.
- Embrace Incrementalism: The Strangler Fig pattern de-risks modernization by replacing a legacy system one piece at a time.
- The Facade is Key: A routing layer (like an API Gateway) is the central component that directs traffic, enabling shadow mode and gradual rollouts.
- Verify, Then Roll Out: Use shadow mode and characterization tests to gain confidence in the new service before exposing it to users with a gradual, feature-flag-driven rollout.
- Strangle and Repeat: Once a feature is fully migrated, the old code is removed, and the process repeats for the next feature.
With the ability to write characterization tests and now a strategy to apply them in a large-scale migration, you have two of the most critical skills for a senior engineer tasked with improving a legacy codebase. In our next lesson, we will focus on ensuring the new code you write is of high quality by learning how to conduct a constructive code review, preventing the creation of tomorrow's legacy systems.