The Rewrite Trap

Philipp Giese
July 12, 2022
9 min read
The Rewrite Trap

This would all be way easier if we would just throw everything away and build it ourselves.

When was the last time you've heard someone say this or even said it yourself? I definitively heard this at least a thousand times. What I observed, though, is that this sentiment usually comes from people who recently joined a new team or a new company. Do these people bring fresh ideas that make them see issues where others are already blinded? Or are they the ones who are missing something and, therefore, think that a rewrite will produce a better result?

TL;DR

We'll learn why rewriting software will most likely not produce a better result. To not fall for this fallacy yourself, you need to understand how to:

Why it is so tempting to start something from scratch

There are multiple reasons why starting from scratch seems like a promising approach. I will talk about the ones I have encountered most often and advise on what to do instead.

You don't need to wrap your head around new concepts

One key reason is that people like to stick to what they already know. When you start all over, you can choose the conditions you want to work in (e.g., the programming language or a framework). No matter what was already there, you don't need to try to learn something new. The freedom to use the tools that you already know can feel like a huge productivity boost.

Why is this a bad thing

Software is much more than a framework or a language. Most complexity is not found in the code that renders something on screen or accesses the database. You'll find the complexity inside the business logic of the software. I would argue that although some languages or frameworks will remove some boilerplate code, the gains you get from replacing one language with another are minimal in many software products. What you'll end up with is the same complex logic expressed in a slightly different way. Will that new way feel better to you? Maybe. However, it will only feel better because you could stick to what you already know.

People also usually forget that the current implementation won't just disappear. While working on the rewrite, your users will still use the old product and find issues that need fixing. The fixes will now take much more time because next to the time it takes to produce the fix, you will also add the time it needs to context switch between the old and the new world. Even worse, when the rewrite is not done by the team that built the original version, this can mean that the rewrite will reintroduce the issues. A co-worker told me about a situation where the old team saw the rewrite as a challenge to compete with the new team because they took pride in what had already been built.

What you can do instead

Be aware of why you like specific frameworks, languages, or concepts and talk to people about it. There is a good chance that you can apply some of the same methodologies also in another language. Also, you might learn that what the team is currently using has some nice features you have never heard of before. See this as a learning opportunity for both the team and you.

When you figure out that you want to refactor parts of the product, do it in the right way.


Follow your mental model

When we build software, we also create a mental model to guide the architecture. Getting into a mental model of someone else can be very hard. When you rewrite a product, you can build your mental model, meaning it is much easier to understand and follow architectural choices when encountering them. This lowers the cognitive load on your end and makes you feel more productive as you move along because the likelihood that you misunderstood a concept is lower (because you invented it).

Why is this a bad thing

Models change and evolve. It is likely that even though the mental modal you find seems confusing, there is a good reason for it being this way. When you create a new mental model, it will likely miss certain parts. However, you won't know this yet. By building up a new mental model that disregards what is already there, you set yourself up for failure.

What you can do instead

Talk to people. When something seems odd, this is a very good start for a meaningful conversation. Be clear about why something seems odd to you and suggest what you think would fit better. Even though there might be good reasons for the current model, this does not mean it is perfect. With your input, the team can iron out inconsistencies and improve.

Don't do this only once. Make sure to adapt the terms you use to build the product as the product evolves. This will make it easier for the next person that joins the team to get going.


Work the way you want

With new tools and new architecture, likely, you'll also choose new processes for your work. You might want to start with continuous delivery right from the start. After all, the product is small again, so changes to the process are easier.

Why is this a bad thing

How you work is only loosely coupled to what you build. If the system you're working in leads to 3-month release cycles, it will most likely lead to 3-month release cycles even when you start from scratch.

What you can do instead

Talk to people. Figure out why things happen in a certain way. Maybe people aren't aware that early integration creates value or that there is a better way of doing things. Make sure to figure out why things are the way they are before you change them.

You don't know what you don't know

Maybe you have noticed already that talking to people is the best way to overcome the initial urge to rewrite everything. Unfortunately, communication is hard and takes a lot of time, and that's probably why we sometimes try to avoid it as much as possible. However, when something is hard, do it more often to strengthen that muscle. Talking with people is no exception to this rule. It would be best if you built relationships to understand where people are coming from and their needs.

Another thing is not to underestimate how much you don't know. When you're new to a project, it is easy to underestimate the problem's complexity. Many problems seem small from the outside but are huge on the inside. Acknowledge that there is a ton of stuff you don't know yet. People will usually react nicer to your questions when you start from this assumption. Because now you're not the person who wants to tell people how to do their jobs, but you're the novice who likes to understand how we got to where we are.

Last but not least: time. We don't want to estimate how long it will take to develop a specific feature because we know our estimate will be incorrect. If we can't estimate how long it will take to build one feature, how can we be confident that a rewrite will be any good? We can't. We want to believe it is faster because of all the reasons I've outlined above. When we allow ourselves to believe in these lies, we're no better than any manager who believes that development estimates will align with reality. And we don't want to be this person. We need to acknowledge that even though we'd like something to be better once we've rewritten it, we don't have any proof that this will be the case. Even worse, we know that all things considered, it will probably take longer, and it won't be better but just different and come with a new set of problems.

Outcome over time

The graph above illustrates what causes us to choose rewrites nonetheless. Initially, we can move fast. This makes us feel productive and gives us lots of small dopamine rushes because we can ship the first features quickly. We must be on the right track! We're missing that we're not fast because we are incredible software engineers but because the new project is small. Over time the complexity increases, and we learn that some of the assumptions we made (explicitly or implicitly) were wrong. Even worse, we've probably made other mistakes along the way that we now need to also fix. That leads to a decline in productivity and maybe to someone new coming along who wants to rewrite the software again.

Rebuild the parts that need rebuilding

Once you have overcome the initial urge to throw everything away and start over and have talked to people you can start to change the parts that matter.

Is there waste in your processes? Can you, for instance, replace a review step with pair programming? Do this!

Are there parts in your software that are re-purposed instead of re-used? Adapt their names, pull them apart, and improve the code step by step.

There will be real shortcomings (i.e., technical debt) that might be more obvious to you than to the existing team. Be vocal about these parts and look out not to make things worse when you add new features. Build appropriate extension points and maybe devise a plan to incrementally get the software into a better shape. A new pair of eyes with fresh ideas is usually appreciated. The one idea that is not: let's start from scratch.


Have you been part of a big rewrite? Did you cause it, or did you have to live through it? I'm interested in hearing about your experiences. Good and bad! Tell me on Twitter: @philgiese.

Working with PeopleWhy Building Software is Hard