Summary
The post-parse analysis phases use memory that grows sharply superlinearly in
the number of window objects (.srw). 815 windows exhaust 44 GB. Parsing
itself is fine — every file parses successfully first — and DataWindows are
not implicated despite being the bulk of the corpus and the largest files.
This is separate from the stack-overflow crash in #3; the runs below all have
an adequate stack.
Measurements
Splitting one ~5,500-file tree by file type and indexing each subset alone:
| subset |
files |
outcome |
.srd DataWindows |
3695 |
clean |
.sru user objects |
654 |
clean |
.srw windows |
815 |
OOM-killed above 44 GB |
.srd is the majority of that tree by both file count and total bytes, so
size alone does not predict this.
Growth against window count, -M40G -N4, peak RSS:
| windows |
time |
peak RSS |
| 100 |
8s |
10 GB |
| 200 |
15s |
11 GB |
| 400 |
203s |
22 GB |
| 600 |
287s |
23 GB |
| 815 |
— |
OOM > 44 GB |
Two things stand out beyond the ceiling itself: time rises 15s → 203s for a
2x input increase, and even 100 windows costs 10 GB, which seems a steep
baseline.
The full mixed tree behaves consistently with this — 5,473 files with an
adequate stack parsed 5,446 files and wrote a 2.0 GB database before being
OOM-killed at 707s.
Notes
-M does not bound this. Resident memory routinely exceeds the GHC heap
cap, presumably because pinned and foreign allocation (DuckDB buffers) sit
outside it — so -M40G inside a 44 GB limit still gets OOM-killed.
- Lowering
-N does not help either; peak tracks the -M ceiling rather than
worker count.
pbc --help exposes no memory controls, so there is nothing to tune from
the outside.
Impact
This puts whole-repository indexing out of reach for large codebases on
ordinary hardware, since 815 windows already exhaust 44 GB. Partitioning
per-library would keep each run small, but it sacrifices exactly the
cross-object analysis that spans libraries.
I am not able to share the tree itself, but I can measure whatever would
help — happy to run further experiments, bisect which phase the growth
happens in, or produce a profile if you would find one useful.
Environment
pbc built from haskell:9.10.2-bullseye, GHC 9.10.2, per the versions in
the project's own CI workflow
- Linux x86_64, 64 GB RAM, 16 cores
Summary
The post-parse analysis phases use memory that grows sharply superlinearly in
the number of window objects (
.srw). 815 windows exhaust 44 GB. Parsingitself is fine — every file parses successfully first — and DataWindows are
not implicated despite being the bulk of the corpus and the largest files.
This is separate from the stack-overflow crash in #3; the runs below all have
an adequate stack.
Measurements
Splitting one ~5,500-file tree by file type and indexing each subset alone:
.srdDataWindows.sruuser objects.srwwindows.srdis the majority of that tree by both file count and total bytes, sosize alone does not predict this.
Growth against window count,
-M40G -N4, peak RSS:Two things stand out beyond the ceiling itself: time rises 15s → 203s for a
2x input increase, and even 100 windows costs 10 GB, which seems a steep
baseline.
The full mixed tree behaves consistently with this — 5,473 files with an
adequate stack parsed 5,446 files and wrote a 2.0 GB database before being
OOM-killed at 707s.
Notes
-Mdoes not bound this. Resident memory routinely exceeds the GHC heapcap, presumably because pinned and foreign allocation (DuckDB buffers) sit
outside it — so
-M40Ginside a 44 GB limit still gets OOM-killed.-Ndoes not help either; peak tracks the-Mceiling rather thanworker count.
pbc --helpexposes no memory controls, so there is nothing to tune fromthe outside.
Impact
This puts whole-repository indexing out of reach for large codebases on
ordinary hardware, since 815 windows already exhaust 44 GB. Partitioning
per-library would keep each run small, but it sacrifices exactly the
cross-object analysis that spans libraries.
I am not able to share the tree itself, but I can measure whatever would
help — happy to run further experiments, bisect which phase the growth
happens in, or produce a profile if you would find one useful.
Environment
pbcbuilt fromhaskell:9.10.2-bullseye, GHC 9.10.2, per the versions inthe project's own CI workflow