Every senior engineer has stood in front of a codebase and felt the pull. The pull says: burn it down. The pull says: this is not a system, it is a sediment deposit. The pull says: if I could just start over, I would do it right this time. That pull is not a technical signal. It is an emotional one. And it is usually wrong.
This article is about separating two very different failure modes. The first is a codebase that has accumulated enough structural debt that a rewrite is the rational economic choice. The second is a team that has accumulated enough operational debt that a rewrite is the rational emotional choice — a way to avoid confronting the team’s own dysfunctions. The two look identical from the inside. They are not identical. The difference shows up in deployment frequency, code review latency, incident response patterns, documentation freshness, and meeting artifacts. Those are the operational signals. Learn to read them before you touch the code.
I am Fritz Muller. I write about engineering team sociology and operational culture critique for senior ICs and EMs who suspect their team’s dysfunctions are system failures, not personal failings. This is not a guide to refactoring. It is a guide to diagnosing the system before you let the system diagnose you.

The Rewrite Impulse Is a Blocking Call
In software, a blocking call is a function that stops the entire program while it waits for something external. A database query. A network response. A file read. The program cannot proceed until the call returns. The rewrite impulse works the same way. It blocks the team’s ability to make incremental progress because everyone is waiting for the new system to arrive. The old system is frozen. The new system is not ready. Nothing ships.
Teams that want a rewrite tend to exhibit a specific operational pattern: deployment frequency drops before the rewrite is even announced. The team stops fixing the old system because they believe it is temporary. They stop writing tests for it. They stop documenting it. They stop reviewing its pull requests with any seriousness. The old system becomes a zombie: still running, still serving traffic, but no longer receiving meaningful investment. The team has already mentally moved on. The codebase has not.
This is not a technical signal. It is a cultural one. The team has decided the old system is dead, so they treat it as dead. The codebase did not ask for that. The team did.
Operational Signal: Deployment Frequency
Look at the deployment history for the last six months. If the team is still shipping to the old system at a steady cadence — even small fixes, even boring maintenance — the codebase is not telling you it needs a rewrite. It is telling you it needs maintenance. A codebase that truly needs a rewrite will show a different pattern: deployments are frequent but increasingly risky. Each release requires more rollback planning. Each release touches more files. Each release has a longer stabilization period. The cost of change is rising, not because the team is lazy, but because the system’s internal structure has degraded to the point where every change is a cross-cutting concern.
If deployments are infrequent because the team has stopped trying, that is a team problem. If deployments are frequent but each one is a small crisis, that is a codebase problem. The distinction matters.
Code Review Latency as a Cultural Thermometer
Code review latency is one of the most underrated operational signals in software organizations. It measures the time between a pull request being opened and the first meaningful review comment. Not the first emoji. Not the first “LGTM”. The first comment that engages with the actual change.
Teams that want a rewrite show a specific latency pattern: reviews on the old codebase slow to a crawl, while reviews on any new prototype or spike are nearly instant. The team is not busy. The team is disengaged. They are voting with their attention. The old codebase has become a chore, and the new codebase — even if it is just a README and a dream — is exciting. This is not a technical signal. It is a motivation signal.
A codebase that needs a rewrite will show a different pattern: reviews are slow because every change is genuinely hard to evaluate. The diff is large. The blast radius is unclear. The tests are flaky. Reviewers are not disengaged; they are overwhelmed. They ask questions like “what does this break?” and “is there a simpler way?” and “why is this file even in this module?” Those are technical questions. The disengaged team asks no questions at all.

