Explanation for everything related to caching

Setup details from /api/system/info - not really relevant in this case I guess
"System": {
    "Version": "10.6.0.92116",
    "Edition": "Enterprise",
    "Container": true,
    "High Availability": false,
    "Official Distribution": true,
    "Force authentication": true,
    "Home Dir": "/opt/sonarqube",
    "Data Dir": "/opt/sonarqube/data",
    "Temp Dir": "/opt/sonarqube/temp",
    "Processors": 4
},
"Bundled": {
    "cayc": "2.3.0.1782 [Clean as You Code]",
    "iac": "1.31.0.10579 [IaC Code Quality and Security]",
    "plsql": "3.13.0.6725 [PL/SQL Code Quality and Security]",
    "sonarscala": "1.15.0.4655 [Scala Code Quality and Security]",
    "csharp": "9.27.0.93347 [C# Code Quality and Security]",
    "jcl": "1.2.0.1148 [JCL Code Quality]",
    "security": "10.6.0.31509 [Vulnerability Analysis]",
    "java": "8.0.1.36337 [Java Code Quality and Security]",
    "web": "3.16.0.5274 [HTML Code Quality and Security]",
    "flex": "2.12.0.4568 [Flex Code Quality and Security]",
    "xml": "2.10.0.4108 [XML Code Quality and Security]",
    "text": "2.12.1.2905 [Text Code Quality and Security]",
    "vbnet": "9.27.0.93347 [VB.NET Code Quality and Security]",
    "swift": "4.12.0.7262 [Swift Code Quality and Security]",
    "cpp": "6.56.0.72172 [CFamily Code Quality and Security]",
    "python": "4.19.0.15616 [Python Code Quality and Security]",
    "dbdpythonfrontend": "1.28.0.9315 [Dataflow Bug Detection Rules for Python]",
    "dbd": "1.28.0.9315 [Dataflow Bug Detection]",
    "go": "1.15.0.4655 [Go Code Quality and Security]",
    "jacoco": "1.3.0.1538 [JaCoCo]",
    "kotlin": "2.20.0.4382 [Kotlin Code Quality and Security]",
    "rpg": "3.9.0.5001 [RPG Code Quality]",
    "dbdjavafrontend": "1.28.0.9315 [Dataflow Bug Detection Rules for Java]",
    "pli": "1.15.0.4810 [PL/I Code Quality and Security]",
    "tsql": "1.13.0.7207 [T-SQL Code Quality and Security]",
    "vb": "2.13.0.5130 [VB6 Code Quality and Security]",
    "sonarapex": "1.15.0.4655 [Apex Code Quality and Security]",
    "javascript": "10.14.0.26080 [JavaScript/TypeScript/CSS Code Quality and Security]",
    "ruby": "1.15.0.4655 [Ruby Code Quality and Security]",
    "securitycsharpfrontend": "10.6.0.31509 [Vulnerability Rules for C#]",
    "securityjavafrontend": "10.6.0.31509 [Vulnerability Rules for Java]",
    "textenterprise": "2.12.1.2905 [Text Code Quality and Security]",
    "cfamilydependencies": "6.56.0.72172 [CFamily dependencies provider]",
    "securityjsfrontend": "10.6.0.31509 [Vulnerability Rules for JS]",
    "cobol": "5.7.0.8061 [COBOL Code Quality]",
    "securitypythonfrontend": "10.6.0.31509 [Vulnerability Rules for Python]",
    "php": "3.36.0.11813 [PHP Code Quality and Security]",
    "abap": "3.14.0.5470 [ABAP Code Quality and Security]",
    "securityphpfrontend": "10.6.0.31509 [Vulnerability Rules for PHP]",
    "javasymbolicexecution": "8.0.1.36337 [Java Advanced Code Quality Analyzer]"
}

Hello,
I am currently trying to understand how caching works and which options exist. It seems that there is no up-to-date and conclusive documentation available. Neither in the docs, nor in this forum. Additionally, our assigned Customer Success Manager confirmed that there is no comprehensive documentation available for “shared cache configuration” and recommended a post here. As I am utilizing GitLab, I will only focus on this specific CI environment, but I would appreciate if the answers are applicable to all / most CI environments.

