← Back to blog

Modernization · 7 min read

Strangling the monolith without strangling the business

Every legacy system is a load-bearing wall in a building people are still living in. You don't get to demolish it. You get to replace it one brick at a time, in the dark, without the tenants noticing.

I've migrated more legacy systems than I can count — classic ASP to .NET Core, on-prem data centers to Azure and AWS, .NET Framework 4.7.2 monoliths into microservices. The technology varies. The failure modes are remarkably consistent. Almost every modernization that goes badly went badly for the same reason: someone tried to do it all at once.

The big-bang rewrite is a trap

It's seductive. A clean greenfield codebase, no compromises, all the lessons applied. And it almost never works, because while you spend eighteen months building the replacement, the original keeps changing underneath you, the requirements drift, and you have nothing in production to show for it. Then the budget gets cut and you're left maintaining two systems instead of one.

The goal of modernization is not a beautiful new system. It's a continuously running business that happens to get better every sprint.

The strangler fig pattern, in plain terms

Name borrowed from a vine that grows around a host tree and gradually replaces it. The idea: stand up a thin routing layer in front of the legacy system, then peel off one capability at a time into new services. Each piece you carve out is small enough to ship, test, and roll back. The old system keeps serving everything you haven't migrated yet.

A migration I'd actually run looks like this:

The cut-over is a planning problem, not a coding problem

The riskiest moment in any modernization is the cut-over — the instant traffic moves from old to new. I've run high-stakes cut-overs for platforms serving tens of thousands of accounts, and the lesson is always the same: the code was the easy part. What makes it safe is the rehearsal. Run the cut-over in staging until it's boring. Have the rollback ready and tested. Pick a low-traffic window. Watch the dashboards like a hawk for the first hour.

Where AI fits now

Modern tooling genuinely helps here in a way it didn't five years ago. LLMs are good at reading unfamiliar legacy code and explaining what it does — invaluable when the original authors are long gone and the documentation is a myth. They can draft the first version of an extracted service, generate characterization tests against existing behavior, and translate between language idioms. They won't make the architectural calls for you. But they take a lot of the archaeology out of the work.

Modernization isn't glamorous. Done right, nobody outside the team even notices it happened — they just notice that things got faster, cheaper, and stopped breaking. That invisibility is the whole point.

Got a legacy system to modernize? →