Legacy systems don't survive because they're good. They survive because they work — which is exactly why no one funds the rewrite. The job isn't to replace everything. It's to modernize in a way that pays off at every stage instead of asking leadership to bet on a multi-year rewrite with no return until the end.
3–6 min read
Key Takeaways
There was a running joke at one company I worked at about the "summer rewrite" — the season we'd finally get approval to modernize the codebase, clean up the architecture, retire the parts everyone was afraid to touch. It never came. Not one summer. The code kept working, and working code is the single hardest thing in the world to get budget to replace.
That joke contains the whole problem. Most companies don't have a technology problem. They have a prioritization problem. The legacy system is ugly, it's fragile, it's slow to change — and it ships value every day. "It works" is a complete sentence to a CFO. So the rewrite stays in the someday column, the debt compounds, and the engineers who have to live in it keep waiting for a summer that never arrives.
An engineering leader who walks in promising to fix all of that with a new stack and a multi-year plan is asking leadership to fund a bet that returns nothing until the very end. That's the pitch they've learned to say no to. The job isn't to rewrite everything. It's to build a modernization strategy that delivers value at every stage — so the work earns trust before it ever has to earn budget. That holds whether you're setting the strategy or arming the leadership above you with a case they can actually approve.
You can't prioritize what you don't understand, and you can't understand a legacy system by looking at its source. You understand it by looking at what it costs the business.
So the first work is mapping, not coding. You're hunting for four things: what's blocking something the business actually wants — a feature that can't ship, a scale ceiling you keep hitting, a partner you can't integrate. What's concentration risk, where one person is the documentation. What sits in the path of feature work so often that every new request pays a tax to route around it. And what's causing real operational pain — the bottleneck that wakes someone up at night.
That last one is where the money usually hides. I've watched a callback-processing layer quietly become the constraint on an entire platform — not because anyone designed it badly, but because the volume outgrew the design. That's worth modernizing. The module that's merely ugly, that offends you every time you open it but costs the business nothing, is not. Ugly is not a business case. The discipline is refusing to spend the company's money on your aesthetic discomfort, and spending it where the system is actually bleeding.
There's a popular idea that a new leader should spend their first ninety days quietly observing before changing anything. I don't buy it. Watching is not leadership; it's tourism. You don't earn standing by conspicuously holding still.
You earn it by being useful immediately. The first thirty to sixty days are observe-and-adjust — learn the system, understand why it is the way it is, and make the cheap efficiency tweaks that demonstrate competence while you assemble the real plan of attack. Because the legacy code you inherited isn't an accident. Someone made deliberate decisions to keep it, under constraints you don't see yet. Understand the why before you touch the what, or you'll propose tearing out the exact load-bearing wall that's holding the building up.
Credibility comes from fixing small things visibly and well before you ask for the latitude to fix the large ones. You earn the mandate for big changes by being trustworthy with small ones first — that's the bridge between knowing what's worth modernizing and being allowed to do it.
Once you know what matters and you've earned the room to act, the mechanism is incremental — not because incrementalism is fashionable, but because the big-bang rewrite is the bet leadership already declined.
So you don't ask for it again. You modernize where it matters, and you architect every piece of new feature work with the modernization in mind. The new feature isn't just a feature — it's a beachhead for the architecture you're moving toward. Wrap the old, build the new alongside it, migrate the traffic, retire what's left. The old system shrinks one deliberate piece at a time, and each piece ships value on its own. No summer required.
The reframe is the whole point: you're not running a modernization project that the business has to fund as a line item. You're making the codebase get better as a byproduct of work the business is already paying for. Modernization stops being a bet and becomes a property of how the team operates.
Here's the part that surprises people who expect a new leader to show up and start architecting. Your first deliverable isn't new code. It's the process that makes modernization sustainable.
Coding standards so "modernize on contact" produces something consistent instead of ten engineers' ten opinions. Automated testing so you can change legacy code without holding your breath. Release governance so incremental migration doesn't turn into incremental breakage. Observability so you can prove the bottleneck you fixed was actually the bottleneck. None of that is glamorous, and all of it is what separates a modernization that compounds from one that happens once, heroically, and then rots again the moment you look away.
It's the same principle as everything above: you're building the conditions for value to keep arriving, not staging a single dramatic delivery. Standards, testing, and observability are what let a team modernize quietly and continuously — without ever needing a summer.
Legacy systems don't get replaced because they're bad. They get replaced because someone finally made modernization cheaper than living with them — one funded win at a time.
Scaling Decision-Making: How to Stay Collaborative Without Losing Authority
As engineering organizations grow, decision-making becomes one of the hardest things to scale. Too centralized and you become a bottleneck. Too distributed and you lose coherence. The answer is a model where collaboration is genuine, authority is clear, and the reasoning behind hard calls is transparent enough that people can commit even when they disagree.
Read moreWhen a Library Upgrade Is Actually an Architecture Migration
A routine "update our libraries" request turned into a multi-phase architecture modernization once dependency audits revealed active CVEs, a pre-release dependency blocking the entire upgrade chain, and architectural coupling across three critical subsystems. The most important decision was reframing the scope before anyone estimated it — then presenting leadership with two paths so they could make a real tradeoff decision.
Read moreTaming 50 Million Callbacks with Event-Driven Architecture
A legacy .NET HttpHandler buried inside the customer portal was processing webhook callbacks synchronously — and at 20M+ messages a month, vendor retry storms inflated that to 75 million callbacks with 90-second processing latency. We replaced it with an Azure Function that acknowledges in milliseconds and routes to channel-isolated processors via Service Bus, dropping latency to sub-second and eliminating the retry cascade entirely.
Read more