A pattern from three recent engagements: how to modernize a legacy stack without the multi-year rewrite that nobody really wants.

The default modernization plan, when a client first talks to us about it, is usually a rewrite. The default rewrite plan is two years. The default actual outcome, after the first delay and the second cost overrun, is four years, then a quiet shelving, and an awkward conversation with the board. We have spent the last eighteen months refusing this default for three different clients. What follows is what actually worked.

Treat the old system as a service

The legacy system has a contract whether or not anyone has written it down. The first thing we do is spend a quarter writing it down. What inputs it accepts, what outputs it produces, where it's reliable, where it isn't. By the end of the quarter the legacy system stops being a scary, fragile thing the team is afraid to touch. It becomes a vendor.

Once that's true, new work can route around it, old work routes through it, and neither one has to wait for a rewrite. The team also stops apologizing for the legacy system in every status meeting, which is a smaller benefit than it sounds but a real one.

Pay down debt at the seams, not in the middle

When we do replace pieces of the system, we replace boundaries before we replace internals. We add a translation layer in front of the database long before we touch the data model. We introduce an event log between two services before we change either one. The seam work is unglamorous, and it is also what unblocks the work the team actually wants to do. Most of the headline modernization wins on these engagements come from doing this kind of plumbing first.

Run two stacks on purpose, for longer than feels comfortable

The most reliable modernization we have shipped in the last three years runs two stacks at once, side by side, for about eighteen months. The mature stack keeps handling the cases that earn the money. The new stack handles the cases the old one was never going to handle well.

The decision about when the old stack retires becomes a business decision — which customers, which contracts, which features — not a technical one. The team isn't racing the old stack out of production. They are letting the new stack earn its way in. This takes more patience than most leadership teams come in expecting, and it works almost every time.

What this trades

The pattern is slower at the beginning than a heroic rewrite, and faster at the end. There are fewer dramatic milestones, which makes some leadership teams nervous. The trade is that the system is in production the whole way through. For most of the clients we have done this with, that is the trade worth making.