Measure the quantitative complexity of a program's control flow graph. Essential for code quality assessment and identifying difficult-to-test functions.
Last updated: March 2026 | By Patchworkr Team
Transitions between statements (control flow edges)
Statements or basic blocks in flow graph
Usually 1 for a single function
Cyclomatic complexity is a software metric developed by Thomas J. McCabe, Sr. in 1976 that quantifies the complexity of a program's control flow. It measures the number of linearly independent paths through a program's source code, providing an objective measure of code complexity. The metric is calculated from a control flow graph of the code.
The metric is based on graph theory, where code is represented as a directed graph with nodes (program statements or basic blocks) and edges (control flow transitions). Cyclomatic complexity equals the number of decision points plus one, or more formally: M = E - N + 2P, where E is edges, N is nodes, and P is connected components (usually 1 for a single function).
Risk Band Guidance: The commonly cited thresholds (≤10 = low, ≤20 = moderate, ≤50 = high, >50 = very high) are heuristics and guidelines developed from industry experience, not universal laws. Different organizations, languages, and coding styles may have different acceptable thresholds. Context matters: complex business logic may justify higher thresholds, while security-critical code should aim for lower values. Use this metric as one of many tools to identify code that needs review and testing, not as an absolute gating criterion.
Higher complexity correlates with more bugs, harder maintenance, and lower test coverage. Functions exceeding the chosen complexity threshold are candidates for refactoring. The metric helps developers identify code that is difficult to understand, test, and maintain. Modern static analysis tools automatically calculate this metric for every function in a codebase.
Low risk, easy to test
Moderate risk, harder to test
High risk, unstable
Extremely high risk
Calculate complexity for a simple if-else statement:
High complexity correlates with more bugs, harder maintenance, and lower test coverage. Studies show defect density increases exponentially with complexity. Functions with complexity >10 are 2-3× more likely to contain bugs than simpler functions.
Break large functions into smaller ones, reduce nested loops and conditionals, use early returns to flatten logic, replace complex switch statements with polymorphism or lookup tables, and extract complex conditions into well-named functions.
Not necessarily. Some algorithms are inherently complex (parsing, state machines). However, high complexity is a signal to review code for potential simplification. If unavoidable, add comprehensive tests and clear documentation.
Most modern IDEs and linters calculate complexity: ESLint (JavaScript), Pylint (Python), RuboCop (Ruby), SonarQube (multi-language), CodeClimate, and built-in analyzers in Visual Studio, IntelliJ, and VS Code extensions.
Cyclomatic complexity represents the minimum number of test cases needed for complete branch coverage. Complexity of 10 requires at least 10 test cases. Higher complexity exponentially increases the test effort required.
Industry best practices suggest keeping functions under 10. Google and many companies enforce limits around 15. Functions exceeding 20 should be refactored. Critical or security-sensitive code should stay below 10.
It's one indicator, not a complete measure. Low complexity helps, but you also need good naming, documentation, and architecture. A function can be complex but well-written, or simple but poorly designed. Use it alongside other metrics.
Draw a control flow graph: nodes are statements/blocks, edges are transitions. Count each if/while/for/case as decision nodes. Count edges between nodes. For connected components, count exit points (usually 1 for most functions).
Related Tools