When our COBOL backend started holding up a mobile ordering feature, I got asked to modernize it. I thought it would be a technical project. It wasn't. It was mostly about fear, and the fear went both ways. The business was terrified of downtime, and my team was terrified of the old codebase nobody really understood anymore.
We started with the classic mistake: we picked the easiest module to replace, not the one with the highest business pain. I wanted a quick win to build confidence. So we rewrote the reporting module first. It took four months, used a new stack, and looked beautiful in demos. Problem was, the reporting module wasn't what kept people up at night. The order entry system was. And while we spent all that time on a clean, modern reporting dashboard, the order entry system got worse because we'd frozen all changes to it.
That freeze was my decision. I thought we needed stability to focus. Instead, we created a backlog of urgent patches that the business needed yesterday. By the time we finally turned to order entry, we had six months of deferred fixes and a lot of unhappy operations folks. I remember standing in a conference room with the warehouse manager, who showed me a printed stack of workaround notes her team had taped to their monitors. That was the real legacy system: not the old code, but the workarounds around it.
So we changed strategy. We stopped trying to replace entire systems and started carving out narrow, high-pain slices. We identified the order validation step as the one where people spent the most time fighting the old screen. Instead of rewriting all of order entry, we built a small service that handled just the validation rules, with a simple API. The old system called it, and we deployed that single piece to production in two weeks. It wasn't glamorous. It didn't have a new dashboard. But it cut the warehouse team's manual rework by something like forty percent.
That taught me the lesson I now repeat to every client: don't modernize the system, modernize the pain. Find the place where the old thing actually hurts someone's day, and fix just that. Then repeat. The strangler fig pattern works, but only if you strangle the right branch first.
Another thing I got wrong early on was ignoring the data. We assumed the old database was fine because it had been running for years. It wasn't. There were duplicate customer records, orphaned order lines, and fields with values nobody could explain. When we eventually moved the validation rules to the new service, we spent more time cleaning up bad data than writing code. Now I tell teams to budget at least a third of any modernization effort for data cleanup, mapping, and reconciliation. You'll thank yourself later.
The boring truth is that legacy modernization is not a big bang project. It's a long series of small, unglamorous replacements, guided by whoever complains the loudest about the current system. And you have to involve the people who use it every day, not just the architects. The warehouse manager who taped notes to monitors ended up being the best product owner we ever had. She knew exactly which pain to fix next.