Tech Debt: The Frankenstein of Product

The best explanation I’ve heard till date for Technical Debt is the financial analogy—the Debt Metaphor—coined by Ward Cunningham, one of the authors of the Agile Manifesto. Ward used the metaphor Technical Debt to justify the code refactoring of a finance software to his boss from the client’s frame of reference.

Many people have a very different interpretation of the debt metaphor. Most confuse it with poor and ugly code written in a rush, full of defects, poor design decisions, security gaps, compliance issues, and so on. Technical debt is less technical and a far more fundamental modelling issue. It is that piece of work which continues to accumulate because of the missing alignment between a team’s understanding of the problem and the delivered solution at a given time.

Borrowing is not bad code

It is well understood and accepted that, under time pressure, a team makes conscious or unconscious trade-offs to deliver fast, but at no point should this serve as an excuse to write crappy code. A team can borrow time and effort to push features out of the door, but with quality code. Because, when it does come time to refactor based on the current understanding, the ability to pay back the debt primarily depends on the clarity of the thoughts and extensibility of the code taken into consideration while writing it the first time.

It is a common problem with both start-ups and large MNCs. The only difference is that start-ups have no or fewer processes to deal with ugly code, and by the time they realize the problems they have a difficult choice to make between scaling and refactoring. MNCs, on the other side, can afford these experiments in the form of MVPs and generally have standard processes in place to guarantee better code quality on regular intervals.

Start-ups also have another common problem—high attrition rate. Because of this, the code base sometimes becomes a mess—a spaghetti mess—which is not only difficult to understand but also results in more sloppy code, frustrations and poor practices.

At this point, teams come up with fancy ideas like implementing new frameworks, re-architecting, introducing more microservices, going serverless, moving everything to Kubernetes or going on a hiring spree for more engineers, a new architect or a more technical Product Manager.

Refactoring, as Martin Fowler explains, “is a disciplined technique for restructuring an existing body of code, altering its internal structure without changing its external behaviour.” It is a costly exercise which no doubt helps, but it can only fix the internals. A system architecture redesign, however, is much more difficult because it is a self-portrait of the organization and its enterprise architecture (Conway’s Law).

Technical debt is a business problem

Often, Product and Engineering teams find themselves involved in horse-trading over technical debt. Engineering Managers (EM) advocate prioritizing technical debt over everything else because, according to them, it is a hindrance to delivering new features. Product Managers (PM), on the other hand, fear losing valuable sprint time by prioritizing technical debt.

It becomes a far more serious problem if an EM sees technical debt purely as a code quality, architecture or infrastructure issue, the PM is inexperienced to understand this as a product quality issue, and management fails to recognize it as a business problem. This infighting soon mounts to blame games, attrition and more embarrassment for both the product and the business.

Technical debt is a business problem and spans vertically across the organization. Teams need to share responsibility and work together. Most importantly, management needs to take cognizance of the organizational structure, the silos and culture inhibiting collaboration, and the conflicting KPIs for managers.

The work starts with Product and Engineering understanding together the extent to which the product and business are affected by technical debt. It primarily involves building a shared understanding of the amount of impact, duration or periodicity, timing, refactoring cost and dependencies on other technical debt.

The PM, together with peers and stakeholders, needs to analyze the business value of the impacted component, its past, present and future, possible impact on other components, cost of delay and the lifecycle stage of the product itself. Once this is complete, technical debt needs to be prioritized accordingly, and a clear message needs to be sent to all stakeholders detailing the impact of not prioritizing technical debt and setting expectations regarding feature delays.

Conclusion

Technical debt grows with insufficient understanding and modelling of the problem domain, which cannot be fixed with technical solutions alone. Remodelling and reorganization must precede refactoring.

In order to address technical debt, we need to improve the way we collaborate and build our understanding of the problem we are trying to solve, be open, clear and transparent in communicating and recognizing these issues, remove the divider between the business and the system, and build a better culture within the organization.