Shift Left to Avoid Technical Debt Disasters: The Need for Continuous Modernization

Bob Quillin May 24, 2023

Can technical debt cause business disasters? Just ask Southwest Airlines: their technical debt caused a shutdown during the 2022 Christmas season that cost the company more than $1 billion, not to mention the goodwill of irate customers who were stranded by the collapse of the carrier’s flight and crew scheduling system.

Or you could ask Elon Musk, whose new Twitter acquisition suffered its own chaos-inducing disruption in March of 2023 due to what one employee described as “so much tech debt from Twitter 1.0 that if you make a change right now, everything breaks.”

As these examples indicate, unaddressed technical debt can indeed pitchfork a company into a sudden and disastrous disruption of its entire operation. That’s why for many companies, addressing the technical debt carried by the mission-critical software applications they depend on is at the top of their IT priorities list.

But identifying and reducing technical debt can be difficult. And that’s especially true of architectural technical debt, which is often even harder to isolate and fix.

In this article, we’ll examine the challenges of architectural technical debt, and see how continuous modernization, along with the “shift left” approach to quality assurance (which helps minimize that debt by beginning QA evaluations early in the development process) can substantially reduce a company’s vulnerability to technical debt disasters.

What is Architectural Technical Debt?

The Journal of Systems and Software describes technical debt as “sub-optimal design or implementation solutions that yield a benefit in the short term but make changes more costly or even impossible in the medium to long term.” Although the term has generally been applied to code, it also applies to architectural issues. The Carnegie Mellon Software Engineering Institute defines architectural technical debt similarly, in this way:

“Architectural technical debt is a design or construction approach that’s expedient in the short term, but that creates a technical context in which the same work requires architectural rework and costs more to do later than it would cost to do now.”

Architectural technical debt may be baked into an application’s design before coding even starts. A good example is the fact that most legacy Java apps are structured as monoliths, meaning that the codebase is organized as a single, non-modularized unit that has functional implementations and dependencies interwoven throughout.

Because the app’s components are all together in one place and communicate directly through function calls, this architecture may at first appear less complex than, for example, an architecture built around independent microservices that communicate more indirectly through APIs or protocols such as HTTPS.

Related: The Cost of Technical Debt and What It Can Mean for Your Business

But the tight coupling between functions in monolithic code imposes severe limitations on the flexibility, adaptability, and scalability of the app. Because functions are so interconnected, even a small change to a single function could have unintended consequences elsewhere in the code. That makes updating monolithic apps difficult, time-consuming, and risky since any change has the potential to cause the entire app to fail in unanticipated ways.

Challenges of Managing Architectural Technical Debt

Not only may initial design decisions insert architectural technical debt into apps up front, but changes that occur over time, through a process known as architectural technical drift, can be an even more insidious driver of technical debt.

Architectural technical drift occurs when, to meet immediate needs or perhaps because requirements have changed, developers modify the code in ways that deviate from the planned architecture. The result is that over time the codebase diverges more and more from the architectural design specification.

What makes such drift so dangerous is that while designed-in architectural debt can be identified by comparing the design specification against modern best practices, the ad hoc changes inserted along the way by developers are typically documented poorly—if at all. 

The result is that architects often have little visibility into the actual state of a legacy codebase since it no longer matches the architecture design specification. And that makes architectural technical debt very hard to identify and even harder to fix.

The problem is that while architects have a variety of tools for assessing code quality through, for example, static and dynamic analysis or measuring cyclomatic complexity (a metric that reveals how likely the code is to contain errors, and how hard it will be to test, troubleshoot, and maintain), they haven’t had comparable tools for assessing how an app’s architecture is evolving or drifting over time.

Why Measuring and Addressing Architectural Technical Debt is Critical

While code quality and complexity are key application health issues, architectural technical debt is an even higher level concern because unaddressed architectural deficiencies can make it very difficult, or even impossible, to upgrade apps to keep pace with the rapidly evolving requirements that define today’s cloud-centric technological environment.

For example, the monolithic architecture that characterizes most legacy Java codebases is notorious for having ingrained and intractable technical debt that imposes severe limitations on the maintainability, adaptability, and scalability of such apps.

