Choosing a SonarQube Leak Period Strategy: Date‑Based vs. SCM‑Based for New‑Code Quality Gates
A decision guide for choosing between SonarQube's date-based and SCM-based leak periods. Covers constraints, a comparison table, trade-offs, and a concrete CI validation procedure using a controlled code change to verify new-code detection accuracy.
23 Nov 2025, 02:49 UTC

The Problem: New‑Code Detection Drives Quality Gates
SonarQube uses a leak period to decide which lines count as "new code" when evaluating quality gates. If the leak period misclassifies code, a gate can pass despite fresh bugs or fail on legacy debt you never intended to block. The choice between date‑based and SCM‑based leak periods is a configuration decision that directly affects whether your CI/CD pipeline catches regressions reliably.
Takeaway: For any team using Git (or another supported SCM) with SonarQube 8.9 LTS or newer, the SCM‑based leak period is the default recommendation. It ties new‑code detection to actual commits since the last analysis on each branch. Date‑based remains a fallback when SCM integration cannot be enabled.
Decision Constraints
- SonarQube version: SCM‑based requires ≥ 8.9 LTS and the SonarSCM plugin (bundled in recent LTS releases). Older versions silently fall back to date‑based.
- SCM access: The analyzer must reach the repository with full history (not a shallow clone) and have credentials for the SCM provider.
- Branch strategy: Monorepos or long‑lived feature branches benefit from per‑branch SCM blame; a single‑branch trunk workflow can tolerate date‑based if analyses run on every commit.
- Analysis frequency: Infrequent scans (nightly, weekly) make date‑based windows either too wide (hiding new issues) or too narrow (flagging unchanged code).
Option Comparison
| Aspect | Date‑Based (sonar.leakPeriodDays) | SCM‑Based (sonar.scm.provider=git) |
|---|---|---|
| Configuration | Single property, e.g. sonar.leakPeriodDays=30 |
Enable SCM plugin, set sonar.scm.provider=git (or svn, hg) |
| New‑code definition | Lines changed within the last N days globally | Lines blamed to commits after the previous analysis on the same branch |
| Branch awareness | None — same window for all branches | Per‑branch; each branch compares against its own prior analysis |
| False positives/negatives | High when analyses are sparse or branches diverge | Low — tied to actual diff since last scan |
| Performance overhead | Negligible | Modest SCM blame lookup (~seconds for <100k LOC) |
| Fallback behavior | N/A | Reverts to date‑based with a warning if SCM data unavailable |
Trade‑offs in Practice
When Date‑Based Is Acceptable
- Legacy SonarQube instances (< 8.9) where upgrade is blocked.
- Repositories without SCM integration (air‑gapped builds, imported archives).
- Trunk‑only workflows with analysis on every push; a 1‑day window (
sonar.leakPeriodDays=1) approximates SCM behavior.
Risk: a 30‑day window on a weekly scan labels five days of unchanged code as "new," diluting the gate. A 1‑day window on a nightly scan misses commits pushed after the scan runs.
Why SCM‑Based Wins for Most Teams
- Accurate blame: SonarQube asks Git "which commit last touched this line?" and compares that commit date to the previous analysis timestamp on the branch.
- Branch isolation: A hotfix branch and a feature branch each measure new code against their own baseline, preventing cross‑branch noise.
- Quality‑gate trust: Developers see failures only on lines they actually changed, reducing alert fatigue.
Overhead is a single git blame --incremental pass during analysis. For a 50k‑line Java project this adds ~3–5 seconds on a modern CI runner.
Concrete Validation: Switching a Pipeline to SCM‑Based
The following steps assume a GitHub Actions pipeline analyzing a Java/Gradle project with SonarQube 9.9 LTS. Adapt the scanner invocation for Maven, .NET, or other ecosystems.
1. Verify Prerequisites
# Run on the CI agent (Linux/macOS/Windows runner)
# Requires: git ≥ 2.30, SonarScanner CLI ≥ 5.0, Java 11+
git --version
sonar-scanner --version
java -version
Ensure the runner checks out with full history:
- uses: actions/checkout@v4
with:
fetch-depth: 0 # critical: shallow clones break SCM blame
2. Current Date‑Based Configuration (Baseline)
Existing sonar-project.properties or scanner CLI args:
sonar.projectKey=myorg-myapp
sonar.leakPeriodDays=30
# sonar.scm.provider is absent or commented out
Run a baseline analysis and note the Quality Gate status and the "New Code" leak period source shown in the UI (Measures → New Code → Leak Period).
3. Enable SCM‑Based Leak Period
Update the properties file or scanner command:
sonar.projectKey=myorg-myapp
sonar.scm.provider=git
# sonar.leakPeriodDays removed or commented
If using the Gradle plugin:
sonarqube {
properties {
property "sonar.scm.provider", "git"
// property "sonar.leakPeriodDays", "30" // remove
}
}
4. Introduce a Controlled Change
Create a feature branch, add a single harmless line (e.g., a comment), push, and trigger the pipeline:
git checkout -b test-leak-period
printf "// leak-period test\n" >> src/main/java/com/example/App.java
git commit -am "test: add marker line for leak period validation"
git push origin test-leak-period
5. Compare Results in SonarQube UI
- Open the project → Measures → New Code.
- Confirm Leak Period shows "SCM" (not a date range).
- Check the New Lines count: it should reflect only the added comment line (1 line).
- Run the same commit with the old date‑based config (temporarily revert properties) and observe whether the new‑code count includes unrelated changes from the last 30 days.
Expected outcome: SCM‑based analysis reports exactly the lines you changed. Date‑based may report dozens of lines if other commits landed in the window.
6. Guard Against Silent Fallback
Add a pipeline step that fails if the scanner logs contain the fallback warning:
- name: Fail on SCM fallback
run: |
if grep -q "Falling back to date-based leak period" sonarqube.log; then
echo "::error::SCM leak period unavailable — check fetch-depth and credentials"
exit 1
fi
This prevents a misconfigured runner from quietly degrading gate accuracy.
Limitations and Verification Checklist
- Shallow clones:
fetch-depth: 0is mandatory. Some CI systems default to depth=1. - SCM credentials: Private repos need a token with read access; otherwise the analyzer cannot run
git blame. - Monorepo subdirectories: Set
sonar.scm.projectBaseDirif the scanned module lives in a subfolder. - First analysis on a branch: With no prior analysis, SCM‑based treats all lines as new. Subsequent runs normalize.
- Verification: After any config change, run the controlled-change test (steps 4–5) to confirm the leak period source and new‑code count match expectations.
Rollback Consideration
Switching leak period modes does not mutate stored data; it only affects the next analysis. If SCM‑based causes unexpected gate failures, revert the property change and re‑run — no database rollback needed.
Final Recommendation
Adopt SCM‑based leak period as the default for all Git‑backed projects on SonarQube ≥ 8.9 LTS. Reserve date‑based for environments where SCM integration is technically impossible. Validate the switch with a one‑line commit test before promoting the configuration to production pipelines.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.