Legacy database? How to adopt the Strangler Fig pattern
Learn how to migrate monolithic legacy databases to modern microservices using the Strangler Fig pattern incrementally and safely.
Summary
- The Strangler Fig pattern replaces old systems gradually by intercepting calls and routing them to the new architecture
- Dual data replication keeps the legacy database and the microservice synchronized during the transition without business downtime
- Ensuring transactional consistency requires strategies like the Outbox pattern to prevent message loss between distinct systems
- Traffic routing at the application layer or API Gateway dynamically decides who answers each query or write operation
- Shutting down old tables requires rigorous metric monitoring to confirm the total absence of remaining dependencies
The challenge of touching a giant legacy database
Every growing company accumulates older systems, commonly known as monoliths. In these systems, a single database holds the core working logic of the entire business, mixing customer tables, payments, and inventory in a complex web of dependencies. In practice, this means altering a single column can crash the entire application, causing fear and paralysis within the development team.
When architecture needs to evolve toward microservices, which are small independent services focused on specific tasks, the monolithic database becomes the primary obstacle. Trying to rewrite everything at once is a historical mistake that usually fails due to excessive time consumption and interrupting business value delivery. It is precisely in this critical scenario that an incremental strategy becomes necessary, allowing environment modernization without halting operations.
What is the Strangler Fig pattern and how it works in practice
The concept of the Strangler Fig comes from nature: the strangler fig is a plant whose seeds land in the canopies of tall trees, growing by embracing the trunk and sending roots to the ground until the original tree dies and the fig takes its place. In software engineering, the idea is identical. Instead of destroying the old system, we build a new structure around it, replacing functionalities piece by piece.
Applying this concept to databases, you do not migrate all tables over a single weekend. You choose an isolated domain, such as customer management, and build a new microservice with its own optimized database. As seen when structuring refactoring in messy legacy code and incremental refactoring, safety lies in short, validated, and continuous steps that protect system integrity.
Synchronization strategies with dual data replication
During the transition, both the new and old applications must coexist and see the same data. The biggest technical challenge of this phase is synchronization. If a customer updates their address in the new interface, that change must reflect immediately in the legacy database; otherwise, other parts of the company relying on the old system will break.
A common approach to resolve this impasse is dual replication, where the application writes to both the legacy and new databases during a transitional period. However, writing to two distinct places opens room for consistency failures when one operation fails. To mitigate this operational bottleneck risk and ensure stability, many engineers combine this approach with resilience techniques similar to those applied when managing network failures and solving Node.js API instabilities with circuit breaker.
Using the Outbox pattern to guarantee transactional consistency
When two databases must be kept in sync, distributed transactions based on two-phase commit protocols tend to be slow and prone to locks. An elegant alternative widely adopted in modern architectures is the Transactional Outbox pattern, which uses an auxiliary table in the database to record change events.
In practice, when a row is inserted or modified in the legacy database, the application writes a corresponding event into an outbox table within the same database transaction. A secondary process, called a publisher, reads this output table and dispatches messages to an event bus or directly to the new microservice. This ensures no data is lost, even if the network fails momentarily or the microservice is temporarily unavailable.
Smart traffic routing between the monolith and the microservice
With data synchronized, the next step is deciding who handles each user request. Traffic routing acts as an intelligent doorman at the application's entrance, usually implemented through an API Gateway or rules configured in a reverse proxy like Nginx or Caddy.
Initially, one hundred percent of read and write calls go to the monolith. As the new microservice gains maturity and stability in production, routing starts directing small percentages of traffic to the new API — for instance, ten percent of users start using the new profile service. If any anomalous behavior or severe slowness occurs, comparable to the issues described in how to find disk IOPS bottlenecks in Linux, traffic can be instantly reverted to the monolith without noticeable impact.
Identifying and safely removing orphaned code and tables
The Strangler Fig cycle is only complete when old code and tables are entirely wiped from the monolith. However, the fear that some hidden feature still relies on that legacy structure paralyzes many developers during final cleanup.
To perform this cleanup safely, use audit logs and database access metrics to track whether any query still touches legacy tables. Monitor system behavior for several weeks of normal operation before executing final deletion. This discipline avoids unpleasant surprises in production and consolidates the independence of the new microservice.
Final considerations on incremental database migration
Adopting the Strangler Fig pattern requires patience, rigorous planning, and cultural maturity from the engineering team. Migration stops being a stressful big-bang event and becomes a continuous architectural evolution. By decoupling databases gradually, your company gains delivery speed, operational resilience, and the freedom to scale services independently according to business demand.