Glossary · Code health

What is cyclomatic complexity?

Cyclomatic complexity is a count of the linearly independent paths through a function. Thomas McCabe defined it in 1976 as M = E - N + 2P on the control-flow graph. In practice it equals the decision points (if, loops, case, catch, && and ||) plus one, and it roughly counts the tests needed to cover every branch.

Last reviewed: November 2026

Also called McCabe complexity, CCN, Cyclomatic complexity number

In depth Nested vs cyclomatic complexity: the same code scored both ways, and which metric to trust for what.

How cyclomatic complexity is measured

McCabe's 1976 paper, "A Complexity Measure" (IEEE Transactions on Software Engineering), defines it on the control-flow graph: M = E - N + 2P. For one function, P = 1. A function with a single if has three nodes (the condition, the branch body, the exit) and three edges, so M = 3 - 3 + 2 = 2.

In practice: start at 1, add 1 for each if, elif, loop, case, catch, ternary, and each && or ||.

A worked example:

def ship(order):
    if order.paid and order.items:   # +1 if, +1 and
        for item in order.items:     # +1 loop
            if item.fragile:         # +1 if
                pack_with_foam(item)
            else:
                pack(item)
    elif order.draft:                # +1 elif
        discard(order)

Five decision points, so complexity is 6, also the number of independent paths to test.

Tools disagree on details such as how a switch is counted, so compare numbers only within one tool.

Why cyclomatic complexity matters

Each independent path needs a test, so complexity 25 means at least 25 cases, and more branches mean more states to hold in your head. The metric ignores layout: ten checks in a row and ten nested ten deep both score 11, which is why cognitive complexity exists. A complex function nobody changes is cheap to leave; the CRAP score combines complexity with coverage to find the ones that matter.

How to measure cyclomatic complexity yourself

  • Python: radon cc -s -a src/ prints a letter grade and number per function; flake8 --max-complexity 10 fails on anything above 10.
  • Many languages: lizard src/ reports CCN per function across C, C++, Java, JavaScript, Go, Python, Rust and others; lizard -C 10 -w src/ prints only functions above 10.
  • JavaScript and TypeScript: the ESLint complexity rule, for example "complexity": ["error", 10].
  • Go: gocyclo -over 10 ..

These suit a lint gate in CI. They do not know which functions change often.

How repowise measures cyclomatic complexity

repowise computes McCabe complexity (it calls it CCN) per function in a single tree-sitter pass, for languages with a complexity map, using the same rule above: branches, loops, cases, catches and boolean operators. else if and elif chains add CCN but not a nesting level. C and C++ #if/#else blocks take the largest arm, not the sum, because the arms are alternative builds.

Thresholds in the detectors, read from the source:

DetectorFires whenSeverity steps
complex_methodCCN 9 or highermedium from 9, high from 15, critical from 25
brain_methodNLOC 70+, CCN 9+ and a central filelisted, not scored
large_methodNLOC 60+ and CCN 3 or morelow to critical by length
god_class200+ code lines, 15+ methods and a brain methodseverity by size

For a function that is mostly one switch or if chain on a single value, the detectors judge the code around the dispatch plus its heaviest arm, and the finding shows the raw count too. Complexity is read beside churn, so a CCN 47 function in a file changed 19 times this quarter outranks the same function in a quiet file.

Where to see it: repowise health (--file <path> for one file), get_health over MCP, and the code health feature page. No LLM is involved. For the paths-versus-reading-cost comparison, see nested vs cyclomatic complexity.

FREQUENTLY ASKED

Cyclomatic complexity: questions

What is the formula for cyclomatic complexity?

M = E - N + 2P, where E is the number of edges and N the number of nodes in the control-flow graph, and P the number of connected components (1 for a single function). The shortcut most tools use: count the decision points in a function and add 1.

What does it mean when cyclomatic complexity is too high?

Many independent paths, so many tests and more places for a bug to hide. High values often mark functions doing several jobs. A flat switch can score high and still read easily.

What is a good cyclomatic complexity?

McCabe suggested a limit of 10 per function, and many linters default near it. 1 to 10 is generally simple, 11 to 20 deserves a look, and above 20 is usually worth splitting. Treat the numbers as review triggers, not laws.

Is cyclomatic complexity the same as lines of code?

No. A 200-line function with no branches scores 1, and a 15-line function with six conditions scores 7.

See it on your own repository.

Index a repository free and read the result for your own code and history. Rolling it out to a team? We will walk you through it.