Understanding Architectural Technical Debt
While most resources and tools today focus on code-level technical debt, it is Architectural Technical Debt (ATD) that incurs the highest "interest rates" and imposes the most significant constraints on the evolution of a software system.
“It’s OK to borrow against the future, as long as you pay it off.” — Ward Cunningham
Since Ward Cunningham first introduced the concept of Technical Debt (TD) in the early 90s, we have used it to describe the accumulated consequences of past decisions and shortcuts in software development.
His comparison to financial debt was simple yet profoundly relatable. Financial debt can be a very useful tool: a bank loan enables you to accomplish your goals faster than would be possible otherwise. However, this loan comes with interest rates, and the more you borrow without repaying the principal, the more interest accumulates. This can lead to a crippling cycle where the burden of servicing the interest becomes overwhelming, with bankruptcy becoming an imminent threat.
Similarly, in software development, technical debt can give the initial development a boost. Early design or implementation decisions may be made because they are convenient in the short term or because they align with the current understanding of product requirements. However, this “loan” incurs “interest” in the form of bugs, complex workarounds, extra time spent trying to understand the system, quality issues, and extended development time for new features.
In essence, the technical debt affects the maintainability and evolvability of the system, making future changes costly or, in some cases, unfeasible.
The longer you defer paying off the technical debt (i.e. refactoring, improving your system, etc.) , the more interest accrues, further slowing future product development.
While most resources and tools today focus on code-level technical debt, it is Architectural Technical Debt (ATD) that incurs the highest "interest rates" and imposes the most significant constraints on the evolution of a software system. Indeed, Gartner reports that, “by 2026, 80% of technical debt will be architectural technical debt.”
ATD accumulates during the system design process because of decisions related to the choice of structure (e.g., architectural style), the choice of technologies (e.g., frameworks, packages, libraries), and even the choice of programming languages and development methodologies.
Over time, these decisions can lead to fragile systems that can’t be changed or accommodate evolving business requirements.
In fact, the cost of technical debt extends beyond the immediate need to refactor initial design and implementation choices; it also encompasses the broader business impact of missed opportunities, failed modernization efforts, and high turnover due to inflexible and brittle IT systems.
The importance of managing Architectural Technical Debt cannot be overstated. Ignoring or neglecting it can result in reduced maintainability, increased complexity, decreased performance, and scalability issues in the software system.
In this blog post, we will explore strategies for identifying and monitoring Architectural Technical Debt, aiming to mitigate the risks it poses to software development.
Why Architectural Technical Debt Has Such a High Interest Rate
“Addressing code-level technical debt is like cleaning and tidying your home. Addressing architectural debt is like maintaining your heating, roof and foundations. Your house will not fall down if it is dirty, but it will leak and potentially subside if structural issues are left untreated, although it is always nice to live in a clean house.” - Tigran Egiazarov
Extensive research has established that technical debt significantly affects developers’ happiness, productivity, and morale. After all, few would find satisfaction in knowing that 23% of their working time was wasted due to technical debt.
However, its repercussions extend far beyond individual developers, profoundly impacting entire organizations.
Currently, technical debt is estimated to be 20-40% of a company’s technology real estate. On average an organization invests more than 30% of its IT budget and more than 20% of its IT human resources to manage and address it.
The ramifications of Architectural Technical Debt can be broadly categorized into three areas:
(1) Business-related
- Lost Business Opportunities: ATD may prevent the system from adapting to new business requirements, resulting in missed opportunities to explore and capitalize on new markets.
- Increased Liability and Risk Exposure: ATD elevates the system’s security vulnerability and the likelihood of security breaches and loss of user private data.
- Customer Dissatisfaction and Churn: The limitations imposed by ATD can lead to poor performance and user experience, culminating in customer dissatisfaction and, ultimately, churn.
- Reduced Agility and Development Velocity: The complexity introduced by ATD necessitates additional time for developers to understand the architecture, implement changes, and fix bugs. This complexity can significantly slow down development processes, making it challenging to estimate timelines accurately and respond swiftly to market demands.
(2) Functionality-related
- Challenges in Implementing New Functionality: The presence of ATD increases the effort and complexity involved in adding new features, which can lead to the rejection or de-prioritization of the feature due to the high risk and cost.
- Crystallized Architecture: In the most severe cases, ATD can lead to a "crystallized" architecture, where the system's flexibility is so compromised that it nearly prohibits the integration of any new functionalities.
(3) Operations-related
- Impediments to Parallel Development: ATD often results from poor separation of concerns and tight coupling among components, which hampers the ability of different teams to work in parallel, leading to bottlenecks in development processes and delays in product delivery.
- Unpredictable System Behavior: Systems heavily burdened with ATD may exhibit flaky and unpredictable behavior, making them unreliable. This issue is often associated with a "crystallized architecture," where the system's rigidity and complexity lead to operational challenges and hinder effective troubleshooting and maintenance.
Architectural Technical Debt’s Worst Symptoms
We have all probably worked on software systems affected by slowdowns in release cycles, glitchy performance, and the presence of dead code. In fact, any software company that’s older than a couple of years can almost feel the shadow of unresolved technical debt: the “swift triumph” of deploying a solution quickly to market is followed by months of grueling engineering challenges, long nights, and constant firefighting.
Prolonged ATD can lead to a “breaking point” and push the application into legacy status. That’s why it’s important to be attuned to the following symptoms:
- Frequent outages, performance issues (e.g. inability to scale), and slow response times to service requests
- High number of defects (including security breaches and data leaks)
- High volume of (and recurrent) customer issues or generally high support costs
- Growing maintenance and refactoring tasks
- Growing resources needed to maintain the system and keep it running (both from a financial perspective (e.g., cloud provider commissions), or headcount)
A less “quantitative” symptom is the increased frequency of hearing things like “I don’t want to touch that code”. In fact, a software developer’s instinctual reluctance to modify a certain component is a good indication that you have ATD.
It’s important to note that Architectural Technical Debt is not poor naming, badly structured code, duplication etc. These are issues of code-level technical debt, which tend to be localized and can be fixed in isolation. It’s also misleading to equate technical debt with “bad code” in general: it leads us to believe that if we just write good enough code, we won’t have any technical debt.
ATD is more complex and has a larger scope than just the quality of the code: it comprises trade-offs made for immediate short-term benefits, architectural drift, suboptimal architectural decisions, intentional violation of best practices or target architecture, and using unstable shortcuts to get to the product delivery finish line.
What is the Root Cause?
“Technical Debt refers to delayed technical work that is incurred when technical short cuts are taken, usually in pursuit of calendar-driven software schedules. Just like financial debt, some technical debts can serve valuable business purposes. Other technical debts are simply counterproductive.” - Steve McConnell
Causes that lead to Architectural Technical Debt can be classified into two broad categories:
- Unintentional Debt (or Emergent Technical Debt) is caused by hard-to-foresee factors such as evolving system requirements, unintentional oversights, technological advancements.
- Intentional Debt results from deliberate, strategic choices. These decisions involve consciously prioritizing rapid development and immediate deliverables over long-term maintainability and system evolution.
Diving deep into the 5 main causes of ADT:
(1) Business Pressures
In the high-stakes environment of software development, the imperative to deliver quickly, often overrides concerns for architectural integrity. Developers, under the gun of deadlines / budget / etc., may resort to architectural shortcuts, trading quality for velocity - operating under the misguided mantra of “moving fast and breaking things”.
This is further exacerbated by business stakeholders who, focused on immediate results and quarterly targets, may lack a deeper understanding of the system design trade offs they are signing off.
(2) Changing business requirements
Software systems need to continuously evolve in order to be aligned with their ever-changing contexts and business requirements.
It is expected and inevitable that a project will need to evolve as we refine our understanding of users’ needs and behaviors. Moreover, the business landscape is in constant flux, with new market opportunities emerging that may necessitate a realignment of priorities or the support of an altered feature set.
(3) Lack of system architecture knowledge
In the presence of unclear and/or undocumented architecture, even the most experienced engineers might introduce ADT, not fully understanding all the constraints, architectural details, dependencies and previous architectural decisions.
(4) Technological advancements
The rapid pace at which technology evolves means that an architecture, once cutting-edge, can quickly become outdated if not periodically reassessed and updated.
Failure to transition to newer technologies (strategically and while minimizing disruption) can significantly increase ATD, leaving aging, non-supported solutions within the tech stack.
One example is the over reliance on aging programming languages. There are many instances of companies scrambling to track down specialized COBOL programmers to tape together the technology stack beneath an ancient banking system (there is now over 800 billion lines of COBOL in daily use in production - a language that is over 60 years old!).
(5) Unsuitable architectural decision
ADT could be introduced inadvertently through an inappropriate, sub-optimal architectural decision. For example, choosing to adopt a framework which is misaligned with either the currently implemented architecture or its requirements.
A similarly unsuitable architectural decision would be overestimating the problem which leads you to choose a superfluous solution in the anticipation of a degree of complexity which is never needed.
Contributing factors can be approximate and/or ill-calibrated trade-off analyses, architecture dependency violations or code and/or component duplication across the architecture, etc.
ADT can also be introduced because of cognitive biases such as the Dunning–Kruger effect: system design is a complex field and junior engineers may not even recognize the need for certain best practices, patterns, or the potential long-term consequences of their architectural choices.
Conclusion
Understanding Architectural Technical Debt is an investment in your software's future, ensuring its adaptability, performance, and maintainability.
While convincing business leaders to prioritize the prevention of ADT over the introduction of new features can be challenging, neglecting this essential maintenance in favor of immediate enhancements leads to a far graver situation.
Postponing debt repayment exacerbates problems, resulting in an inability to scale, diminished momentum, and escalating operational difficulties. Ultimately, such neglect will unequivocally obstruct innovation initiatives, stifling the organization's growth and competitive edge.
By embracing tools designed for the very purpose of architectural visibility and collaboration, teams can pivot from reactive firefighting to proactive stewardship.
This is where Multiplayer shines, offering a platform that transcends traditional diagramming tools. With its real-time architectural visualization, observability, and drift detection capabilities, Multiplayer empowers teams to collaboratively navigate and refine their software architecture. It enables a shared understanding and informed decision-making, turning the daunting task of ADT management into an integral, manageable aspect of everyday development work. Sign up and check our platform for free now!