Operational Signal: Review Comment Depth
Measure the average length of review comments on the old codebase over the last three months. If comments have become shorter, more generic, or more deferential — “looks fine to me”, “not my area”, “ship it if you want” — the team has checked out. If comments are still substantive but increasingly negative — “this will break the payment flow”, “we tried this in 2019 and it caused a data loss incident”, “this module is a tangle and I cannot verify this change is safe” — the codebase is the problem. The team is still engaged. The system is not cooperating.
Incident Response Patterns: The Most Honest Signal
Incidents are the closest thing software organizations have to a stress test. They reveal what the team actually believes about the system, not what they say in planning meetings. A team that wants a rewrite will respond to incidents in the old system with a specific pattern: resignation. The incident is treated as inevitable. The postmortem is perfunctory. The action items are vague. The underlying tone is “of course this broke, the whole thing is garbage, we need to rewrite it.”
A codebase that needs a rewrite will produce a different incident pattern: surprise. The team is genuinely shocked that the system failed in this particular way. The postmortem is detailed. The action items are specific. The underlying tone is “we did not see this coming, and we need to understand why.” That is a team that still believes the system can be understood. That belief is the difference between a maintenance problem and a rewrite problem.
Watch for the phrase “known issue” in incident channels. If the team has a long list of known issues that they have accepted as permanent, that is a team that has given up. If the team has a long list of known issues that they are actively triaging and fixing, that is a team that is managing a difficult codebase. The list is the same. The response is not.
Operational Signal: Postmortem Action Item Completion
Track the completion rate of postmortem action items over the last year. Teams that want a rewrite will have a low completion rate on action items related to the old system. Not because the items are hard, but because the team does not see the point. Teams that are managing a codebase that needs a rewrite will have a higher completion rate, but the items themselves will be increasingly defensive: adding more monitoring, adding more guards, adding more tests around fragile areas. The team is not fixing the root cause because the root cause is structural. But they are still trying to contain the damage. That is the signature of a codebase problem.
Documentation Freshness: The Canary in the Coal Mine
Documentation is the first thing to die when a team disengages. Not because documentation is hard, but because documentation is an act of faith. Writing documentation says: this system will still be here in six months, and someone will need to understand it. A team that wants a rewrite stops writing documentation because they no longer believe the system will be here in six months. The documentation becomes a fossil record of a previous era.
Look at the last-modified dates on the core documentation. If the architecture docs, the runbooks, and the onboarding guides have not been meaningfully updated in six months or more, that is a signal. But it is an ambiguous signal. A codebase that needs a rewrite will also have stale documentation, because the system changes faster than anyone can document it. The difference is in the attempts. A team managing a difficult codebase will have a trail of half-finished documentation updates, abandoned because the system changed again. A team that wants a rewrite will have no trail at all. They stopped trying.

