TL;DR: Seven recurring signals mark a codebase as unmanageable, including rising cyclomatic complexity, duplication, coupling, bug density, security debt, and developer turnover, according to Sonar’s analysis. The practical lesson is that code health stops being a subjective debate once teams measure maintainability, reliability, and change risk in the same operational view.
At a glance
What this is: This is an analysis of seven indicators that a codebase has become hard to manage, with Sonar arguing that complexity, duplication, coupling, defects, security debt, and turnover are measurable signals rather than subjective impressions.
Why it matters: It matters because engineering and security teams need a common way to spot code health problems before they become delivery bottlenecks, operational risk, and avoidable maintenance drag.
By the numbers:
- Developers may spend as much as 84% of their time on maintenance and remediation rather than new feature development.
- Code delivery can be up to 50% slower when unmanaged quality issues become a systemic burden.
Context
A codebase becomes unmanageable when small changes stop being small. Complexity, duplication, coupling, defects, and security debt all raise the cost of change until delivery slows and the organisation starts paying a persistent velocity tax.
The governance problem is that code health is often discussed qualitatively, even though the underlying signals are measurable. For teams responsible for software resilience, application security, and developer productivity, the question is not whether code feels messy but which modules are accumulating measurable risk fastest.
Key questions
Q: What is the first thing engineering teams should do when code manageability starts to degrade?
A: Start by measuring the codebase at module level, because manageability problems are easiest to fix when you can see which components are generating the most complexity, duplication, coupling, and defects. Without that baseline, refactoring becomes subjective and teams often optimise the wrong areas.
Q: Why does high coupling create so much delivery risk in practice?
A: High coupling turns a simple change into a chain of dependent changes, which raises the chance of inconsistent updates and regression. The more ripple effects a change creates, the more the team pays in coordination overhead, review burden, and defect introduction.
Q: What are the signs that a codebase is becoming too brittle to change safely?
A: Look for repeated bug fixes that introduce new bugs, persistent churn in modules that should be stable, and sections that engineers avoid touching because they lack confidence in the code. Those signals usually mean structure, documentation, or ownership has broken down.
Q: How should teams decide where to invest refactoring effort first?
A: Prioritise the areas where maintainability, reliability, and security risk overlap, especially modules with high complexity, duplication, and security hotspots. That combination usually produces the highest reduction in delivery friction for the least engineering effort.
Technical breakdown
Cyclomatic complexity and cognitive load
Cyclomatic complexity measures the number of independent paths through a function or module. As that number rises, test effort, review effort, and defect risk increase because developers must reason through more execution paths. Sonar’s framing is useful because it converts an abstract “hard to read” complaint into a measurable maintenance burden. High complexity also tends to cluster with poor modular boundaries, which means fixes take longer and introduce more regression risk. In practice, complexity is less a style problem than a signal that design has outgrown its current structure.
Practical implication: Use complexity thresholds to target the specific functions that should be simplified before they become the source of repeated defects.
Duplication, coupling, and ripple changes
Duplication means the same logic exists in multiple places, so one fix must be applied repeatedly and consistently. Coupling means a change in one area forces changes elsewhere, which is a sign that boundaries are too weak and dependencies are too entangled. Together, they create change friction: the more places touched by a simple change, the more likely drift, inconsistency, and merge conflict become. This is why ripple effects are such a strong manageability signal. They show that the codebase is no longer locally understandable and that change control is becoming structurally expensive.
Practical implication: Track duplicated logic and cross-module dependencies together so refactoring focuses on the highest-friction change paths.
Bug density, security debt, and untouchable code
High bug density shows that quality problems are no longer occasional; they are part of the codebase’s normal operating pattern. When fixes introduce new defects, the problem is usually structural, not isolated. Security debt adds another layer because unsafe patterns and self-admitted technical debt often indicate known weaknesses that have not been removed. Untouchable code is the end state of this progression: a module becomes so risky, opaque, or undocumented that teams stop changing it. At that point, the code is not just hard to maintain. It is effectively excluded from normal engineering control.
Practical implication: Prioritise the modules where bugs, security hotspots, and low test coverage overlap, because those are the most likely to stay fragile.
NHI Mgmt Group analysis
Code manageability is an engineering governance problem, not a taste issue. Sonar’s central point is that manageability can be measured through stability, structure, and change risk, which makes it governable in the same way teams govern security or availability. Once code health is treated as a measurable control surface, leaders can stop debating opinions and start prioritising risk. That changes technical debt from a vague complaint into an operational management issue.
The most important signal is not one metric but the interaction between them. Complexity on its own is noisy, but complexity plus duplication, coupling, and defect density is a much stronger sign of structural decay. That combination tells teams the codebase is absorbing change poorly and that the cost of every future release is rising. The named concept here is velocity tax: the accumulated delivery slowdown caused by unmanaged code health. Engineering leaders should use it as a portfolio-level signal, not a local complaint.
Security and maintainability become inseparable once debt is embedded in production code. Sonar’s discussion of security vulnerabilities and self-admitted technical debt shows that poor code health is also a security governance issue. Weakly controlled code paths make it harder to reason about validation, attack surface, and regression risk, especially when knowledge leaves with developers. The practitioner conclusion is straightforward: treat maintainability as part of security assurance, not as an afterthought to it.
Developer turnover is an outcome signal, not just a people issue. When engineers leave because the code is too hard to work in, the organisation loses the tacit knowledge needed to safely change that code. The debt then becomes more opaque, more expensive, and more resistant to cleanup. That makes retention, documentation, and modularity part of the control environment. Teams should view attrition around high-debt code as evidence that the system has crossed from inconvenience into governance failure.
Automated quality gates are most valuable when they protect new code first. Sonar’s emphasis on continuous analysis aligns with a simple operating principle: stop adding to the problem while you work down the backlog. New-code thresholds, module-level reporting, and severity-based triage help teams direct refactoring effort where it reduces the most risk per unit of time. Practitioners should use automated review to keep decay from compounding further.
What this signals
Velocity tax is the right lens for code decay. When developers spend most of their time fixing and navigating legacy structure, the issue stops being isolated technical debt and becomes an operating model problem. Leaders should watch for any code area where maintenance work consistently crowds out feature work, because that is where delivery capacity is being consumed.
Security assurance should track maintainability, not just vulnerabilities. Vulnerability counts matter, but they do not explain why a codebase keeps generating fragile change. The stronger signal is the intersection of poor structure, low test coverage, and repeated defect introduction, because that is where risk becomes persistent.
Continuous code review turns code health into a managed control rather than a periodic audit exercise. The practical goal is to catch decay while it is still local and cheap to fix, before it becomes untouchable code and an organisational drag.
For practitioners
- Measure code health at module level Use automated static analysis to score complexity, duplication, coupling, reliability, and security hotspots by module so teams can see where manageability is deteriorating.
- Set new-code quality gates Block new changes that introduce avoidable complexity, duplication, or low test coverage, so the backlog stops growing while remediation work is underway.
- Prioritise the highest-friction refactors Rank work by the modules that create the most ripple changes, bugs, and maintenance churn, because those areas are driving the largest delivery penalty.
- Treat security hotspots as maintainability signals Review code areas flagged for unsafe input handling, weak validation, or known technical debt alongside defect trends, not in isolation from them.
- Protect tacit knowledge with documentation and ownership Assign clear ownership to fragile components and document the reasoning behind recent changes before key developers move on from the codebase.
Key takeaways
- Unmanageable codebases are identifiable through repeatable signals such as complexity, duplication, coupling, defects, security debt, and turnover.
- The operational cost is not limited to maintenance spend, because unmanaged code also slows delivery and increases the chance of brittle changes.
- The most effective response is continuous measurement with prioritised refactoring of the modules that create the highest risk and the greatest change friction.
Standards & Framework Alignment
This section maps relevant standards and security frameworks to the operational risks and controls described in this guidance.
NIST CSF 2.0, CIS Controls v8, OWASP SAMM, OWASP ASVS and NIST SP 800-53 Rev 5 set the governance and control requirements practitioners need to meet.
| Framework | Control / Reference | Relevance |
|---|---|---|
| NIST CSF 2.0 | GV.OV-01 — Oversight of Cyber Risk Management | Code health is being framed as a governable operational risk across engineering teams. |
| Recommendation — Use governance oversight to treat code manageability as a measurable risk, not a subjective engineering debate. | ||
| CIS Controls v8 | CIS-16 — Application Software Security | The article focuses on quality gates, secure coding, and recurring software defects. |
| Recommendation — Apply application software security practices to reduce defects, hotspots, and unsafe code patterns before release. | ||
| OWASP SAMM | Governance — Governance | The post is about measuring and improving software assurance maturity across the SDLC. |
| Recommendation — Build software assurance metrics into governance so teams can measure and improve code health continuously. | ||
| OWASP ASVS | V15 — Secure Coding and Architecture | The article discusses structural code quality issues that affect maintainability and security. |
| Recommendation — Use secure coding and architecture requirements to limit complexity, duplication, and risky design drift. | ||
| NIST SP 800-53 Rev 5 | SA-11 — Developer Testing and Evaluation | Automated review and quality gates are directly aligned to evaluating code before merge. |
| Recommendation — Require development testing and evaluation controls that catch fragile code before it reaches production. | ||
Key terms
- Cyclomatic Complexity: A measure of how many independent paths exist through a function or module. Higher complexity usually means more branching, more testing effort, and greater risk that a small change will create unexpected behaviour or maintenance overhead.
- Technical debt: Legacy shortcuts or weak design choices that create future cost, risk, or operational friction. In identity programmes, technical debt often shows up as brittle trust relationships, inconsistent revocation, poor traceability, or controls that only work in one environment and fail in another.
- Code Churn: Code churn is code that is committed and then quickly reverted or substantially rewritten. High churn often signals poor fit between the change and the codebase, and in AI-assisted workflows it can indicate that the agent was missing context, producing plausible output that had to be repaired later.
- Security Hotspot: A Security Hotspot is a code finding that may deserve review but is not automatically treated as a confirmed vulnerability. It tells teams to examine the surrounding context before deciding whether the issue is risky. This approach reduces false alarms, but it also depends on disciplined manual review.
Deepen your knowledge
NHI Mgmt Group covers identity security, NHI governance, and agentic AI through independent research, practitioner guides, and the NHI Foundation Level course. If your programme also has to govern software delivery risk, the same discipline of measurement and control still applies.
Published by the NHIMG editorial team on August 20, 2026.
Updated on October 12, 2026.
NHI Mgmt Group, the independent authority on Non-Human Identity, IAM, and Agentic AI security. nhimg.org