What I want:
A comprehensive answer / guide for the available caches, how they differ from one another, what should be used / not used, what is officially deprecated or experimental and best practices on how to configure cache related options. The goal should be to help me and other community members with this post or even better, to add the information in a consolidated and easy to understand way to the official documentation.

What I know / gathered:
As I am using SonarQube, I am only linking documentation and threads related to SQ, but in general I presume these points also relate to SonarCloud.

There seems to be two types caches available:

General question to shared runner caches:
Our current setup consists of multiple GitLab Runner nodes. Currently it does not utilize the GitLab “distributed cache via s3”, we use a k8s pvc in combination with ceph. Would that work as well? Is the cache from GitLab recommended? What kind of speed improvement are we talking about here?

Thanks,
Patrick

I’m not an expert in incremental scanning. This feature is recent and is probably intended to optimize scan times.

As far as the plugin cache, it simply prevents the scanner from downloading the rule-implementing binaries from the server for each scan! It seems to me that the list of downloaded plugins is now limited to the language of the project to be scanned.

If you activate the verbose logs, you’ll see the list of requests and the time used by these downloads.

I strongly recommend you to test it in your CI and remember to clean the cache when upgrading plugins or sonar servers. This will take some of the load off the server, network and disk.

The same applies to the SonarLint cache, which I believe is activated by default.

2 Likes

Hi @Bachri_Abdel,
thanks for the reply.

Yes, I can see that incremental caching seems to be a rather new addition. Though that in my opinion makes it only more difficult to understand everything about caching and some updates to the documentation are due.

Could you share some light on this “Plugin Cache”? Is it somewhere documented what it downloads and where it stores it? Sadly this still isn’t 100% clear to me on how it behaves and how it compares to any (as mentioned in my post) local analysis cache (in terms of location, setup, etc… of course I understand that it stores different data).

Looking at the verbose/debug log, I assume you are talking about this?
I can see that it stores data in .sonar/_tmp and isn’t touching .sonar/cache, I am still not 100% certain how this relates to caching.

