The rewrite that shouldn't happen
On reading being harder than writing, the undocumented behavior that looks like cruft, and how to argue against this without becoming the person who blocks everything.
A proposal landed in August to rebuild a client platform from scratch. It’s a good document. It’s written by somebody sharp who has been in that codebase for four months and is not enjoying it, and every criticism in it is accurate.
It’s also the third such proposal in five years, on the same system, from three different people who did not know about each other’s.
That pattern is the thing I want to write about, because when the same conclusion keeps being reached independently by capable people, either it’s correct or there’s a mechanism producing it. I think it’s mostly the second, and understanding the mechanism is what lets you have the conversation without being tedious about it.
Why the proposal keeps arriving
Reading code is harder than writing it. This is the whole thing, really. When you read somebody else’s system you’re reconstructing intent from artifacts, and every decision arrives without its reasoning. When you write, the reasoning is present, effortlessly, because it’s yours and it’s happening now.
So the existing system always feels worse than the imagined one, and the feeling is a fact about the reading rather than about the code. Even code you wrote yourself 18 months ago feels like this. I’ve proposed rewriting my own work.
You’re comparing a known mess to an imagined clean thing. All the existing system’s complexity is visible, because it’s there in front of you as evidence. None of the new system’s complexity is visible, because it hasn’t been discovered yet. It will be exactly as complex, because the complexity is mostly coming from the problem rather than from the previous developer, and you’ll find that out in month seven.
And rewriting is more enjoyable. I don’t think anybody says this out loud and I think it does a lot of work. Greenfield is fun, it’s legible on a résumé, and there’s a demo at the end. Maintenance is archaeology and there’s nothing to show.
You're comparing a mess you can see with a clean thing you've imagined. The new system's complexity isn't smaller, it's just undiscovered.
What the old code actually contains
The strongest argument against, and the one that’s hardest to make persuasively because it sounds like sentimentality.
A system that’s been in production for six years contains the accumulated response to six years of reality. Hundreds of small corrections for cases nobody wrote down: the customer whose zip code has no space, the supplier whose feed sends dates in a different format on Mondays, the payment provider’s sandbox that behaves differently from live, the redirect that exists because a URL was printed on 50,000 leaflets.
Every one of those looks like cruft. Every one of them looks exactly like the sort of thing a rewrite would clean up. And each is a bug that was found by a real customer, reported, diagnosed and fixed, at a cost, once.
Rewriting means finding every one of them again, in production, by the same method, which is a customer being annoyed.
That’s the “last twenty percent” everybody talks about. It isn’t 20% of the features, it’s the entire undocumented behavioral surface, and there’s no document you can read to shortcut it because if there were a document it wouldn’t be the problem.
When it’s actually right
I’d have no credibility if I didn’t mean this bit, and I’ve been on the other side of it twice.
When the platform is genuinely dead. A runtime with no security patches and no upgrade path, a framework whose maintainers have gone. At that point you’re not choosing to rewrite, you’re choosing when.
When it’s small enough. This is the single biggest predictor and it’s under-weighted every time. A rewrite you can finish in six weeks is a completely different risk from one estimated at nine months, not because the work is different in kind but because a six-week rewrite can be wrong and survive it. Nine months cannot.
When the requirements have changed. If the business now does something structurally different, you’re not rebuilding the same thing, and most of the argument above doesn’t apply, because the accumulated edge cases are about a problem you no longer have.
When it’s cheaper than the alternative, demonstrably. Sometimes it is. Just make somebody show the arithmetic rather than the feeling.
Arguing without being the blocker
The practical part, since “this is usually a bad idea” is not a thing you can say in a meeting without becoming a character.
Agree with the goal, question the mechanism. The goal is never “rewrite it.” The goal is “this is too hard to change and it’s slowing us down,” which is true and which everyone agrees with. So: what specifically is hard? Which changes take longest? And then you’re both looking at a list rather than at each other.
Get a range and the reason for its width. A rewrite estimate is the widest distribution anybody will ever hand you, and the honest version of that is enormously clarifying. Asking “what’s the pessimistic case, and what makes it pessimistic” is not hostile, it’s the same question I’d want asked about my own estimate.
Ask what happens if it takes twice as long. Not as a gotcha. As planning. Every rewrite I’ve seen has run at roughly double, and if double is fatal to the business then the plan has no slack in it and that’s worth knowing before rather than after.
Propose replacing one piece instead. The worst route, the worst module, behind the same URLs, in two weeks. If that goes well you have evidence and momentum and a pattern to repeat. If it goes badly you’ve spent two weeks, and you’ve learned the thing the nine-month plan would have taught you in month seven. There’s a name for this approach and I’ll write it up properly next time.
And be willing to lose. The person proposing it has been inside that code for four months and I haven’t. They may know something I don’t, and if I’ve already decided, the conversation is theater and they can tell.
Credibility is a budget
The bit underneath all of this, which took me about a decade.
The developer who objects to everything stops being heard. Not because they’re wrong, usually they’re right more often than average, but because “they’ll say no” becomes a known quantity and people route around it. They stop asking. Decisions get made elsewhere and you find out afterward.
So opposition is a budget and it’s smaller than you’d like. Spend it on the ones that matter, say yes to things you’re merely unsure about, and be visibly pleased when you’re proved wrong, because the times you’re wrong are what buy the times you’re right.
What happened in August
What happened with the August proposal: we picked the worst part, which was the ordering flow, and gave it six weeks behind the existing URLs. It went reasonably. It also surfaced two behaviors nobody knew about, both of which would have been found much later and much more expensively.
Nobody has mentioned the full rewrite since, and I don’t think that’s because anybody won an argument. It’s that “this is hard to change” stopped being true for the part that was actually hurting, and the proposal was always downstream of that feeling.