Home About Subscribe RSS

Software Complexity

Tackling Complexity in Software Engineering

NPath and Cyclomatic Complexity

By Andrew Rousseau. Published on March 6, 2025.

In my previous post on Dynamic Complexity, we talked about how breaking code up into multiple methods and having multiple conditions inside a method increases software complexity. There are a few different ways of measuring this type of complexity and we’ll explore a few here in this post.

NPath complexity

NPath complexity Is a measure of the number of possible outcomes that a method can produce. There are a number of static code analysis tools that can help measure this. Many of those tools have a default setting of 200 to report a finding for NPath complexity. Depending on the purpose of the method this may still be too generous and you may want to keep an eye on the possible number of outputs for a given method as you construct it.

Why does it matter how many outcomes a method can produce? If we’re to properly test the method we should be able to account for all the possible results. Imagine you are writing a choose your own adventure book. If you have to write a different story line to continue after every decision point you are exponentially increasing the complexity of the overall book and the amount of material you have to keep track of.

Here is an example of this measurement from PHPMD:

NPath Complexity

source:https://phpmd.org/rules/codesize.html#npathcomplexity

In the above example, the NPath complexity would be 4 as there are only 4 possible outcomes. You can imagine being able to efficiently write a test for this method that can account for all of these. Depending on the type of output it may be reasonable to test more than 200 outcomes while in other situations it may be difficult to test far fewer. As with all strategies for managing complexity, it is best to use your judgment as your code organically grows.

Cyclomatic complexity

Cyclomatic complexity is the measure of decision points in a given method. This measurement takes into account first the declaration of the method itself and then accounts for each if, while, for, or case statement inside of the method. The default threshold for cyclomatic complexity is typically 10. This means that outside of the declaration of the method itself, you should not have more than 9 other decision points.

Methods that exceed this amount of decision points can be very difficult to reason about which can make the code difficult to read and maintain. To visualize this type of complexity it may help to picture a branching logic tree diagram. The more decision points there are the more branches there are in the tree and many times these logic branches merge or circle back on themselves.

Here is another example from PHPMD:

Cyclomatic Complexity

Source: https://phpmd.org/rules/codesize.html#cyclomaticcomplexity

In the above example, the cyclomatic complexity is 11 which is considered very high complexity. For low complexity, you want to keep this number below 5 and anything above that is approaching moderate to high complexity. If you are using a static scanning tool that allows warnings at a lower threshold it may be advisable to set them appropriately. It’s easier at the outset to control this type of complexity and very likely that ongoing changes to the code to accommodate additional cases will unintentionally reach a level of high cyclomatic complexity.

Both NPath and Cyclomatic complexity offer valuable insights into how code complexity can impact maintainability and testing. By keeping an eye on the number of possible outcomes (NPath) and decision points (Cyclomatic complexity), you can write code that is easier to read, test, and maintain in the long run. Remember, it's best to use your judgment based on the specific context for each method. However, aiming for lower complexity from the beginning will help you avoid headaches down the road as your codebase grows.


Home