The true measure of software quality

Amir Rapson

February 28, 2025

How to measure software quality: Architecture or code

This piece originally appeared in AWS ComSum Quarterly, an independent publication dedicated to knowledge-sharing within the AWS community. For this edition, Amir Rapson, CTO of vFunction, guest-edited the issue to highlight a critical truth: software quality isn’t just about code—it’s about architecture.

The principles of good software are a popular discussion topic at vFunction. Improving software quality is at the heart of our mission—whether for cloud migration, cost reduction, or simply building better software. Our focus, architectural observability, centers on improving applications via software architecture. You can have bad software built entirely of good code, because software quality isn’t just about clean syntax or following patterns. Software architecture is the crucial element of software quality.

Yet, we still encounter software architectures that make us question our principles and spark discussions like “But why is this bad?” or “How would you fix this?”

This article sets the groundwork for what makes software truly good—not just at the code level but at the architectural level. We hope sharing our perspective provides valuable insights and meaningful discussions on the essential elements of good software.

What makes one piece of software better than another?

To define software quality, let’s start with some common ground. Imagine that every piece of software meets its current requirements and satisfies its current user needs—it’s easy if you try. With that assumption, we can easily differentiate between good software and better software. Now, suppose this software is reliable under the current conditions—it isn’t hard to do—and even performs well with the current resources—I wonder if you can...

Alas, software is never static. Requirements, users, and usage patterns and conditions are always subject to change. What is considered “ok” in terms of operational costs and performance today may be the cause of a major headache tomorrow.

Assuming no software is future-proof—if it were, why wasn’t it released sooner?—then, software quality in this imaginary world can be defined by how easily it adapts:

  • Functionality & usability: Can the software be easily modified, updated, and repaired to meet new requirements and usage patterns?  
  • Security & portability: Can updates to security vulnerabilities be made quickly without risking the stability of the software? Can the software run in new environments and platforms with minimal changes?
  • Reliability & quality: Can the software perform reliably despite constant changes, with little impact on other components? Will it deploy efficiently with changes?

Good architecture, good code, and their contribution to good software

A fabulous article from 2012, “In Search of a Metric for Managing Architectural Technical Debt,” describes a simple model to calculate architectural technical debt. By defining this metric, the authors imply that good architecture is one with minimal architectural technical debt. The article states that the “cost of reworking” a software element is the sum of the cost of reworking all its dependent elements. This means good architecture minimizes dependencies—whether code classes, modules, or libraries. Fewer dependencies ensure when we modify a piece of software, we only need to rework a small set of elements vs. a cascade of rework across the system.

Returning to the definition of better software—we can now say that better architecture makes for better software.

Good code is another matter. A class with good code can minimize the rework effort for that specific class. With readability, coding standards, and code reviews, a class can be maintained more easily. The effect of good code is primarily limited to its class. In other words, you can have bad software built with good code.

For further exploration, you may want to read  “Is your software architecture as clean as your code?” which explains the principles of good architecture that lead to minimizing dependencies, and “Measure It? Manage It? Ignore It? Software Practitioners and Technical Debt” which emphasizes the importance of architectural technical debt as a source of technical debt.

AWS Comsum Quarterly image

AWS ComSum is an independent, community-driven initiative that fosters collaboration among AWS users, helping them navigate the ever-evolving cloud landscape.

Quality practices that support software quality

Besides the key element of having good software architecture, other practices contribute to the quality of software and reduce the cost of reworking or adding new capabilities to an existing software application:

  1. Clear requirements & design: Clear and precise requirements and a detailed blueprint of the potential dependent elements ensure that engineers understand the task at hand. Bad requirements and design will lead to confusion and possible rework.
  2. Robust testing & QA: Conducting various levels of testing (unit, integration, system, load, and acceptance testing) ensure the software functions correctly and meets quality standards. The more automated and complete the testing, the easier it is to minimize the time to release software. Less dependencies for the changed element allow QA to focus on the specific functionality rather than conducting acceptance on the entire system.
  3. Automated CI/CD, security testing and tooling: Automating the process of code integration, testing, vulnerability testing, and deployment to ensure rapid and reliable delivery of software updates.

With these elements, software engineers can develop high-quality software that meets user expectations and performs reliably. However, while these practices support a good software development lifecycle, they do not ensure that the software itself is of good quality.