But given the difficulty of detecting and measuring architectural technical debt, how can architects effectively address it to prevent it from eventually causing serious issues? As management guru Peter Drucker famously said, “You can’t improve what you don’t measure.”

The answer is by following a “shift left” QA strategy based on use of the advanced AI-based tools now available for detecting, measuring, monitoring, and remediating architectural debt and drift issues before they cause technical debt meltdowns.

Shifting Left to Address Architectural Technical Debt

In the traditional waterfall approach to software development, operational testing of apps comes near the end of the development cycle, usually as the last step before deployment. But architectural issues that come to light at that late stage are extremely difficult and costly to fix, and may significantly delay deployment of the app. The shift left approach originally aimed to alleviate that problem.

In essence, shift left moved QA toward the start of the development cycle—the technique gets its name from the fact that diagrams of the software development sequence typically place the initial phase on the left with succeeding phases added on the right. Ideally, the process begins, before any code is written, by assessing the architectural design to ensure it aligns with functional specifications and customer requirements.

Shift left is a fundamental element of Agile methodology, which emphasizes developing, testing, and delivering working software in small increments. Because the code delivered with each Agile iteration must function correctly, shift left testing allows verification of the design and performance of components such as APIs, containers, and microservices under realistic runtime conditions at each step of the development process.

In this context, shifting left for architecture gives senior engineers and architects visibility into architectural drift throughout the application lifecycle. It makes modernization a closed-loop process where architecture debt is always being proactively observed, tracked, baselined, and where anomalies are detected early enough to avoid disasters.

That’s especially beneficial for modernization efforts in which legacy apps are refactored from monoliths to a cloud-native microservices architecture. Since microservices are designed to function independently of one another, the shift left approach helps to ensure that all services integrate smoothly into the overall architecture and that any functional incompatibilities or communications issues are identified and addressed as soon as they appear.

The Importance of Continuous Modernization

One of the greatest benefits of legacy app modernization is that it substantially reduces technical debt. This is especially the case with monolithic apps—the process of refactoring them to a microservices architecture automatically eliminates most (though not necessarily all) of their technical debt.

But modernization isn’t a one-time process. Because of the rapid advances in technology and the quickly evolving competitive demands that characterize today’s business environment, from the moment an app is deployed it begins to fall behind the requirements curve and become out of date.

Plus, the urgency of those new requirements can put immense pressure on development and maintenance teams to get their products deployed as quickly as possible. That, in turn, often leads them to make “sub-optimal design or implementation solutions that yield a benefit in the short term.” And that, by definition, adds technical debt to even newly designed or modernized apps.

As a result, the technical debt of any app will inevitably increase over time. That’s not necessarily bad; it’s what you do about that accumulating debt that counts. Ward Cunningham, who coined the term “technical debt” in 1992, puts it this way:

“A little debt speeds development so long as it is paid back promptly with refactoring. The danger occurs when the debt is not repaid.”

That’s why continuous modernization is so critical. Without it, the technical debt carried by your company’s application portfolio is never repaid and will continue to increase until a business disaster of some kind becomes inevitable. As a recent Gartner report declares:

“Applications and software engineering leaders must create a continuous modernization culture. Every product or platform team must manage their technical debt, develop a modernization strategy and continuously modernize their products and platforms… Teams must ensure that they don’t fall victim to “drift” over time.”

Related: The Top 5 Reasons Technical Debt Accumulates in Your Business Applications

The Key to Continuous Modernization

Until recently, it’s been difficult for software development and engineering leaders to establish a culture of continuous modernization because they lacked the specialized tools needed for observing, tracking, and managing technical debt in general—and architectural technical debt in particular. But the recent advent of AI-based tools specially designed for that process has been a game changer. They enable software teams to identify architectural issues, understand their complexity, predict how much time and engineering effort will be required to fix them, and actually lead the team through the refactoring process.

The vFunction Continuous Modernization Manager enables architects to apply the shift left principle throughout the software development lifecycle to continuously identify, monitor, manage, and fix architectural technical debt problems. In particular, it enables users to pinpoint architectural technical drift issues and remediate them before they contribute to some future technical debt catastrophe.

If you’d like to know more about how an advanced continuous modernization tool can help your company avoid technical debt disasters, contact us today.