Skip to main content
Code Smells

SonarQube vs. Semgrep vs. Human Review for Code Smells

I pit SonarQube, Semgrep, and human review against each other to help you decide how to catch code smells without wasting your team's time.

Which tool actually catches code smells without drowning your team in noise?

I've spent the last few years watching teams toggle between SonarQube, Semgrep, and plain old human eyeballs. The debate usually goes like this: one camp swears by SonarQube's technical debt ratio, another waves the Semgrep flag for security, and a third insists that only humans can smell a code smell. I think that's a false choice, but if you force me to pick a starting point, I'll pick SonarQube every time for maintainability smells — provided you set it up correctly. Here's why, and where the other two win.

What's a code smell, and why should you care?

A code smell is a surface indication that usually corresponds to a deeper problem in the system. Think duplicated logic, a function with cyclomatic complexity so high you need a map to follow it, or a 500-line class that does everything. SonarQube tracks these under maintainability, using metrics like cyclomatic complexity (1 + number of conditional branches), cognitive complexity (how hard the control flow is to understand), duplication, and technical debt ratio. Technical debt itself is the sum of remediation costs in minutes, and the ratio is debt divided by the cost to develop all those lines — where the default cost is 30 minutes per line. A maintainability rating of A means a debt ratio of 5% or less; E means 50% or more. Those numbers give you a concrete target.

But here's the catch: SonarQube will happily flag a 12-line function as complex if it has enough branches, and it has no idea whether that complexity is inherent to the problem or just lazy coding. I've seen teams spend sprint after sprint driving debt ratio down to 4.9% while the architecture rotted. That's why I never let SonarQube be the only reviewer.

SonarQube: the maintainability workhorse

SonarQube is the tool I recommend when your primary pain is maintainability smells — long methods, deep nesting, duplication, and creeping technical debt. It's also the only one of the three that gives you a single number (the technical debt ratio) you can put on a dashboard and track over time. The built-in Sonar way quality gate has four conditions: no new issues, all new Security Hotspots reviewed, new code test coverage ≥ 80%, and duplication in new code ≤ 3%. That gate can block a merge or fail CI, which makes it a real enforcement mechanism, not just a report.

Who is SonarQube for? Teams with a legacy codebase and a mandate to reduce maintainability risk. If you're a five-person startup with a two-year-old codebase, the setup overhead may not pay off yet. But if you've got a 10-year-old monolith and a CTO asking why velocity is dropping, SonarQube gives you the vocabulary to answer.

One quick tip: don't turn on every rule at once. Start with the Sonar way gate, measure for a month, then add rules that match your actual pain. Otherwise you'll generate thousands of issues, the team will ignore them, and you'll have wasted the license.

Semgrep: the security smell specialist

Semgrep is a static analysis tool that finds insecure coding patterns and security vulnerabilities. It's not a maintainability tool in the same way SonarQube is — it won't tell you your function is too long — but it will catch the smells that actually hurt: SQL injection, unsafe deserialization, hardcoded credentials. The OWASP Top 10 2025 lists Broken Access Control as the #1 risk, with 3.73% of applications tested having at least one of its 40 CWEs. Semgrep can be tuned to catch many of those patterns across any codebase, repository, or folder in a monorepo.

I recommend Semgrep when security is the dominant concern — say, you're handling payments or PII. It's lighter than SonarQube, faster to configure for specific rules, and its pattern-matching syntax is friendly enough that a senior dev can write a custom rule in an afternoon. But Semgrep won't tell you that your module has 40% duplication, and it won't give you a debt ratio. It's a specialist, not a generalist.

Warning: Semgrep's default rulesets can be noisy on legacy code. If you run it against a 15-year-old Java codebase, expect a flood. Scope your first scan to new commits only.

Human review: the only one that catches design smells

No tool I've used catches the smell that matters most: a design that's wrong for the problem. Google's own guidance says the most important thing to cover in a review is the overall design of the change, before checking functionality, complexity, tests, naming, and comments (Google Engineering Practices). A linter will never tell you that you're building a generic framework for a problem you don't have yet — but a good reviewer will. Google explicitly warns against over-engineering, and that's a judgment call no static analyzer makes.

Human review also catches concurrency smells — deadlocks, race conditions — which are very hard to detect by just running the code. And it's the only mechanism that transfers knowledge. Rigby and Bird's cross-organizational study found that peer review increases the number of distinct files a developer knows about by 66% to 150% (Convergent Contemporary Software Peer Review Practices). That's a smell-catching benefit no tool provides.

But human review has a scaling problem. At Google, the median change size is about 24 lines, and more than 10% of changes modify only one line (Modern Code Review: A Case Study at Google). If your team routinely pushes 800-line pull requests, your reviewers will miss smells because they're skimming. Keep changes under 400–500 lines of meaningful change, as Google recommends, and split by concern.

Head-to-head: which one wins?

CriteriaSonarQubeSemgrepHuman review
Primary smell typeMaintainability (complexity, duplication, debt)Security (injection, unsafe deserialization)Design, concurrency, over-engineering
Enforcement mechanismQuality gate can block merge/CICan fail CI if configuredApproval required by branch protection
Best forLegacy monoliths with debtSecurity-sensitive codebasesAny team that wants knowledge transfer
Key limitationNoisy on legacy; ignores designNo maintainability metricsDoesn't scale to large diffs

If I had to pick one as the foundation, I'd pick human review — because it's the only one that can catch a bad design before it ships. But that's a cop-out. The real answer is that you need all three, layered. Use SonarQube to keep maintainability debt from compounding. Use Semgrep to catch the security smells that OWASP keeps warning about. And use human review for the judgment calls that no tool can make.

If you can only afford one tool, though, start with SonarQube. It gives you the broadest coverage of code smells (bugs, vulnerabilities, code smells, coverage, duplication) and the most actionable metric — the technical debt ratio. Add Semgrep later when security becomes a board-level concern. Human review is non-negotiable; if you don't have it, no tool will save you.

The bottom line

Code smells are a category, not a single thing. Maintainability smells need SonarQube's metrics. Security smells need Semgrep's pattern matching. Design smells need a human who cares. Don't let any one tool become a religion. The teams I've seen succeed treat static analysis as a filter and human review as the final gate — and they keep their pull requests small enough that the humans can actually pay attention.

The single most important thing to remember: a tool can tell you a function is complex, but only a reviewer can tell you it shouldn't exist.

Sources

  • Google Engineering Practices (code review) - https://google.github.io/eng-practices/review/
  • SonarQube Server Docs - Understanding measures and metrics - https://docs.sonarsource.com/sonarqube-server/user-guide/code-metrics/metrics-definition
  • 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
  • Convergent Contemporary Software Peer Review Practices (Rigby & Bird, ESEC/FSE 2013) - https://dl.acm.org/doi/10.1145/2491411.2491444
  • OWASP Top Ten 2025 - https://owasp.org/Top10/2025/0x00_2025-Introduction/
  • Semgrep Docs - Getting started - https://semgrep.dev/docs/getting-started/

Share this article:

Comments (0)

No comments yet. Be the first to comment!