Process What we build Team Blog Contact
Services Custom Software Development SaaS Platform Development AI Products & Automation Startup MVP Development Web & Mobile Apps Cloud Infrastructure & DevOps Full-Cycle QA & TestingLegacy ModernizationDevelopment OutsourcingSupply Chain Hardening Landing & Business Sites IT Cost Estimator SaaS Cost CalculatorAI Agent BuilderSaaS Cost Guide Start a project →
Home Blog Strangler Fig Pattern
Legacy Modernization

Legacy System Modernization Without a Rewrite: The Strangler Fig Pattern Explained

Full rewrites of business-critical systems fail more often than they succeed. Here's the incremental alternative that lets you modernize a legacy system while it keeps running the business.

Why the "big rewrite" keeps failing

The instinct when a legacy system becomes unbearable is to freeze feature work, rebuild it properly from scratch, then cut over. It's an understandable instinct and it goes wrong constantly, for a consistent set of reasons: the rewrite takes far longer than estimated because the old system's edge cases were never written down anywhere except its own code; the business can't actually freeze feature requests for a year while engineering rebuilds; and the cutover itself is a single high-stakes event where every latent difference between old and new becomes a production incident at once.

None of this means legacy systems shouldn't be modernized. It means the rewrite-and-cutover approach is the wrong tool for systems that are still running the business while you fix them.

What the strangler fig pattern actually is

Named after the strangler fig vine, which grows around a host tree and gradually replaces it without the tree ever fully disappearing until the very end. Applied to software: instead of rebuilding the whole system and switching over at once, you put a routing layer in front of the legacy system and move traffic to new, properly-built components one piece at a time. The legacy system keeps running everything you haven't migrated yet. Nothing is ever fully "down" during the process, and if a newly migrated piece has a problem, you route that traffic back to the legacy system while you fix it.

The core idea in one line

You're not replacing the system. You're replacing pieces of it, one at a time, behind a routing layer that makes the transition invisible to everyone who depends on it — including your own team, most of the time.

How it actually plays out, phase by phase

Zero
Planned downtime — the system keeps serving traffic through every phase
Per-route
Rollback granularity — a bad migration affects one slice, not everything
Continuous
Business value delivery — no multi-quarter feature freeze while it happens

Where teams get it wrong

Two mistakes account for most strangler fig projects that stall out. The first is skipping the mapping phase and migrating whatever seems easiest, which usually means discovering a critical undocumented behavior three pieces in in production, not two. The second is treating the routing layer as a temporary hack rather than real infrastructure — it needs the same monitoring, testing, and on-call attention as anything else in the request path, because for the duration of the migration, it is the request path.

Have a legacy system nobody wants to touch?

We'll map what it actually does — not what the documentation says — before proposing anything.

Talk to us about your legacy system →

Frequently asked questions

How long does a strangler fig migration take compared to a rewrite?

Longer end-to-end in most cases — but the business keeps getting value and keeps running throughout, instead of betting everything on a single cutover date. The comparison that matters isn't total calendar time, it's risk and continuity.

Does this work for a system with no tests and no documentation?

It's often the better option specifically because of that — the parallel-run-and-verify step (routing real traffic to both old and new, comparing outputs) becomes your test suite, discovering the undocumented behavior as you go rather than assuming you already know it.

What if the legacy system's database schema is the actual problem?

The pattern still applies — the routing layer and the migration phases can operate at the data layer too, not just the request layer, migrating data ownership piece by piece with the same parallel-run safety net.

Is this pattern only for large enterprise systems?

No — the principle (incremental replacement behind a routing layer, verified before cutover) scales down to a single problematic module in a smaller codebase just as well as it scales up to a monolith.

HS
Written by the Hardened Soft engineering team
We write about the decisions we make on real client projects — cost trade-offs, architecture patterns, and the parts of a build that don't show up in a sales pitch.