technical debt quality and trade offs

Technical Debt, Quality, and Trade-offs: Striking the Right Balance

November 29, 2024

Justin Ammerlaan and Guy Coleman

Read Time: ~12 minutes

As engineers, we are constantly juggling the demands of delivering high-quality products quickly while also maintaining the integrity of our codebase. One of the most critical aspects of this balancing act involves managing technical debt, understanding what quality truly means, and making informed trade-offs. This post explores these concepts and offers insights into how teams can navigate these challenges effectively.

Our Co-Founder and CTO at Empower, Justin Ammerlaan, has laid the foundation through years of experience building successful financial service products for how we can and should leverage 2Technical Debt2 and view and challenge concepts of 2Quality2 at Empower.

Understanding Technical Debt

"Technical debt" is a metaphor for the future cost incurred when opting for a quicker solution now, rather than a longer, potentially better approach. The alternative might be simpler, more flexible, adaptable, robust, or easier to maintain in the long run. Essentially, it’s the trade-off of immediate action for a known solution versus investing time in developing a potentially superior one. Like financial debt, it’s a form of borrowing now with the obligation to repay later.

“In finance, using debt as a tool is a way to leverage, or increase returns. In our case, in Engineering, it is a tool to create speed. It is an essential part of any financial strategy and also an essential part of the MVP process.” - Justin Ammerlaan

“Strategic use of technical debt can be a tool for creating speed and leveraging opportunities. However, like financial debt, it needs to be managed carefully. Accumulating too much without a plan for repayment can hinder progress and introduce significant risks to the project.” - Justin Ammerlaan

Just like with financial debt, technical debt needs to be repaid and should be repaid on a schedule; otherwise, the ‘interest’ starts to compound, and the maintenance overhead becomes a massive burden. At Empower, we allocate 30% of engineering resources to non-product work, including technical debt.

Defining Quality

Quality is a foundational aspect of software development that ensures the product meets the needs and expectations of its users. However, misconceptions about what constitutes quality can lead teams astray. By clearly defining what "quality is" and what "quality is not," we can align our efforts toward delivering value effectively. Justin provides some specific guidelines on how to think about what quality is and what it isn’t.

Quality Is:

  1. Correctness (Functionality)

    • Correctness ensures that the software behaves as intended, fulfilling all specified requirements without bugs or errors.
    • Example: In a financial application, correctness ensures that all calculations (like interest computations or balance updates) are accurate, preventing financial discrepancies.
  2. Accuracy (Adherence to Requirements)

    • Accuracy involves meeting the specifications and requirements.
    • Example: If stakeholders need a report-generating tool that exports data in CSV format, accuracy means delivering exactly that feature—not an elaborate reporting suite with formats they don't need.

Quality Is Not:

  1. Optimization

    • While performance is important, premature optimization can lead to unnecessary complexity and wasted resources.
    • Example: Spending days optimizing a function that runs in milliseconds, when users wouldn't notice the difference, instead of working on delivering new features can divert resources from more impactful areas.
  2. Generalization

    • Engineering solutions to handle a wide range of scenarios beyond current requirements can complicate the codebase.
    • Example: Creating a complex plugin architecture for an application that is only ever going to need built-in functionality can be overkill if current needs are limited and well-defined.
  3. Extensibility

    • Building systems with capacity for extensive future expansion can introduce unnecessary complexity.
    • Example: Designing a module with extensive API endpoints for integrations that aren't planned can make the system harder to maintain.
  4. Elegance

    • While elegant code can be beautiful, overemphasis on elegance can hinder progress.
    • Example: Using a complex design pattern for a simple problem can complicate the code without offering significant benefits.
  5. Personal Coding Style Preferences

    • Imposing individual coding styles over team standards can disrupt consistency.
    • Example: A developer insists on using programming language features that others on the team are unfamiliar with, complicating maintenance.

“Quality is something that should never be sacrificed when it comes to engineering at Empower. We are a financial tech company that moves millions of dollars every day, and a mistake in specific areas of the codebase can create significant issues.” - Justin Ammerlaan

Understanding what quality is and what it is not helps guide our engineering teams into the “pit of success,” or pit of 'productivity' success. Our engineering teams can deliver reliable and valuable software by focusing on correctness and accuracy.

Trade-offs

Balancing quality, technical debt, and speed of delivery requires careful consideration and strategic decision-making. The key is to adjust these trade-offs relative to the requirements of the solution and the consequences of the decisions involved.

Balancing Technical Debt and Quality

Technical debt is a tool that can be leveraged to increase development speed. However, the amount of technical debt incurred should align with the specific needs and risks associated with the project.

Ultimately, the approach varies depending on factors like the stage of the product and the criticality of the system being developed. Understanding when to prioritize speed over quality—or vice versa—is essential for delivering value effectively.


Key Take-Aways

  1. Strategically Manage Technical Debt

    • Leverage technical debt deliberately to accelerate development, treating it as an investment that can yield significant returns if managed wisely.
  2. Quality Equals Correctness and Accuracy

    • Focus on ensuring the software works as intended and meets requirements.
  3. Balance Trade-offs Based on Decision Types

    • Understand whether decisions are hard-to-reverse (Type 1) or easily reversible (Type 2).
  4. Adjust Technical Variables Without Compromising Core Functionality

    • Manage aspects like abstraction and documentation without compromising the solution's correctness and accuracy.

About Justin Ammerlaan

Co-founder and CTO of Empower Finance

Software expert with a wealth of technical and commercial skills. Extensive experience in finance software, including high transaction flow and modelling systems.