Problem
The exact merged S20 Graph500 ladder on commit eccb6e06726d05cdef9e5242cad885be80565eee completed bounded ingest on a private 2-performance-vCPU / 4 GiB Fly machine, then was kernel-OOM-killed during the ordinary fixed-hop query proof.
Authoritative aggregate evidence:
- generator: 4.80 s, about 80 MB peak RSS
- ingest: 2,602.08 s, 15,698,918 live unique edges, about 688 MB peak RSS
- reopen plus recount: passed in 231.40 s but raised process high-water RSS to 3,328,512,000 bytes
- query phase:
MATCH (a)-[r]->(b) RETURN b.node_uuid AS id ORDER BY id LIMIT 1000, followed by the two-hop equivalent if the first completes
- last durable query journal: about 1.90 GB anonymous RSS resident and 3.33 GB process high-water
- kernel victim:
scale-g500-ladd, about 3.80 GB anonymous RSS and negligible file RSS
- exit status: 137
- volume: 52% used, so this was not storage exhaustion
The query journal is written before the one-hop request and only persisted again after both requests, so current evidence cannot yet distinguish whether the OOM occurred in the one-hop query or the two-hop query. That attribution gap is part of the required repair.
Objective
Make reopen/recount and fixed-hop ORDER BY ... LIMIT execution remain bounded by explicit batches/frontiers rather than graph cardinality or path-result cardinality. GraphForge is designed to be disk-bound at scale; a larger machine is not the repair.
Requirements
- Measure RSS and operator state independently for project open, node count, edge count, one-hop expand, one-hop order/limit, two-hop first expansion, two-hop second expansion, and two-hop order/limit.
- Identify retained allocations after reopen/recount and prove they are released or intentionally bounded before query execution.
- Push terminal demand through fixed-hop expansion where semantics permit, while preserving deterministic global
ORDER BY results.
- Implement bounded top-k/spill for ordered LIMIT rather than materializing all candidate/path rows.
- Keep adjacency/topology access streaming or shard/page selective; do not load the complete edge set into anonymous memory.
- Preserve ordinary Rust facade execution. Do not add a ladder-only query path, skip, relaxed limit, or increased RAM requirement.
Acceptance criteria
- S20 source reopen, recount, one-hop query, and two-hop query complete on the same 4 GiB machine class with phase/operator RSS evidence and reasonable headroom.
- Peak anonymous RSS plateaus across lower rungs and remains bounded by documented operator budgets, not edge/path cardinality.
- Ordered LIMIT results match the existing deterministic semantics.
- Tests fail if a fixed-hop ordered LIMIT materializes the complete candidate set or if query allocations remain retained after completion.
- The journal persists one-hop completion before starting two-hop work, so a host OOM identifies the exact query/operator.
- Full source → export → verify → clean import → reopen proof completes without a benchmark-only fallback.
Root-cause boundaries
This issue is independent of #901. #901 owns superlinear topology publication I/O and retained-generation disk amplification. This issue owns post-ingest reopen/recount and execution memory. Both block the canonical S20 gate #900.
Observability
Record aggregate rows examined/emitted, expansion frontier size, top-k heap/spill bytes, Arrow batch rows, process RSS before/after each operator, and retained memory after each query. Do not record graph identities, values, paths, or credentials.
Testing
- deterministic lower-scale tests with fixed batch/operator budgets across increasing graph cardinality
- one-hop and two-hop ordered LIMIT plan and execution regressions
- allocation-release regression between recount and query phases
- exact changed-surface formatting, clippy, Cargo/Bazel drift, and authoritative CI
Problem
The exact merged S20 Graph500 ladder on commit
eccb6e06726d05cdef9e5242cad885be80565eeecompleted bounded ingest on a private 2-performance-vCPU / 4 GiB Fly machine, then was kernel-OOM-killed during the ordinary fixed-hop query proof.Authoritative aggregate evidence:
MATCH (a)-[r]->(b) RETURN b.node_uuid AS id ORDER BY id LIMIT 1000, followed by the two-hop equivalent if the first completesscale-g500-ladd, about 3.80 GB anonymous RSS and negligible file RSSThe query journal is written before the one-hop request and only persisted again after both requests, so current evidence cannot yet distinguish whether the OOM occurred in the one-hop query or the two-hop query. That attribution gap is part of the required repair.
Objective
Make reopen/recount and fixed-hop
ORDER BY ... LIMITexecution remain bounded by explicit batches/frontiers rather than graph cardinality or path-result cardinality. GraphForge is designed to be disk-bound at scale; a larger machine is not the repair.Requirements
ORDER BYresults.Acceptance criteria
Root-cause boundaries
This issue is independent of #901. #901 owns superlinear topology publication I/O and retained-generation disk amplification. This issue owns post-ingest reopen/recount and execution memory. Both block the canonical S20 gate #900.
Observability
Record aggregate rows examined/emitted, expansion frontier size, top-k heap/spill bytes, Arrow batch rows, process RSS before/after each operator, and retained memory after each query. Do not record graph identities, values, paths, or credentials.
Testing