How to measure software quality

If you’ve made it this far, then you may agree that evaluating software quality predominantly involves assessing its architecture. Here are some approaches and metrics to evaluate it:

  • Architectural peer reviews: Systematically evaluate architectural decisions and trade-offs by conducting reviews with architects and engineers. Assess the architecture’s quality, feasibility, and alignment with requirements. 
  • Documentation quality: Ensure the architecture is well-documented, including diagrams and design decisions to support understanding, maintenance, and evolution as the software changes. Strive, through the use of tools, to keep your documentation accurate and up to date with minimal overhead.
  • Coupling & cohesion: Measure the degree of dependency between components (coupling) and the degree to which components are related (cohesion). At vFunction, we call this metric “exclusivity,” which measures the percentage of classes or resources required solely for the component.
  • Technical debt & architectural complexity: Measure the amount of work required to fix issues in the architecture. For instance, you can count story points in your refactoring backlog or sum up weighted scores on your to-dos.
  • Modularity: Assess the degree to which the architecture supports modularization and reuse of components. Look for ways to ensure and monitor modularity through compile-time boundaries and runtime monitoring.
  • Code complexity & code churn: Use existing tools to measure cyclomatic complexity and maintainability. Although certain parts of the code need to be complex, if all your code is complex, you have a problem. Code churn is the percentage of code that’s added and modified over time. If the same code changes all the time, or too many classes get checked in at once, there are probably too many dependencies in the code.

By employing these approaches and metrics, you can effectively assess the quality of your software architecture and ensure it can support future changes to the application.

Other measures that support software quality

As you consider how to measure software architecture quality in your organization, the following measures serve as a safety net for software quality. Ironically, these are measured more often than software quality itself. Here are some common metrics and methods:

  • Test coverage: The percentage of code executed by the test cases, ensuring that all parts of the code are tested. Think about mimicking production behavior and not just covering every line in your code, since the same code can be executed in different contexts by your real users. In vFunction, we call this “Live Flow Coverage.”
  • Reliability metrics (MTBF, MTTR): The average time between failure and the time taken to repair the software following a failure. Application performance monitoring (APM) tools are built to monitor this.
  • Performance issues and error rates: The frequency of performance glitches and user errors while interacting with the software. This, too, can be monitored with APM tools.

GenAI, code quality, and its contribution to software quality

GenAI tools enhance code quality by automating and assisting with various aspects of coding, including:

  • Code generation: Generating boilerplate code, repetitive code patterns, and even complex algorithms, which reduces human error and improves consistency.
  • Code reviews: Assisting in code review processes by identifying potential issues, code smells, and suggesting improvements.
  • Testing: generating unit tests, integration tests, and other forms of automated testing to ensure code correctness and reliability.

GenAI also plays a lesser role in improving overall software quality by supporting higher-level aspects of software development, such as:

  • Requirements analysis & design: Analysing user requirements and generating relevant documentation.
  • Performance optimization: Suggesting optimizations to enhance software performance.

While GenAI tools are particularly effective in enhancing code quality by automating and optimizing coding tasks, their contribution to software quality is limited. If GenAI tools can create a lot more code, then measuring and maintaining good quality and good architecture becomes even more critical.

Software architecture: The foundation of software quality

Good software architecture is essential for building high-quality applications that adapt easily to changing requirements and support future enhancements. By measuring and assessing the quality of your architecture, you can ensure that your software will be able to meet the changing needs of your users and business. 

Consider how your organization currently measures software quality, and the growing importance of doing so in a world increasingly driven by GenAI tools. Take proactive steps to ensure  your software is reliable, maintainable, and scalable, which is what engineering excellence is all about.

What is software architecture? Checkout our guide.
Read More

Amir Rapson

CTO & CCSO/Co-Founder

Amir Rapson co-founded vFunction and serves as its CTO, where he leads its technology, product and engineering. Prior to founding vFunction in 2017, Amir was a GM and the VP R&D of WatchDox until its acquisition by Blackberry, where Amir served as a VP of R&D. Prior to WatchDox, Amir held R&D positions at CTERA Networks and at SofaWare (Acquired by Check Point). Amir has an MBA from the IDC Herzlia, and a BSc in Physics from Tel-Aviv University.

Get started with vFunction

See how vFunction can accelerate engineering velocity and increase application resiliency and scalability at your organization.