Performance
What is fast, what is slow, and the measurements behind the defaults.
Security tooling has a reputation for making editors slow. Here are the actual numbers and what was done about them.
Measured on an AMD Ryzen 7 PRO 7840U (16 threads) against the embedded rule set of 1,899 modules.
Startup
| Compile all rules, single-threaded | 1.72 s |
| Compile across 16 parallel shards | 0.30 s |
| Prepare queries for evaluation | 7.5 ms |
| Index a 50,000-file repository | 71 ms |
Compilation happens once when the server starts and the result is kept, so this is a startup cost, not a per-check cost. Indexing is fast enough to be uninteresting.
Evaluation, and the reason secrets are on save
Evaluation, not compilation, is the expensive part, and it is dominated by one rule family.
| Rules evaluated | Modules | One file |
|---|---|---|
| Everything | 1,232 | 231 ms |
| Secrets only | 1,092 | 213 ms |
| Code, infrastructure and containers | 140 | 10.4 ms |
The 1,092 secret rules declare no language, so no language filter can remove them, and each examines every file. They are 92% of the cost of checking a file that may contain no secret at all.
So the editor splits by rule family rather than throttling everything equally:
- As you type: code, infrastructure and container rules. 10 ms.
- On save: the above plus secrets. 231 ms.
- On demand: everything, in the background, cancellable.
That is the whole reason vulnetix.secrets.onType defaults to false. You can turn it on; now you know what it costs.
Whole-repository scans
Evaluation scales linearly with file count, so a full scan of a large repository including secrets is a minutes-long operation. It is always background, always cancellable, always shows progress, and is never triggered automatically. vulnetix.scan.onStartup defaults to false for that reason.
Things that will make it slow
Git history scanning. Off by default in the editor. It walks hundreds of commits and thousands of file versions, which is a CI job, not an editor one.
Very large repositories. The engine caps how much file content it holds. Beyond that it evaluates in batches and reports that it did, so a partial scan never presents as a clean one.
Underpowered cloud workspaces. A 2-core container takes noticeably longer for the initial compile. Progress distinguishes warming up from stuck.
Turning things down
{
"vulnetix.scan.onType": false, // only check on save
"vulnetix.scan.debounceMs": 1000, // wait longer after typing stops
"vulnetix.scan.exclude": ["**/generated/**", "**/vendor/**"],
"vulnetix.lsp.maxCpu": 4, // cap parallelism
"vulnetix.lsp.memoryLimitMb": 1024,
"vulnetix.lsp.idleShutdownMinutes": 30
}