DEV Community

ThankGod Chibugwum Obobo
ThankGod Chibugwum Obobo

Posted on • Originally published at actocodes.hashnode.dev

Cyclomatic vs. Cognitive Complexity: What's More Important for Code Quality?

In the quest for maintainable code, we often turn to metrics. For decades, Cyclomatic Complexity was the gold standard. However, as modern software has become more functional and asynchronous, a new metric has emerged Cognitive Complexity.

Understanding the difference between these two is the difference between satisfying a linter and actually helping your team.

Cyclomatic Complexity: The Mathematical Model

Developed by Thomas J. McCabe in 1976, Cyclomatic Complexity is a quantitative measure of the number of linearly independent paths through a program's source code.

  • How it’s calculated: It counts the number of decision points (if, while, case, etc.) plus one.
  • The Goal: To determine how many test cases are needed to cover every possible path.
  • The Flaw: It treats all decision points equally, regardless of how they are nested or structured.

Cognitive Complexity: The Human Model

Introduced by SonarSource, Cognitive Complexity aims to measure how difficult it is for a developer to understand the flow of a piece of code. It prioritizes the "mental load" over mathematical paths.

The Three Basic Rules:

  1. Ignore structures that allow multiple statements to be readable: (e.g., method chaining or "guard clauses").
  2. Increment for nesting: Deeply nested if statements are penalized more heavily than sequential ones.
  3. Increment for "breaks" in linear flow: Things like catch blocks, switch statements, and recursion.

The "Nesting Penalty" Example

Consider these two snippets:

Snippet A (Sequential - Low Cognitive Complexity):

function processUser(user) {
  if (!user.isLogged) return;
  if (!user.hasAccess) return;
  saveUser(user);
}
Enter fullscreen mode Exit fullscreen mode

Snippet B (Nested - High Cognitive Complexity):

function processUser (user) {
  if (user.isLogged) {
    if (user.hasAccess) {
      saveUser(user);
    }
  }
}
Enter fullscreen mode Exit fullscreen mode
  • Cyclomatic Complexity: Both have a score of 3.
  • Cognitive Complexity: Snippet A scores 2, while Snippet B scores 3 (or more depending on the linter) because the brain has to "keep track" of the nested state.

Comparison: Which One Should You Use?

Feature Cyclomatic Complexity Cognitive Complexity
Primary Focus Testability and path coverage. Readability and maintainability.
Philosophy Mathematical (The computer's view). Psychological (The developer's view).
Nesting No extra penalty for nesting. Heavy penalty for nesting.
Best For QA engineers ensuring 100% path coverage. Teams trying to reduce technical debt.

Which One Actually Matters for Maintainability?

For modern development, Cognitive Complexity is the winner.

Why? Because code is read far more often than it is written. High Cyclomatic Complexity tells you that a function is hard to test, but high Cognitive Complexity tells you that a function is hard to change without breaking it.

Regardless, I'd like to read your thoughts in the comments.

Best Practices for Your Team

  • Set a Cognitive Limit: In tools like SonarQube or ESLint, set a threshold (usually 15). Any function exceeding this must be refactored.
  • Flatten Your Code: Use guard clauses and early returns to keep the nesting level low.
  • Encapsulate Complexity: If a complex mathematical algorithm is required, move it into its own isolated, well-named function so the main business logic remains linear.

Conclusion

Cyclomatic Complexity is a good metric but in today’s world of complex, multi-threaded, and highly abstract applications, we must optimize for the human brain. By focusing on Cognitive Complexity, you ensure that your codebase remains accessible to every member of your team, regardless of their seniority.

Top comments (0)