Back to blog

My server is 8 years old and I won't rewrite it. Here's why.

A client came to me with a request: "We need to rewrite the backend. It's old." I asked: "What specifically is broken?" Pause. "Well... it's old."

That's not a technical argument. It's a cultural reflex.

We work in an industry where "rewrite" has become synonymous with "doing real work." If you're not migrating, you're burying your head in the sand. If the system is three years old, it's "legacy" — said like an insult. If it doesn't use the latest framework, it's dying.

I disagree.

How "rewrite" became the default answer

Architectural decisions are made in context. Two years later the context shifts: new tech lead, new microservices hype, new stack at the neighboring team. The old decision starts looking wrong — not because it broke, but because it's *different*.

Rewrites are also easier to sell. "Let's migrate to Next.js" sounds like progress. "Let's keep the PHP, add a cache layer, and fix three bugs" sounds like giving up. Even though the second option solves the actual problem and the first creates six new ones.

Developers want to work on new code. That's understandable. But that's the developer's motivation, not the business's.

What a migration actually costs

When a team proposes a rewrite, they quote the cost of development. They don't quote the cost of everything else.

First, rewrites destroy tacit knowledge. Every line in a working system is a decision made by someone who understood the context. Why does this edge case get handled this way? Why is that query oddly structured? When you rewrite from scratch, you lose all of that. It's not in Confluence. It's not in the README. It's in the code.

Second, you create real uncertainty that lasts. For six months to a year, the new system runs alongside the old one. Who maintains the old one? Who takes bug reports? How do you keep state synchronized? That's a whole project inside the project, and nobody plans for it.

Third, the tech debt transfers rather than disappears. If the team hasn't changed its development practices, the new codebase will look like the old one in two years — just without eight years of production debugging baked in.

I have a system that's been running for over eight years. It works. Updates slowly, but it's never been the source of an incident. Whenever I feel the urge to rewrite something, I ask different questions.

Three signs a system should stay untouched

First: it solves the problem you designed it for. Not the one you have now — the one you had then. If the problem hasn't changed, why change the solution?

Second: operational cost is predictable. You know what breaks and how to fix it. That predictability is worth money, even if it's hard to put a number on — it shows up in the absence of incidents.

Third: you can make changes without risking adjacent parts. If adding a new feature doesn't require an architectural decision — just "wrote it, tested it, deployed it" — that's a good system. Regardless of age.

Three signs you actually need to rewrite

I'm not saying never migrate. That would be its own mistake.

The clearest case: foundational dependencies have stopped being maintained. If your PHP version or a core library is getting CVEs and no patch is coming, that's a security issue, not an architecture conversation. You don't have a choice.

The harder signal to read: the cost of the next feature is growing exponentially. If every change requires touching five places and something breaks each time, that's worth paying attention to. Not "rewrite everything" — but "we need to start paying down this debt systematically."

The one that sneaks up on teams: nobody can work without a single knowledge holder. If one person leaving would paralyze support, that's an architectural risk. But address it gradually, not by starting from scratch.

Three questions before "let's rewrite"

I run through this framework every time I hear that phrase — from a client, from a colleague, from myself.

First: what specifically is broken? Not "old," not "ugly," not "not on our stack." What exactly isn't working, how often, and what does it cost the business?

Second: what happens if we don't do this? Sometimes the answer is "nothing bad." That ends the conversation. Sometimes it's "we won't be able to hire engineers in a year" — and that's a real argument.

Third: is there a cheaper solution to the same problem? In half the cases where someone proposed a full rewrite, the answer was replacing one module, updating a dependency, or refactoring within a single file. That's engineering work, not a rewrite.

When I turned down a $40K rewrite contract, it was exactly this scenario. The client wanted to rewrite Bitrix because a developer said it was "outdated." We opened the logs. 40 SQL queries per catalog page. LCP at 4.2 seconds. All of it fixed without a rewrite — in three weeks.

The honest caveat: when stability becomes a trap

Stability isn't a goal in itself. There's a point where "we don't touch this" shifts from a deliberate decision to avoidance.

It happens when the maintenance cost starts slowing down the whole team's output. Or when nobody on the team can explain how the system actually works anymore. Or when business requirements appear that the system genuinely can't meet without a core redesign.

In those cases the right answer isn't "rewrite from scratch" — it's "disassemble in pieces." Isolate the problematic module first. Replace it without touching the rest. It takes longer, but the blast radius is smaller.

Owner mindset isn't about protecting old code. It's about counting the consequences of every decision. Including the decision to rewrite.

Conclusion

A stable system is an asset. Not a perfect one, not a beautiful one — but a predictable one. Predictability is the money you don't spend.

Three questions before the next "let's rewrite." They close the conversation more often than you'd think.