Operational Signal: Documentation Commit History
Check the git history for the docs directory. If there are no commits in the last quarter, that is a team signal. If there are commits but they are increasingly out of date within weeks, that is a codebase signal. The first means the team has stopped caring. The second means the system is changing too fast to document. Both are problems. Only one is solved by a rewrite.
Meeting and Decision Artifacts: The Paper Trail of Intent
Meetings are where teams negotiate their relationship with the codebase. The artifacts of those meetings — decision records, architecture review notes, planning docs — are a paper trail of intent. A team that wants a rewrite will have a specific pattern in their meeting artifacts: the rewrite is discussed as a foregone conclusion, not as a decision. The architecture review notes will say things like “when we rewrite this” not “if we rewrite this”. The planning docs will have a section called “post-rewrite” with no criteria for what would trigger the rewrite in the first place. The decision record, if it exists at all, will be thin.
A codebase that needs a rewrite will have a different pattern: the rewrite is discussed as a reluctant conclusion, reached after exhausting alternatives. The decision record will be long. It will list the alternatives that were tried. It will list the metrics that were measured. It will list the specific failure modes that made incremental improvement impossible. The team did not want to rewrite. The codebase forced them to.
This is the single most reliable signal I know. A team that wants a rewrite will not have a decision record. A codebase that needs a rewrite will have a decision record that reads like a eulogy.
The Race Condition Between Team and Codebase
In concurrent programming, a race condition occurs when two processes access shared state and the outcome depends on the order of execution. The team and the codebase are in a race condition. The team’s motivation and the codebase’s structure are both changing, and the outcome depends on which one degrades first.
If the team’s motivation degrades first, the codebase will look worse than it is. The team will stop maintaining it, stop documenting it, stop reviewing it, and stop responding to its incidents with any seriousness. The codebase will then actually get worse, because neglect is a self-fulfilling prophecy. The team will point to the degraded codebase as proof that they needed a rewrite all along. They are right, but only because they caused it.
If the codebase’s structure degrades first, the team’s motivation will follow. The team will try to maintain it, try to document it, try to review it, and try to respond to its incidents. But the system will resist. Every change will be harder than the last. Every incident will be more surprising. The team will eventually conclude that a rewrite is necessary. They are right, and they have the decision record to prove it.
The question is not “does this codebase need a rewrite?” The question is “which degraded first?” The answer is in the operational signals.
A Diagnostic Checklist for Senior ICs and EMs
Here is a practical checklist. Run it before you run the rewrite.
- Deployment frequency: Is the team still shipping to the old system? If yes, is each deployment a small crisis? If no, why did they stop?
- Code review latency: Are reviews slow because the team is disengaged, or because the changes are genuinely hard to evaluate?
- Incident response: Are incidents met with resignation or surprise? Are postmortem action items completed?
- Documentation freshness: Is the documentation stale because the team stopped trying, or because the system changes too fast to document?
- Decision artifacts: Is there a decision record for the rewrite? Is it long and reluctant, or thin and eager?
If the answers point to team disengagement, a rewrite will not fix the problem. It will just move the disengagement to a new codebase. The team will be excited for three months, and then the same patterns will reappear. The new codebase will become the old codebase. The rewrite will have been a very expensive team-building exercise.
If the answers point to structural degradation, a rewrite may be the right call. But it should be a decision, not a mood. It should have a decision record. It should have success criteria. It should have a plan for the old system during the transition. And it should be led by people who understand that a rewrite is a system migration, not a fresh start. There is no fresh start. There is only a new system with a new set of problems.
What to Do Instead of Rewriting
If the diagnosis is team disengagement, the fix is not technical. It is operational. Here are three concrete moves.
First, force a deployment. Pick a small, boring fix in the old system and ship it. Not a feature. A fix. A typo in an error message. A log line that is too noisy. A test that is flaky. Ship it. The act of shipping to the old system breaks the mental block. It reminds the team that the old system is still a system, not a corpse.
Second, write a decision record for the rewrite. Not a plan. A decision record. What problem are we solving? What alternatives have we tried? What metrics would tell us the rewrite is working? If the team cannot write this document, they do not have a case for a rewrite. They have a feeling. Feelings are not a basis for a multi-quarter engineering investment.
Third, rotate the on-call burden. Disengagement often concentrates in the people who carry the pager. They are the ones who feel the old system’s pain most acutely. They are the ones who want to burn it down. Rotate the on-call schedule so that the people who want the rewrite are not the only ones feeling the pain. The pain will either spread, which will create a real case for change, or it will dissipate, which will reveal that the pain was localized, not systemic.
When the Codebase Is Actually Right
Sometimes the codebase is right. Sometimes the system has accumulated so much structural debt that incremental improvement is genuinely impossible. The signs are specific. The module boundaries have collapsed. The data model is wrong in a way that cannot be fixed without a migration that is itself a rewrite. The test suite takes longer to run than the code takes to write. The deployment process is a manual ritual that only one person understands. The incident rate is rising, and each incident is a new failure mode, not a repeat of an old one.
When these signs are present, the rewrite is not an emotional escape. It is an economic necessity. The cost of maintaining the old system exceeds the cost of building a new one. The team is not running away from the old system. They are running toward a system that can actually support the business.
But even then, the rewrite should be a decision, not a mood. It should have a decision record. It should have a plan. It should have a team that understands the old system well enough to know what to preserve. A rewrite led by people who hate the old system will produce a new system that repeats the old system’s mistakes. A rewrite led by people who understand the old system will produce a new system that learns from them.
FAQ
How do I know if my team’s desire for a rewrite is legitimate?
Look for a decision record. A legitimate rewrite desire is accompanied by a written document that lists the alternatives tried, the metrics measured, and the specific failure modes that made incremental improvement impossible. If no such document exists, the desire is a mood, not a decision. Moods are not a basis for a multi-quarter engineering investment.
What is the single most reliable operational signal that a team wants a rewrite rather than needs one?
Deployment frequency. If the team has stopped shipping to the old system before the rewrite is even announced, that is a team signal. The team has mentally moved on. The codebase did not ask for that. The team did. A codebase that needs a rewrite will show frequent but increasingly risky deployments, not a sudden stop.
Can a rewrite fix a disengaged team?
No. A rewrite can temporarily re-engage a disengaged team, but the disengagement will return. The underlying operational patterns — slow reviews, stale documentation, perfunctory postmortems — are team behaviors, not codebase properties. They will follow the team to the new codebase. Fix the team’s operational culture first. Then decide if the rewrite is still necessary.
What should I do if I am a senior IC and my EM is pushing for a rewrite I think is unnecessary?
Ask for the decision record. Ask what alternatives have been tried. Ask what metrics would tell you the rewrite is working. Ask what happens to the old system during the transition. If the EM cannot answer these questions, the rewrite is a mood. Your job is not to block the rewrite. Your job is to force it to become a decision. That is the most useful thing a senior IC can do.
This article is part of a series on reading operational signals in engineering teams. The next article will cover how to diagnose a team that has stopped reviewing code — not because they are busy, but because they have stopped caring. If you have a team signal you want diagnosed, send it in. I read everything.