Migrating a Banking Monolith Without Stopping the Business
The Strangler Fig in Practice
The Strangler Fig in Practice
Legacy core banking systems rarely fail loudly. They fail slowly — through mounting change-request backlogs, brittle integrations, and engineering teams who spend more time protecting the system than improving it. A full rewrite is rarely the answer: for a bank running mission-critical infrastructure, a "stop the world, rebuild everything" migration is a regulatory and operational risk few institutions can justify. The strangler fig pattern offers a more pragmatic path — decompose the monolith incrementally, in production, while the business keeps running on it.
Named after the strangler fig vine, which grows around a host tree until it eventually replaces it, the pattern works by intercepting traffic at the edge. An API gateway sits in front of the monolith and routes requests either to the legacy system or to a newly extracted service, depending on which one now owns that capability. Over time, more traffic is routed to new services, and the monolith's footprint shrinks — until what remains is small enough to retire outright or leave in place as a low-risk residual system.
The advantage for banking specifically is continuity. There is no cutover weekend, no single point where the whole platform is at risk, and no moment where regulatory reporting or payment processing stops while engineers migrate data. Risk is distributed across many small, reversible steps instead of one large, irreversible one.
The order in which services are extracted determines whether the migration succeeds or stalls. A useful sequencing principle: extract by coupling, not by convenience.
Start with edge capabilities that have few dependencies on shared state — notification services, document generation, or read-only reporting endpoints are common first candidates.
Move to bounded, well-understood domains next: KYC/onboarding workflows or card management are typically more self-contained than core ledger operations.
Leave the ledger and settlement core for last. These are the highest-risk, highest-coupling components, and by the time a team reaches them, the gateway routing logic, dual-write patterns, and rollback procedures should already be proven on lower-stakes services.
Extracting the riskiest component first is the most common cause of stalled strangler fig migrations — teams underestimate the operational complexity and lose confidence in the pattern before it has a chance to prove itself.
The hardest technical problem in this pattern is rarely the new service itself — it's keeping data consistent while both the monolith and the extracted service can write to overlapping domains during the transition window.
Event-based synchronization, using a system like Kafka with Flink for stream processing, publishes changes from the monolith as events that the new service consumes to build its own data store. This avoids direct coupling between the old and new write paths but introduces eventual consistency, which needs careful handling for anything touching account balances or transaction state.
Synchronous dual writes, where the application layer writes to both systems within the same transaction boundary, offer stronger consistency guarantees but tightly couple the migration timeline to both systems' availability. This approach is more defensible for regulatory reporting data, where eventual consistency is harder to justify to an auditor.
Whichever approach is used, reconciliation jobs that compare state between the legacy and new systems are not optional — they are the mechanism that catches drift before it becomes a customer-facing incident or a compliance finding.
Most banking monoliths are built around a single, deeply shared database, and this is usually the real obstacle to extraction — not the application code. A service can't be considered "extracted" if it still reads and writes directly against tables owned by the monolith.
The practical sequence is: introduce a data ownership boundary before extracting the service that will own it. This typically means creating a dedicated schema or database for the new service, backfilling it from the monolith's data, and routing the monolith itself through an API or event stream rather than direct table access — effectively strangling the database access pattern before strangling the application logic. Skipping this step is why many extraction attempts end up with a "distributed monolith": separate deployables that are still fully coupled at the data layer.
For banks operating under DORA, the migration itself is an ICT risk event that needs to be managed, not just an engineering initiative. This has practical implications:
Change management records need to reflect each extraction as a discrete, auditable change, not a single undocumented "migration in progress" state that spans months. Incident response and business continuity plans must account for the transition architecture — including what happens if the API gateway or an event stream becomes unavailable — not just the end-state architecture.
Data residency and access control requirements apply equally to the newly extracted services and their intermediate data stores, not only to the original system.
Institutions that treat the migration architecture itself as in-scope for regulatory review, rather than something to document only after the fact, avoid the most common compliance friction point in these programmes.
Backend decomposition is often planned as though client applications are passive consumers, but for teams maintaining a React Native banking app, the strangler fig migration has direct consequences that need coordination, not just notification.
API contract stability matters more than usual. As the gateway routes a given endpoint from the monolith to a newly extracted service, the response shape, error codes, and latency profile can all shift — even when the gateway is designed to preserve the external contract. Version the API explicitly at the gateway level, and treat any contract drift as a breaking change requiring app-side testing, not an internal implementation detail.
Latency and offline handling need re-validation per extracted service. A newly extracted service backed by event-based synchronization may introduce eventual consistency that wasn't present when the monolith served that data synchronously. For screens showing balances or transaction history, this can surface as stale data immediately after an action — something the RN app's caching and optimistic-update logic needs to account for, and something worth testing explicitly as each service goes live behind the gateway.
Feature-flag the client against the migration timeline. Because extraction happens incrementally, the mobile app benefits from the same incremental posture — using remote feature flags to control which client version talks to which backend path, rather than shipping a single release that assumes the entire migration is complete. This also gives the mobile team a fast rollback path if a newly extracted service needs to be rolled back at the gateway.
Involving mobile engineering early in the extraction sequencing — not just at integration testing — avoids a common failure mode where backend teams consider a service "migrated" while the client layer is still silently depending on monolith-specific behavior.
The strangler fig pattern succeeds when each extraction is small enough to be low-risk and reversible, and fails when teams treat it as a shortcut to avoid planning a real target architecture. The pattern is a delivery mechanism, not a substitute for architectural decisions about service boundaries, data ownership, and consistency guarantees — those decisions still need to be made deliberately, before the first line of extraction code is written.
For banks and payment companies running on aging infrastructure, this is what makes strangler fig viable where a full rewrite isn't: it lets the business keep operating at full capacity while the architecture underneath it changes, one bounded, auditable extraction at a time.