TL;DR overview
- Cyclomatic Complexity is a classic software metric that counts the number of independent execution paths through a function—providing a quantitative measure of how difficult code is to test and maintain.
- Functions with high cyclomatic complexity require more test cases to achieve full branch coverage, are harder to understand, and are more prone to bugs—particularly in edge cases.
- SonarQube applies cyclomatic complexity rules to flag overly complex functions across 30+ languages, encouraging developers to refactor large, branchy functions into smaller, testable units.
- While Cyclomatic Complexity is useful for identifying complexity hotspots, Sonar's Cognitive Complexity metric is a more modern alternative that better reflects how difficult code is to read and understand in practice.
Googling on Cyclomatic Complexity (CC), gives some interesting results... Among those results, you'll find the two following definitions :
- A measure of the complexity of a software module, equal to e - n + 2, where e is the number of edges in the control flow graph and n is the number of nodes in this graph (that is, the cyclomatic number of the graph plus one)
- A measurement of the intricacy of a program module based on the number of repetitive cycles or loops that are made in the program logic. It is used as a general measure of complexity for software quality control as well as to determine the number of testing procedures
- ...
Those two definitions, though perfectly true, are one of the reason for Sonar to exist: going away from the fact that code source quality is a notion only accessible to elite. Sonar is about democratization of the source code quality concepts to be understandable and usable by every stakeholder in a development project.
Having said that, what is it that CC is trying to represent? This is roughly the number of different paths in your source code and there are two ways in java to begin a new path :
- Calling a method (CC + 1)
- Encountering the following keywords : if, while, repeat, for, &&, ||, catch, case, etc ... (CC + 1)
The good news is that calculating the cyclomatic complexity is a human accessible operation. Moreover, according to the previous definition it's easy to understand that the more paths you have in your application, the more complex your application will be.
But does that mean a program with a high cyclomatic complexity has a poor quality ? For sure not ! Otherwise all developers would prevent themselves from doing anything beyond a simple "HelloWorld" program whose cyclomatic complexity is 1 and would quickly lose their jobs :-)
Having a high total cyclomatic complexity on a program just means that a lot of logic has been implemented in the program but you cannot deduce any quality information from there. When zooming on classes or methods, that's another story.
Is it better to have a method with a CC of 30, or three methods with a CC of 10 each ? If you have been in charge of source code maintenance for an application written by somebody else, you know the answer : when having three methods with a CC of 10 each, the chance is higher that the program is more maintainable, with a better separation of logic. As a consequence, you also decrease the risk to inject a bug. The CC value by method can be used to evaluate the quality of the source code.
At the class level, you can follow the same logic : high CC by class could be the witness of bad levels of decoupling, encapsulation and cohesion.
In fact, what matters in a program is not its total cyclomatic complexity but the fact that each of its methods / classes has a suitable low level of CC.
We'll discuss in an other post how valuable Sonar can be to help identify those non suitable parts of source code.

