In the software industry, “Technical Debt” is perhaps the most frustrating term. This may be controversial, and clean architecture enthusiasts might disagree, but let’s dip into this topic.
Thank you for reading this post, don't forget to subscribe!Defining Technical Debt
During interviews, candidates are often asked to define “tech debt,” and surprisingly, each one provides a different answer. The industry seems to lack a consensus. These responses can generally be classified into a few categories:
Common Issues with Definitions:
- Vagueness: Terms like “old code” lack specificity. Does “old” mean six months, a year, or longer?
- Symptom-Focused: Answers often describe symptoms rather than root causes. For instance, why does no one want to modify a particular piece of code? Is it hard to understand, has knowledge been lost, or is it too critical to risk altering?
- Problem Clarity: Some definitions, such as “code is slow,” are not always indicative of a problem. For example, a maintenance script that runs once a month and takes three hours might not be optimized but still does its job effectively.
- Subjectivity: There’s also the issue of ego, with some engineers labeling code written by others as tech debt.
The Ubiquity of Tech Debt
Regardless of the definition, every company has tech debt. There’s always some code that is difficult to modify, not optimized, or based on an outdated framework. For instance, in 2014, parts of Amazon’s retail website were written in Perl, even though Java had become the standard. Despite its age and the lack of Perl expertise, this code was crucial and used daily by millions.
Consensus on Tech Debt
Despite varied definitions, one thing is consistent: tech debt is viewed negatively. Candidates often express concern when a company admits to having tech debt. Some even state they would not want to work for a company with tech debt.
The Cost of Tech Debt
The primary argument against tech debt is its cost. However, unlike financial loans with clear interest rates, tech debt is difficult to quantify. Observations of team velocity, for example, showed slower progress with monolithic architectures compared to microservices initially. Yet, as the number of microservices grew, maintenance burden increased, slowing progress despite cleaner architecture. Similarly, velocity comparisons between Android and iOS teams revealed that clean architecture principles did not always correlate with faster development or fewer bugs.
Respecting Legacy Code
The conversation about tech debt often implies that past decisions were mistakes. This presumption overlooks the context in which those decisions were made. For example, at Amazon, the use of an internal key-value storage system (Beaver) instead of DynamoDB was criticized, until it was pointed out that DynamoDB did not exist when the project started. Assuming good intentions and understanding the original constraints can provide valuable insights into past choices.
Reevaluating Technical Debt
Technical debt, like financial debt, can accumulate interest over time, making it more challenging to address the longer it is ignored. However, debt itself is not inherently bad. Just as financial debt can enable significant investments like buying a house or starting a company, technical debt can facilitate rapid development and market entry. For example, a startup’s initial mobile app, built quickly using React Native by a single front-end engineer, enabled the company to acquire thousands of clients and secure funding, ultimately allowing for the development of a native app by a dedicated team.
Technical debt should be viewed as a tool rather than a liability. It can be beneficial if managed properly, enabling projects and growth. It is crucial to respect the decisions made by predecessors, recognizing the context and constraints they faced. Properly leveraging technical debt can provide time, attract clients, and unblock projects, turning it into a strategic advantage rather than a hindrance.