Repository navigation
Conversation
|
Review complete. 🟠 1 high 💬 Inline comments (1)
This PR introduces a memory-aware admission and eviction controller for the plan cache:
Reviewed commit: c83256e |
There was a problem hiding this comment.
Adds a process-heap admission/eviction controller for the schema plan cache, wires it through the GraphQL server instance build path, and adds env/config validation helpers in the graphql/env package.
Key findings
- 🟠 Disposal failure permanently bricks all schema admission — admission.ts:71
Consolidate PR #1747, including its merge-owned release instrumentation, before rebasing onto current main.
71ead47 to
21a42e4
Compare
Concurrent cold cache misses previously started resource allocation before a resident slot was available. F19 reserves resident count and process-heap headroom first, accounts for disposal in progress, and waits for evicted resources before admitting replacements.
Rebased onto main
299b3920; tested head21a42e45. This main-based PR includes the F04/F17 prerequisites. #1855 also targets main and includes this PR's commits; the two diffs overlap.Measured conclusion: pre-allocation admission works, but the measurements do not establish a stable speedup or RSS reduction. Evaluate this as cold-burst resource protection, not a demonstrated throughput optimization.
The existing measured cache heap budget remains enforced through
cacheGraphileInstance, including oversized-build release and reservation cleanup. ExistingGRAPHILE_CACHE_MAX_HEAP_BYTESremains distinct from the new process-watermark settingGRAPHILE_CACHE_HEAP_MAX_BYTES. Configuration parsing/precedence belongs to graphql-env; main's current presets, scoped introspection, request ownership and storage-cache invalidation are retained. Cleanup failure permanently latches admission unavailable until process restart.Measured medians, three runs per row; elapsed time completes all requested builds and validation reads:
At tight capacity 4, main started all 8 creates concurrently. F19 limited concurrent creates to 4: 4 initial calls succeeded and 4 returned
SCHEMA_CAPACITY_EXHAUSTEDbefore service allocation. After the entire initial wave settled, one immediate in-process retry wave completed the remaining 4. The all-completed timer starts before the initial calls and includes rejection time, the initial-wave wait, retry work and scheduling; there is no artificial network/backoff delay. Real client retry latency may be higher. This compares equal completed work, not 4 successful builds against 8.The loose-8 median is 13.4% lower, but ranges overlap substantially: main 6580–7810 ms, F19 6100–7496 ms. Three repetitions do not support a reliable general speedup, and RSS did not decrease.
Measured on 2026-11-04: Node 24.20.0, PostgreSQL 18.6, 3 available CPUs, approximately 4 GiB RAM,
--expose-gc --max-old-space-size=768. Each fresh worker builds a 24-table schema and validates a seeded GraphQL read. Three repetitions per arm/scenario, randomized sequential order; 36/36 runs passed across main/F19/F21. Every successful build produced the same schema hash and query result.Loose capacity is 50 residents; tight capacity is 4. Both measured resident heap budget and process heap watermark are set to 4 GiB, with a 64 MiB build reserve, to isolate count/coordinator behavior. This does not test default heap-watermark tuning or OOM prevention. No subscriptions are used.
The validation read runs inside the create callback before publication to prevent eviction racing validation. Consequently, permit occupancy includes query time: this is a cache-layer cold build-and-query microbenchmark, not production HTTP latency/throughput or a bound on all SQL concurrency. RSS peaks cover the entire run, including retry waves.
Validation at the rebased head:
Raw measurements, samples and runtime/source provenance are retained in the task workspace at
/workspace/scratch/admission-rebase/bench/results-24.json; grouped medians/ranges are inresults-24-summary.json, alongside the worker, runner and analysis scripts.