Summary
Graph projection is a full-history rebuild with full materialization: every run executes SELECT <cols> FROM <sourceDataset> — no WHERE, no watermark (plugins-workspace/context-graph/src/project.js, the LLP 0096 shared scan) — through executeQuerySql, which collects every row into a JS array (result.rows) before the rule loop starts. Both the run's memory and its time are O(entire history), so the design has a scaling expiry date independent of any budget or host size. On the hyperparam prod server it has already expired: the kernel's 1 GiB heap-growth budget (LLP 0097) now refuses every projection run — correctly, since millions of materialized rows are genuine retention — and the graph has been frozen at 2026-07-10 for three weeks (hypaware-server#143).
The output side is NOT the problem: three months of fleet history projects to only 9,904 nodes / 28,151 edges — the node/edge maps are trivial. It's the input rows that are materialized wholesale.
Why each cheap fix expires
- Raise the budget for projection runs: retained rows grow linearly with ingest (hyperparam prod: 202k rows on 07-10 → 1.66M+ by 07-22). Any ceiling is walked to within weeks-to-months, and past it lies the OOM class the budget exists to prevent. Band-aid only.
- Slice the scan by date partition: bounds memory durably (peak retention = one slice's rows; the accumulated node/edge maps stay small). But each run still scans all of history — a full pass costs 17–42s today, grows linearly forever, and runs daily on the same event loop that serves queries and ingest.
Proposed
- Incremental projection with a per-scope watermark: each automatic run reads only rows past the last successful run's high-water mark (
date partition + a stable tiebreaker). The graph's upsert/first_seen semantics already accommodate append-style updates. O(new data) per run, constant-ish forever.
- Streaming or sliced reads for internal callers: projection should iterate rows without materializing the full result — either a streaming interface on
executeQuerySql for trusted daemon jobs, or per-date-slice queries with rules applied per slice. This keeps full REBUILDS possible at any history size.
- Full rebuild becomes the recovery path, not the daily path: kept for contract changes, run sliced (and ideally admin-triggered/offline), preserving the derived-rebuildable philosophy (LLP 0053) without paying its cost daily.
Context
Found while diagnosing hypaware-server#143 (prod graph frozen at 07-10 across the 07-16 redeploy that shipped the heap budget): the issue-#9 OOM fix and automatic projection (#124) are incompatible as shipped, and the freeze self-perpetuates (scheduler retries daily into the same refusal). The band-aid/slice/watermark ladder is written up there; this issue tracks the durable fix.
Summary
Graph projection is a full-history rebuild with full materialization: every run executes
SELECT <cols> FROM <sourceDataset>— no WHERE, no watermark (plugins-workspace/context-graph/src/project.js, the LLP 0096 shared scan) — throughexecuteQuerySql, which collects every row into a JS array (result.rows) before the rule loop starts. Both the run's memory and its time are O(entire history), so the design has a scaling expiry date independent of any budget or host size. On the hyperparam prod server it has already expired: the kernel's 1 GiB heap-growth budget (LLP 0097) now refuses every projection run — correctly, since millions of materialized rows are genuine retention — and the graph has been frozen at 2026-07-10 for three weeks (hypaware-server#143).The output side is NOT the problem: three months of fleet history projects to only 9,904 nodes / 28,151 edges — the node/edge maps are trivial. It's the input rows that are materialized wholesale.
Why each cheap fix expires
Proposed
datepartition + a stable tiebreaker). The graph's upsert/first_seensemantics already accommodate append-style updates. O(new data) per run, constant-ish forever.executeQuerySqlfor trusted daemon jobs, or per-date-slice queries with rules applied per slice. This keeps full REBUILDS possible at any history size.Context
Found while diagnosing hypaware-server#143 (prod graph frozen at 07-10 across the 07-16 redeploy that shipped the heap budget): the issue-#9 OOM fix and automatic projection (#124) are incompatible as shipped, and the freeze self-perpetuates (scheduler retries daily into the same refusal). The band-aid/slice/watermark ladder is written up there; this issue tracks the durable fix.