Skip to content
Simran's Writing Room
Menu
  • Blogs
  • Books
  • About
Menu

Migrating Legacy Systems: Strangler Fig, Branch by Abstraction, and Parallel Run Explained

Posted on by Simran Chawla

Migrating away from legacy monoliths can feel like navigating a labyrinth, but strategic patterns like Strangler Fig, Branch by Abstraction, and Parallel Run simplify the journey. Here’s a quick dive into how they work, when to use them, and how to decide when to switch completely to the new implementation.


1. Strangler Fig Applications

  • What It Is: Gradually replace monolith functionality by routing calls to new microservices. Over time, the monolith “withers” away.
  • When to Use: When functionality is easily identifiable and can be routed externally using proxies.
  • When to Switch: Once all functionality is migrated, no active dependencies remain, and the new system is stable.
  • How to Switch: Remove routing rules to the old monolith and decommission the corresponding components.
strangler-fig

2. Branch by Abstraction

  • What It Is: Introduce an abstraction layer in the codebase to allow old and new implementations to coexist until the transition is complete.
  • When to Use: When functionality is deeply coupled within the monolith, requiring internal refactoring to extract it.
  • When to Switch: Once the new implementation meets functional and nonfunctional requirements, and bugs/inconsistencies are resolved.
  • How to Switch: Activate the new implementation using feature toggles, remove the old implementation, and clean up the abstraction layer.
branch-by-abstraction

3. Parallel Run

  • What It Is: Run old and new implementations side by side, comparing their outputs to validate the correctness of the new system.
  • When to Use: For high-risk migrations where accuracy and performance must be verified before switching.
  • When to Switch: Once the new implementation consistently produces equivalent results, meets performance thresholds, and discrepancies are resolved.
  • How to Switch: Declare the new implementation as the source of truth and retire the old system.
parallel-run

Summary of Differences

Here’s a handy comparison table:

Aspect Strangler Fig Branch by Abstraction Parallel Run
Focus Incremental external replacement Internal decoupling with abstractions Simultaneous validation of old and new
Transition Approach Redirects calls to new service Coexists via an abstraction layer in code Calls both implementations in parallel
Rollback Easy (via redirection) Via feature toggle Retain old implementation as fallback
When to Use Clear routing path for migration Tightly coupled functionality High-risk migrations
Challenges Duplicated functionality Code complexity, data consistency Resource overhead, managing side effects

Key Takeaways

  • Use Strangler Fig for external routing and phased replacement of well-isolated functionality.
  • Choose Branch by Abstraction when working with deeply embedded functionality that requires code refactoring.
  • Opt for Parallel Run for high-risk, mission-critical transitions where correctness and performance must be validated.

Each of these patterns can complement one another as part of a cohesive migration strategy.

© 2025 Simran's Writing Room