A few weeks ago I hit my six-year anniversary at Microsoft. In that time, I've worked with several teams building web services inside the company, and I've built a network of decent size at many of our peer companies. I've learned a lot about software engineering, both from my own experience and that of my peers. In all this time, perhaps the biggest thing I've understood is this: pretty much every engineer who works on a software project of any complexity hates their codebase.
Talented engineers faced with market pressures make tough choices that almost miraculously result in shipped software. It's well understood that those choices add up at a micro level as technical debt, and most great companies have figured out mechanisms for improving individual components over time. But it's harder to account for—and correct—choices that add up at a macro level.
Architectural debt is the sum of those macro-level choices. It affects every piece of your code base, and is usually the result of decisions that were made years ago. Importantly, those decisions may well have been the right ones at the time, both from a "getting to market" perspective and from a "right technical choice for this moment in time" perspective.
However, because it affects so much of your codebase, it's dramatically harder to revisit architectural debt, and the decisions that made sense once upon a time evolve into an albatross around the neck of the people who have to deal with them now. This is the source of the codebase hatred that pervades among engineering departments at companies; they are weighed down by two major factors:
- The architectural debt has started affecting every aspect of their day-to-day work: everything takes a long time, functionality is fragile, ownership and accountability is hazy, etc.
- The codebase is so large that making any real impact on the problem seems like an insurmountable challenge.