Repository navigation
Description
Version
built from source, main @ 2278498 (v0.11.0-186)
Platform
Linux (x64)
Install channel
Built from source
Binary variant
standard
What happened, and what did you expect?
On the sequential route, which a repo takes with 50 files or fewer or with CBM_WORKERS=1 (src/pipeline/pipeline.c:2684), cbm_pipeline_pass_definitions caches each file's raw result (pass_definitions.c:870-871) with its tree-sitter tree and uncompacted working arena until the run ends. The parallel worker frees the tree (pass_parallel.c:1233) and compacts the result (pass_parallel.c:1290) before caching. So peak memory on the sequential route grows by about 1.7 MB per small Python file instead of about 0.2 MB, and a small repo of large files takes this route at any worker count.
The fix frees the tree and compacts the result before caching, as the parallel worker does, and releases the thread's working arena when the pass ends. The graph is byte-identical on 7 sequential-route corpora. The cost is that the cross-file LSP pass re-parses these files, as it already does on the parallel route (268-275 ms to 528 ms on the 480-file corpus).
Reproduction
To see it, index 40 large .py files with default settings (I used 17.9 MiB from torch, tensorflow, scipy, wx and others), or any Python tree with CBM_WORKERS=1, and watch peak memory.
| Peak memory, Linux x86_64, 32 logical CPUs, GCC 16 | main | fixed |
|---|---|---|
40 large .py files, 3 workers (sequential because ≤ 50 files) |
962 MB | 246 MB |
480 .py files from a Python 3.14 install, CBM_WORKERS=1 |
865 MB | 137 MB |
240 .go files from the Go 1.26.3 source, CBM_WORKERS=1 |
225 MB | 108 MB |
Logs
Diagnostics trajectory (memory / performance / leak issues)
Not a leak: the extra memory is held until one index run ends, so the table gives each run's peak memory rather than a trajectory.
Project scale (if relevant)
No response
Confirmations
- I searched existing issues and this is not a duplicate.
- My reproduction uses shareable code (a dummy snippet or a public OSS repository), not proprietary code.
Activity
DeusData commentedon Oct 19, 2026
Thank you for separating retained per-run memory from a leak and for including the reparse-time tradeoff. The sequential-versus-parallel cache behavior is useful context. The proposed lifetime change still needs verification.
DeusData commentedon Oct 25, 2026
Thank you for your patience. Sequential-result lifetime and the reparse tradeoff remain the review scope. Sorry for the delay; I’ll follow up soon.
DeusData commentedon Oct 29, 2026
Fixed on main by #2418 (merge ba4122d): the sequential definitions pass no longer keeps every result with its parse tree and working arena alive until the end. On six projects indexed with one worker the graph is byte-identical and peak memory drops by 20 to 89 percent (for example django 3.50 to 0.55 GB). Thank you for the report and the fix!