debug log snippet
2024-09-13T09:31:34.940+0200 [INFO] [org.sonarqube.gradle.SonarTask] Loading required plugins
2024-09-13T09:31:34.941+0200 [INFO] [org.sonarqube.gradle.SonarTask] Load plugins index
2024-09-13T09:31:34.941+0200 [DEBUG] [org.sonarqube.gradle.SonarTask] --> GET https://sonar.somesite.com/api/plugins/installed
2024-09-13T09:31:34.951+0200 [DEBUG] [org.sonarqube.gradle.SonarTask] <-- 200 https://sonar.somesite.com/api/plugins/installed (10ms, unknown-length body)
2024-09-13T09:31:34.976+0200 [DEBUG] [okhttp3.internal.concurrent.TaskRunner] Q10000 scheduled after   0 µs: OkHttp ConnectionPool
2024-09-13T09:31:34.976+0200 [INFO] [org.sonarqube.gradle.SonarTask] Load plugins index (done) | time=36ms
2024-09-13T09:31:34.976+0200 [INFO] [org.sonarqube.gradle.SonarTask] Load/download plugins
2024-09-13T09:31:34.977+0200 [DEBUG] [org.sonarqube.gradle.SonarTask] Download plugin 'cayc' to '/builds/project/repo/.sonar/_tmp/fileCache18085346404613052130.tmp'
2024-09-13T09:31:34.979+0200 [DEBUG] [org.sonarqube.gradle.SonarTask] --> GET https://sonar.somesite.com/api/plugins/download?plugin=cayc
2024-09-13T09:31:34.985+0200 [DEBUG] [org.sonarqube.gradle.SonarTask] <-- 200 https://sonar.somesite.com/api/plugins/download?plugin=cayc (6ms, unknown-length body)
2024-09-13T09:31:34.997+0200 [DEBUG] [okhttp3.internal.concurrent.TaskRunner] Q10000 scheduled after   0 µs: OkHttp ConnectionPool
2024-09-13T09:31:35.004+0200 [DEBUG] [org.sonarqube.gradle.SonarTask] Download plugin 'iac' to '/builds/project/repo/.sonar/_tmp/fileCache10202762265121085898.tmp'
2024-09-13T09:31:35.004+0200 [DEBUG] [org.sonarqube.gradle.SonarTask] --> GET https://sonar.somesite.com/api/plugins/download?plugin=iac
2024-09-13T09:31:35.030+0200 [DEBUG] [org.sonarqube.gradle.SonarTask] <-- 200 https://sonar.somesite.com/api/plugins/download?plugin=iac (25ms, unknown-length body)
2024-09-13T09:31:35.400+0200 [DEBUG] [okhttp3.internal.concurrent.TaskRunner] Q10000 scheduled after   0 µs: OkHttp ConnectionPool
2024-09-13T09:31:35.429+0200 [DEBUG] [org.sonarqube.gradle.SonarTask] Download plugin 'jacoco' to '/builds/project/repo/.sonar/_tmp/fileCache15026281678329345347.tmp'
2024-09-13T09:31:35.429+0200 [DEBUG] [org.sonarqube.gradle.SonarTask] --> GET https://sonar.somesite.com/api/plugins/download?plugin=jacoco
2024-09-13T09:31:35.434+0200 [DEBUG] [org.sonarqube.gradle.SonarTask] <-- 200 https://sonar.somesite.com/api/plugins/download?plugin=jacoco (4ms, unknown-length body)
2024-09-13T09:31:35.434+0200 [DEBUG] [okhttp3.internal.concurrent.TaskRunner] Q10000 scheduled after   0 µs: OkHttp ConnectionPool
2024-09-13T09:31:35.435+0200 [DEBUG] [org.sonarqube.gradle.SonarTask] Download plugin 'python' to '/builds/project/repo/.sonar/_tmp/fileCache12672099416329084750.tmp'
2024-09-13T09:31:35.435+0200 [DEBUG] [org.sonarqube.gradle.SonarTask] --> GET https://sonar.somesite.com/api/plugins/download?plugin=python
2024-09-13T09:31:35.439+0200 [DEBUG] [org.sonarqube.gradle.SonarTask] <-- 200 https://sonar.somesite.com/api/plugins/download?plugin=python (3ms, unknown-length body)
2024-09-13T09:31:35.683+0200 [DEBUG] [okhttp3.internal.concurrent.TaskRunner] Q10000 scheduled after   0 µs: OkHttp ConnectionPool
2024-09-13T09:31:35.708+0200 [DEBUG] [org.sonarqube.gradle.SonarTask] Download plugin 'text' to '/builds/project/repo/.sonar/_tmp/fileCache16533199212220783691.tmp'
2024-09-13T09:31:35.708+0200 [DEBUG] [org.sonarqube.gradle.SonarTask] --> GET https://sonar.somesite.com/api/plugins/download?plugin=text
2024-09-13T09:31:35.713+0200 [DEBUG] [org.sonarqube.gradle.SonarTask] <-- 200 https://sonar.somesite.com/api/plugins/download?plugin=text (4ms, unknown-length body)
2024-09-13T09:31:35.833+0200 [DEBUG] [okhttp3.internal.concurrent.TaskRunner] Q10000 scheduled after   0 µs: OkHttp ConnectionPool
2024-09-13T09:31:35.845+0200 [DEBUG] [org.sonarqube.gradle.SonarTask] Download plugin 'textenterprise' to '/builds/project/repo/.sonar/_tmp/fileCache11489382043522876673.tmp'
2024-09-13T09:31:35.845+0200 [DEBUG] [org.sonarqube.gradle.SonarTask] --> GET https://sonar.somesite.com/api/plugins/download?plugin=textenterprise
2024-09-13T09:31:35.850+0200 [DEBUG] [org.sonarqube.gradle.SonarTask] <-- 200 https://sonar.somesite.com/api/plugins/download?plugin=textenterprise (5ms, unknown-length body)
2024-09-13T09:31:35.980+0200 [DEBUG] [okhttp3.internal.concurrent.TaskRunner] Q10000 scheduled after   0 µs: OkHttp ConnectionPool
2024-09-13T09:31:35.998+0200 [DEBUG] [org.sonarqube.gradle.SonarTask] Download plugin 'xml' to '/builds/project/repo/.sonar/_tmp/fileCache12512019228720803834.tmp'
2024-09-13T09:31:35.998+0200 [DEBUG] [org.sonarqube.gradle.SonarTask] --> GET https://sonar.somesite.com/api/plugins/download?plugin=xml
2024-09-13T09:31:36.005+0200 [DEBUG] [org.sonarqube.gradle.SonarTask] <-- 200 https://sonar.somesite.com/api/plugins/download?plugin=xml (6ms, unknown-length body)
2024-09-13T09:31:36.068+0200 [DEBUG] [okhttp3.internal.concurrent.TaskRunner] Q10000 scheduled after   0 µs: OkHttp ConnectionPool
2024-09-13T09:31:36.073+0200 [INFO] [org.sonarqube.gradle.SonarTask] Load/download plugins (done) | time=1096ms
2024-09-13T09:31:36.073+0200 [DEBUG] [org.sonarqube.gradle.SonarTask] Plugins not loaded because they are optional: [abap, sonarapex, csharp, cpp, cfamilydependencies, cobol, dbd, dbdjavafrontend, dbdpythonfrontend, flex, go, web, jcl, javasymbolicexecution, java, javascript, kotlin, php, pli, plsql, rpg, ruby, sonarscala, swift, tsql, vbnet, vb, security, securitycsharpfrontend, securityjsfrontend, securityjavafrontend, securityphpfrontend, securitypythonfrontend]
2024-09-13T09:31:36.097+0200 [DEBUG] [org.sonarqube.gradle.SonarTask] Plugins loaded:
2024-09-13T09:31:36.097+0200 [DEBUG] [org.sonarqube.gradle.SonarTask]   * Text Code Quality and Security 2.12.1.2905 (textenterprise)
2024-09-13T09:31:36.097+0200 [DEBUG] [org.sonarqube.gradle.SonarTask]   * Python Code Quality and Security 4.19.0.15616 (python)
2024-09-13T09:31:36.097+0200 [DEBUG] [org.sonarqube.gradle.SonarTask]   * Clean as You Code 2.3.0.1782 (cayc)
2024-09-13T09:31:36.097+0200 [DEBUG] [org.sonarqube.gradle.SonarTask]   * XML Code Quality and Security 2.10.0.4108 (xml)
2024-09-13T09:31:36.097+0200 [DEBUG] [org.sonarqube.gradle.SonarTask]   * JaCoCo 1.3.0.1538 (jacoco)
2024-09-13T09:31:36.097+0200 [DEBUG] [org.sonarqube.gradle.SonarTask]   * IaC Code Quality and Security 1.31.0.10579 (iac)
2024-09-13T09:31:36.097+0200 [DEBUG] [org.sonarqube.gradle.SonarTask]   * Text Code Quality and Security 2.12.1.2905 (text)
[...]
2024-09-13T09:31:50.655+0200 [INFO] [org.sonarqube.gradle.SonarTask] Loading plugins for detected languages
2024-09-13T09:31:50.655+0200 [DEBUG] [org.sonarqube.gradle.SonarTask] Detected languages: [java]
2024-09-13T09:31:50.655+0200 [INFO] [org.sonarqube.gradle.SonarTask] Load/download plugins
2024-09-13T09:31:50.655+0200 [DEBUG] [org.sonarqube.gradle.SonarTask] Download plugin 'dbd' to '/builds/project/repo/.sonar/_tmp/fileCache6523159669426988533.tmp'
2024-09-13T09:31:50.656+0200 [DEBUG] [org.sonarqube.gradle.SonarTask] --> GET https://sonar.somesite.com/api/plugins/download?plugin=dbd
2024-09-13T09:31:50.661+0200 [DEBUG] [org.sonarqube.gradle.SonarTask] <-- 200 https://sonar.somesite.com/api/plugins/download?plugin=dbd (5ms, unknown-length body)
2024-09-13T09:31:50.724+0200 [DEBUG] [okhttp3.internal.concurrent.TaskRunner] Q10000 scheduled after   0 µs: OkHttp ConnectionPool
2024-09-13T09:31:50.734+0200 [DEBUG] [org.sonarqube.gradle.SonarTask] Download plugin 'dbdjavafrontend' to '/builds/project/repo/.sonar/_tmp/fileCache9632236013435957344.tmp'
2024-09-13T09:31:50.734+0200 [DEBUG] [org.sonarqube.gradle.SonarTask] --> GET https://sonar.somesite.com/api/plugins/download?plugin=dbdjavafrontend
2024-09-13T09:31:50.739+0200 [DEBUG] [org.sonarqube.gradle.SonarTask] <-- 200 https://sonar.somesite.com/api/plugins/download?plugin=dbdjavafrontend (5ms, unknown-length body)
2024-09-13T09:31:50.764+0200 [DEBUG] [okhttp3.internal.concurrent.TaskRunner] Q10000 scheduled after   0 µs: OkHttp ConnectionPool
2024-09-13T09:31:50.769+0200 [DEBUG] [org.sonarqube.gradle.SonarTask] Download plugin 'javasymbolicexecution' to '/builds/project/repo/.sonar/_tmp/fileCache16262239370953974656.tmp'
2024-09-13T09:31:50.769+0200 [DEBUG] [org.sonarqube.gradle.SonarTask] --> GET https://sonar.somesite.com/api/plugins/download?plugin=javasymbolicexecution
2024-09-13T09:31:50.774+0200 [DEBUG] [org.sonarqube.gradle.SonarTask] <-- 200 https://sonar.somesite.com/api/plugins/download?plugin=javasymbolicexecution (5ms, unknown-length body)
2024-09-13T09:31:50.953+0200 [DEBUG] [okhttp3.internal.concurrent.TaskRunner] Q10000 scheduled after   0 µs: OkHttp ConnectionPool
2024-09-13T09:31:50.972+0200 [DEBUG] [org.sonarqube.gradle.SonarTask] Download plugin 'java' to '/builds/project/repo/.sonar/_tmp/fileCache16487487931468384048.tmp'
2024-09-13T09:31:50.972+0200 [DEBUG] [org.sonarqube.gradle.SonarTask] --> GET https://sonar.somesite.com/api/plugins/download?plugin=java
2024-09-13T09:31:50.979+0200 [DEBUG] [org.sonarqube.gradle.SonarTask] <-- 200 https://sonar.somesite.com/api/plugins/download?plugin=java (6ms, unknown-length body)
2024-09-13T09:31:51.346+0200 [DEBUG] [okhttp3.internal.concurrent.TaskRunner] Q10000 scheduled after   0 µs: OkHttp ConnectionPool
2024-09-13T09:31:51.378+0200 [DEBUG] [org.sonarqube.gradle.SonarTask] Download plugin 'security' to '/builds/project/repo/.sonar/_tmp/fileCache2868986549702474490.tmp'
2024-09-13T09:31:51.379+0200 [DEBUG] [org.sonarqube.gradle.SonarTask] --> GET https://sonar.somesite.com/api/plugins/download?plugin=security
2024-09-13T09:31:51.385+0200 [DEBUG] [org.sonarqube.gradle.SonarTask] <-- 200 https://sonar.somesite.com/api/plugins/download?plugin=security (5ms, unknown-length body)
2024-09-13T09:31:51.602+0200 [DEBUG] [okhttp3.internal.concurrent.TaskRunner] Q10000 scheduled after   0 µs: OkHttp ConnectionPool
2024-09-13T09:31:51.629+0200 [DEBUG] [org.sonarqube.gradle.SonarTask] Download plugin 'securityjavafrontend' to '/builds/project/repo/.sonar/_tmp/fileCache730296424197319892.tmp'
2024-09-13T09:31:51.630+0200 [DEBUG] [org.sonarqube.gradle.SonarTask] --> GET https://sonar.somesite.com/api/plugins/download?plugin=securityjavafrontend
2024-09-13T09:31:51.635+0200 [DEBUG] [org.sonarqube.gradle.SonarTask] <-- 200 https://sonar.somesite.com/api/plugins/download?plugin=securityjavafrontend (5ms, unknown-length body)
2024-09-13T09:31:51.795+0200 [DEBUG] [okhttp3.internal.concurrent.TaskRunner] Q10000 scheduled after   0 µs: OkHttp ConnectionPool
2024-09-13T09:31:51.810+0200 [INFO] [org.sonarqube.gradle.SonarTask] Load/download plugins (done) | time=1156ms
2024-09-13T09:31:51.811+0200 [DEBUG] [org.sonarqube.gradle.SonarTask] Optional language-specific plugins not loaded: [abap, sonarapex, csharp, cpp, cfamilydependencies, cobol, dbdpythonfrontend, flex, go, web, jcl, javascript, kotlin, php, pli, plsql, rpg, ruby, sonarscala, swift, tsql, vbnet, vb, securitycsharpfrontend, securityjsfrontend, securityphpfrontend, securitypythonfrontend]
2024-09-13T09:31:51.874+0200 [DEBUG] [org.sonarqube.gradle.SonarTask] Plugins loaded:
2024-09-13T09:31:51.874+0200 [DEBUG] [org.sonarqube.gradle.SonarTask]   * Vulnerability Rules for Java 10.6.0.31509 (securityjavafrontend)
2024-09-13T09:31:51.874+0200 [DEBUG] [org.sonarqube.gradle.SonarTask]   * Vulnerability Analysis 10.6.0.31509 (security)
2024-09-13T09:31:51.874+0200 [DEBUG] [org.sonarqube.gradle.SonarTask]   * Java Code Quality and Security 8.0.1.36337 (java)
2024-09-13T09:31:51.874+0200 [DEBUG] [org.sonarqube.gradle.SonarTask]   * Dataflow Bug Detection Rules for Java 1.28.0.9315 (dbdjavafrontend)
2024-09-13T09:31:51.874+0200 [DEBUG] [org.sonarqube.gradle.SonarTask]   * Java Advanced Code Quality Analyzer 8.0.1.36337 (javasymbolicexecution)
2024-09-13T09:31:51.874+0200 [DEBUG] [org.sonarqube.gradle.SonarTask]   * Dataflow Bug Detection 1.28.0.9315 (dbd)

