Cyclomatic Complexity

McCabe, 1976: the number of linearly independent paths through a program’s control-flow graph — V(G) = E − N + 2P (edges − nodes + 2×components), equivalently decisions + 1. It answers: how many paths must tests cover?

What it counts

One increment per branching construct: if, while, for, case labels, catch, &&/||, ternary. A straight-line function is 1 regardless of length.

What it’s for (and what it isn’t)

  • Its native job is testability: V(G) = the minimum number of test cases for branch coverage. That’s the original paper’s claim, and it still holds.
  • It’s a path count, not a comprehension measure: a 20-case switch on an enum scores ~20 but reads fine (uniform structure); a nested-arrow of 20 mixed conditions scores the same and is a nightmare. McCabe treats all decisions as equal — human readers don’t.

Thresholds (folklore with a basis)

McCabe’s own guidance: limit V(G) to 10; 11–20 = refactor-worthy; 20+ = high risk. SonarSource historically gates at 10 for methods. These are heuristics, not laws — a switch-heavy dispatcher at 25 is usually healthier than recursion-plus-nesting at 15.

Measurement

cccc (OSS) (96★ Rust, MIT) computes it per-function across 20+ languages in one binary (alongside Cognitive Complexity); rustc’s clippy, lizard, SonarQube, and most linters carry it.

The agent-era use (why it’s back)

André Staltz: install cccc, gate max-cyclomatic (he suggests 40 as a lenient ceiling), and instruct agents in AGENTS.md to validate the gate passes — then “have one agent in ultracode refactor everything until cccc passes.” A deterministic, machine-checkable complexity budget as the contract the refactor agent must satisfy. This is Pit of Success for agent-written code: the checkable rail, not prose review — and it survives Software engineering in AI era’s finding that human code review is going zombie.

Vault kin

  • Cognitive Complexity — the readability-weighted successor; use both: cyclomatic for test surface, cognitive for comprehensibility
  • Fearless refactoring — complexity budgets are what make refactoring fearless
  • LLM evals — deterministic checks are the eval ladder’s floor; a complexity gate is a tiny eval that never needs a grader