Skip to main content
Code Smells

SonarQube vs. Semgrep vs. Human Review: Which Actually Kills Code Smells?

Static analysis and human review catch different smells. We compare SonarQube, Semgrep, and human review on three criteria and declare a winner for each context.

SonarQube rates technical debt under 5% as an A and over 50% as an E. That spread tells you everything about code smells: they are not binary, they are a spectrum of rot. And most teams attack that spectrum with the wrong tool. I have watched teams burn hours arguing about cyclomatic complexity in a pull request while Semgrep quietly flagged a SQL injection three lines below. So here is the straight answer: use SonarQube for maintainability debt, Semgrep for security smells, and reserve human review for design and logic. Anything else is wasted effort.

The three contenders

SonarQube is a platform that analyzes reliability, security, maintainability, coverage, and duplication. It assigns code smells to the maintainability bucket and computes a technical debt ratio. Semgrep is a static analysis tool that finds insecure coding patterns across any codebase, repository, or folder. Human review is what your team does in GitHub or GitLab. Each one sees a different layer of the smell problem.

Criterion 1: What they actually catch

SonarQube catches structural smells. It measures cyclomatic complexity as 1 plus the number of conditional branches, and cognitive complexity as how hard the control flow is to understand. A function with 30 branches will show up. A function with a hardcoded password might not.

Semgrep catches security smells. It scans for insecure coding patterns and vulnerabilities, and you can run it on any folder in a monorepo. It does not care if your function is 200 lines long. It cares if you concatenated user input into a query.

Human review catches everything else: over-engineering, missing edge cases, concurrency bugs like deadlocks and race conditions, and the overall design of the change. Google says the most important thing to cover in a review is the overall design, before functionality, complexity, tests, naming, and comments (Google Engineering Practices – What to look for in a code review). That is a human job. No linter will tell you the abstraction is wrong.

Criterion 2: Speed and friction

SonarQube runs on every analysis. Its built-in Sonar way quality gate has four conditions: no new issues, all new Security Hotspots reviewed, new code test coverage at least 80%, and duplication in new code at most 3%. That gate can block a merge or fail CI. Good. It is objective.

Semgrep runs in seconds. You can trigger it on a push. It does not care about coverage percentages. It reports findings and gets out of the way.

Human review is the slowest. Google sets one business day as the maximum response time for a review request, and median time to first feedback at Google was under 1 hour for small changes (Modern Code Review: A Case Study at Google, ICSE-SEIP '18). That speed only holds because Google keeps changes tiny. The median change size there is about 24 lines. If your pull requests average 400 lines, your human review will not be fast, and it will not be thorough.

Criterion 3: Cost of a false positive

SonarQube false positives on complexity are annoying but cheap. You mark it as accepted debt. The technical debt ratio absorbs it.

Semgrep false positives on security patterns are also cheap, but the cost of a false negative is catastrophic. A missed injection is an OWASP A05 failure. A missed broken access control is A01, still the number one risk in the 2025 list, present in an average of 3.73% of applications tested (OWASP Top Ten 2025).

Human false positives are expensive. A reviewer who blocks a pull request over a naming nit wastes the author's time and poisons the review culture. Google's rule is to critique the code, not the author. But the deeper fix is to let machines handle style so humans never have to argue about it.

Head-to-head comparison

ToolBest atWeak atWho it is for
SonarQubeCyclomatic and cognitive complexity, duplication, maintainability ratings, technical debt ratioBusiness logic, architecture, concurrencyTeams with a long-lived codebase that needs a maintainability score
SemgrepInsecure coding patterns, injection, unsafe deserialization, hardcoded secretsDesign, readability, test qualityAny team shipping code that touches user input or external systems
Human reviewDesign, edge cases, concurrency, over-engineering, knowledge transferConsistency, speed at scale, mechanical checksEvery team, but only for the things machines cannot judge

Who wins, and when

If your codebase is a decade-old monolith with a maintainability rating of D or worse, SonarQube wins. It gives you a number you can track. A team I know reduced its technical debt ratio from 22% to 8% in six months by refusing to merge anything that failed the Sonar way gate. That moved them from a D to a B. Not perfect, but better.

If your application accepts user input, Semgrep wins by default. Pair it with Bandit for Python or gosec for Go if you want language-specific depth. gosec even does taint analysis for SQL injection, command injection, path traversal, SSRF, XSS, and unsafe deserialization. That is a security review you cannot do reliably by eye.

If your problem is that reviewers argue about import order while missing a race condition, human review wins only after you fix the process. Automate the mechanical checks first. Then use the humans for design. Google's own data says finding bugs is not the primary focus of review. The four key expectations are education, maintaining norms, gatekeeping, and accident prevention (Modern Code Review: A Case Study at Google, ICSE-SEIP '18).

The one thing to remember

Code smells are not one problem. They are three: maintainability debt, security patterns, and design flaws. SonarQube measures the first. Semgrep catches the second. Humans handle the third. If you are using one tool for all three, you are either slow, insecure, or both.

Sources

  • Google Engineering Practices - What to look for in a code review - https://google.github.io/eng-practices/review/reviewer/looking-for.html
  • SonarQube Server Docs - Understanding measures and metrics - https://docs.sonarsource.com/sonarqube-server/user-guide/code-metrics/metrics-definition
  • Semgrep Docs - Getting started - https://semgrep.dev/docs/getting-started/
  • OWASP Top Ten 2025 - https://owasp.org/Top10/2025/0x00_2025-Introduction/
  • Modern Code Review: A Case Study at Google (ICSE-SEIP '18) - https://www.papercache.org/papers/mlsys/system/2026/03/25/modern-code-review-a-case-study-at-google
  • gosec - Go Security Checker - https://raw.githubusercontent.com/securego/gosec/master/README.md

Share this article:

Comments (0)

No comments yet. Be the first to comment!