← Home ← Codex ← DEBT
Browse by Category
+ added · updated 7d
← Back to glossary

Cyclomatic Complexity

Code Quality Intermediate
debt(d3/e5/b5/t5)
d3 Detectability Operational debt — how invisible misuse is to your safety net

Closest to 'default linter catches the common case' (d3). The term's detection_hints lists phpmd, phpcs, phpmetrics, phploc as tools that automatically detect high cyclomatic complexity. PHPMD is commonly configured in CI pipelines and reports CC >10 by default, making this a standard lint-level catch rather than requiring specialist SAST tools.

e5 Effort Remediation debt — work required to fix once spotted

Closest to 'touches multiple files / significant refactor in one component' (e5). The quick_fix says to 'extract decisions into separate methods,' but as common_mistakes notes, 'extracting private methods but keeping the same logic' just shifts the score. Genuine remediation requires rethinking the branching logic, often involving strategy patterns, polymorphism, or restructuring conditionals — a significant refactor within the component, not a one-line fix.

b5 Burden Structural debt — long-term weight of choosing wrong

Closest to 'persistent productivity tax' (b5). Cyclomatic complexity applies across all contexts (web, cli, queue-worker) per applies_to. High-complexity functions slow down multiple work streams: testing becomes harder (each branch needs coverage), debugging takes longer, and onboarding new developers suffers. However, it doesn't define system architecture (b7-b9) — it's a function-level concern that accumulates into a steady tax rather than a gravitational force.

t5 Trap Cognitive debt — how counter-intuitive correct behaviour is

Closest to 'notable trap (a documented gotcha most devs eventually learn)' (t5). The misconception field directly states the trap: developers believe 'cyclomatic complexity below 10 means a function is simple enough,' but CC is a guideline, not a guarantee. Common_mistakes also highlights confusion with cognitive complexity. These are well-known gotchas in the static analysis community that most developers learn, but they still catch intermediate developers who treat the metric as absolute.

About DEBT scoring →

Also Known As

CC McCabe complexity decision complexity

TL;DR

A count of linearly independent paths through a function — each if, for, while, case, and && adds 1.

Explanation

Defined by Thomas McCabe in 1976, cyclomatic complexity measures the number of independent paths through a piece of code. Each decision point (if, elseif, for, while, foreach, case, catch, ||, &&, ?:) adds 1 to the base score of 1. A score of 1–5 is simple, 6–10 is moderate, 11–20 is complex, 20+ is very high risk. High cyclomatic complexity correlates with higher defect density and lower testability — you need at least one test per path to achieve full branch coverage.

Common Misconception

Cyclomatic complexity below 10 means a function is simple enough. The threshold is a guideline, not a guarantee — a function with 8 branches acting on global state can be far harder to understand than one with 15 well-named branches on a simple data structure.

Why It Matters

Cyclomatic complexity counts independent execution paths — a score above 10 predicts defect density and indicates a function that is hard to fully test and reason about.

Common Mistakes

  • Not measuring cyclomatic complexity as part of CI — it only gets addressed when someone notices, not systematically.
  • Reducing complexity by extracting private methods but keeping the same logic — the extracted methods just shift the score.
  • Targeting zero complexity — some decision logic is inherently complex; the goal is appropriate decomposition.
  • Confusing cyclomatic complexity with cognitive complexity — cyclomatic counts branches, cognitive accounts for nesting depth.

Code Examples

💡 Note
Every branch adds 1 to CC. Aim for CC ≤ 10 per method; above 15 is a strong refactor signal.
✗ Vulnerable
// CC = 8 (one path per branch)
function classify(int $score): string {
    if ($score >= 90) {
        return 'A';
    } elseif ($score >= 80) {
        return 'B';
    } elseif ($score >= 70) {
        return 'C';
    } elseif ($score >= 60) {
        return 'D';
    } else {
        return 'F';
    }
}
✓ Fixed
// CC = 2 — data-driven, trivially testable
function classify(int $score): string {
    return match(true) {
        $score >= 90 => 'A',
        $score >= 80 => 'B',
        $score >= 70 => 'C',
        $score >= 60 => 'D',
        default      => 'F',
    };
}

Added 15 Mar 2026
Edited 22 Mar 2026
Views 66
Rate this term
No ratings yet
🤖 AI Guestbook educational data only
| |
Last 30 days
0 pings T 0 pings W 1 ping T 0 pings F 1 ping S 0 pings S 0 pings M 0 pings T 0 pings W 0 pings T 5 pings F 2 pings S 3 pings S 1 ping M 0 pings T 2 pings W 0 pings T 0 pings F 1 ping S 0 pings S 0 pings M 0 pings T 0 pings W 0 pings T 0 pings F 1 ping S 0 pings S 0 pings M 0 pings T 0 pings W
No pings yet today
No pings yesterday
Scrapy 12 Perplexity 11 Ahrefs 10 Amazonbot 9 Google 4 SEMrush 4 ChatGPT 4 Unknown AI 2 Claude 1 Bing 1 Meta AI 1
crawler 54 crawler_json 5
DEV INTEL Tools & Severity
🟡 Medium ⚙ Fix effort: Medium
⚡ Quick Fix
Functions with cyclomatic complexity >10 are hard to test — each decision point requires another test case; extract decisions into separate methods
📦 Applies To
any web cli queue-worker
🔗 Prerequisites
🔍 Detection Hints
Function with 10+ if/else/switch/loop/catch branches; phpmd reports CC >10; 10+ test cases needed for single function
Auto-detectable: ✓ Yes phpmd phpcs phpmetrics phploc
⚠ Related Problems
🤖 AI Agent
Confidence: High False Positives: Low ✗ Manual fix Fix: Medium Context: Function Tests: Update


✓ schema.org compliant