Looking at the log, there is one line:
2024-09-13T09:31:33.385+0200 [DEBUG] [org.sonarqube.gradle.SonarTask] Download https://sonar.somesite.com/batch/file?name=scanner-enterprise-10.6.0.92116-all.jar to /builds/project/repo/.sonar/cache/_tmp/fileCache12079997518889350775.tmp
This seems to store some data in the cache dir, albeit also in _tmp and does not give any direct indication of how long it takes.

Regarding testing in CI, what should I test and which cache should I clean when I update SonarQube?

Another cache appears… SonarLint, interesting. Can you share some documentation? The current SonarLint setup we have is terribly slow and everyone just disables it. Maybe there are some improvements to be done with caching.

Thanks for the feedback, but I am still a bit lost and now have new questions… :smiley:

Regards,
Patrick

Hi @pmaieref,

You found logs i was talking about. The times it takes
2024-09-13T09:31:51.810+0200 [INFO] [org.sonarqube.gradle.SonarTask] Load/download plugins (done) | time=1156ms
Plugins are download in the cache dir but i think never read from this cache dir.
If you user docker you can find some documentation in this page SonarScanner CLI
You need to find a way to persist and share this directory between all youre scan.

For SonarLint, same files are cached in user data directory something like AppData\Local\JetBrains\IdeaIC2022.3\sonarlint\storage.
When you uprade sonar server you can have some issues until you clean this directory.

1 Like

@Bachri_Abdel Thanks for your feedback. It feels like it isn’t worth it to cache this. It would save 1 second, maybe a bit more depending on load, but setting it up on a shared runner platform seems to be a bit more involved. If it turns out in the future this will take more time, I’ll look into that. Thanks!

I tried to find some more information on this SonarLint cache, but I am unable to properly figure out what it caches. Is there any documentation?

Currently I utilize the Gradle Scanner and the NPM Scanner.

In general I’d really appreciate if someone from SonarSource would find the time to shed some light on the topics or at least bring it up internally to improve the documentation. I think (and hope?) I am not the only one here who is a bit lost figuring out all the different cache options.

Thanks,
Patrick