Repository navigation
Conversation
A plan node materialized `MatAtQueryKeptAcrossEvaluations` (#509 Example 4's B3) is now executed instead of rejected. Its output is kept in memory by (definition, pane end), with the SDS identity rule, built from its pane's raw samples the first time an evaluation reads it, reused by later evaluations, and evicted like stored panes (older than the largest read offset plus two pane widths, measured from the newest evaluation). The control plane's default DeploymentCapabilities now set query_time_results_retained. examples/planner-layering-example4-b3.json is a workload for which the Planner selects B3 under the default cost model.
A pane computed at query time is kept across evaluations only once its end is at or before the precompute engine's watermark (newest sample minus the allowed lateness). A pane read while still open is computed for that evaluation but not kept, so a later evaluation computes it again, including samples that arrived late, and keeps it once it is closed.
This was referenced Oct 18, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Stack 6/6. Base: #822.
Why
#819 rejected any plan that keeps a query-time result across evaluations, and the backend declared
query_time_results_retained: false, so the Planner never offered #509 Example 4's B3 (tumbling panes built at query time and kept). The design's query engine section specifiesMatAtQueryKeptAcrossEvaluations, so the backend can now execute it and declare it.What
MatAtQueryKeptAcrossEvaluationsnode's output is stored after it is computed, in memory. It is keyed like a pane, by (definition, pane end). Identity follows the SDS rule: an offset-onlyTimeShifttakes its input's identity, and the offset goes into the pane binding. A kept output must have the stored-pane shapeTimeRange(width) ← TimeShift(offset)* ← Scan; any other shape isUnsupportedShape.T, a kept output reads the kept pane ending atT − offset. A missing one is computed from its pane's raw samples(end − width, end], fetched from Prometheus.--allowed-lateness-ms; no watermark before the first sample). A pane read while still open is computed for that evaluation but not kept. A later evaluation computes it again, so it includes samples that arrived late, and keeps it once it is closed. In B3 each evaluation after the first fetches one minute of raw samples instead of five.backend_capabilities()setsquery_time_results_retained: true.SdsError::KeptAcrossEvaluations.x-asap-execution,x-asap-forward-reason.examples/planner-layering-example4-b3.jsonis Example 3b's panel (quantile_over_time(0.99, latency_ms[5m])every minute) over 10 series sampled every millisecond (10,000 rows/s). The Planner selects B3 (P3-m2) for it under the default cost model.How
Sds::from_dagruns the frontier's per-output pass over every kept node too, intokept_definitions/kept_outputs. The pane build (Scan, then the definition's sub-DAG from itsTimeRangeup to its builder) moves out of the precompute engine intoPaneBuild, which both engines use. The precompute engine runs it under ingestion scope. The query engine runs it under query scope at the pane's end, so a kept pane is the same whichever evaluation built it.QueryEnginecompiles each root with kept outputs as bounded inputs.raw_rangesasks for the raw range of each kept pane not held yet.evaluatebuilds those panes, keeps the closed ones (the engine thread passes the precompute engine's watermark), reuses the rest, then evicts.Key code interfaces added / modified
Before this PR
The B3 workload planned with
query_time_results_retained: false(the old default) getsP2, one KLL rebuilt over the whole 5-minute window at every evaluation. A plan that does contain B3 fails to install:After this PR
The default deployment gets B3 (
P3-m2) for that workload: five 1-minute KLL panes built at query time and kept. The first evaluation fetches five 1-minute raw ranges from Prometheus. Each later one fetches only the newest minute and reuses the other four panes. Every answer equals the Planner executor's.Usage
The output comments come from running this as a scratch test on this PR's tree, with one series whose
nth 15-second sample is25n mod 101. Over HTTP, the same flow runs indata_plane/tests/e2e_examples.rs::example4_b3against thedata_planebinary.End-to-end numbers
cargo test -p data_plane --test e2e_examples -- --nocapture, Example 4 B3 (two series, one sample every 15 s up to 13 min, so every pane read is closed; evaluated at 10, 11 and 12 min):The other examples select the same plans as before (
P1,P485,P2,P3-m1,P4125,P3-m1) and give the same answers. 3a/4a still differ by at most 1, as in #822.Planner notes (no Planner change)
planner_layering_example4.rsonly checks that it is offered. Swept over 1–1M series at a consistent rate (series / interval): B3 never wins at 15 s or 1 s intervals. At a 1 ms interval it wins from 10 to 100 series, which is the example added here.Limitations
--allowed-lateness-ms), is not in the kept pane, as for stored panes.Verification
Tests written first; each failed against interface stubs before the implementation (the kept answers matched, then the stats assertion failed with
built: 0; the control plane test failed on the old default).data_plane/tests/kept.rs(3 tests): a pane read before it closes is not kept, is computed again by the next evaluation including a late sample (answer changes, equals the reference), and is kept once the watermark reaches its end; with no watermark nothing is kept. (a) and (b), the B3 plan answers like the reference at 10 and 11 min; the second evaluation reads one raw range and reuses four panes (KeptResultStats { built: 6, reused: 4 }); repeating it recomputes nothing. (c), eviction at 11, 12 and 20 min and after an older evaluation.data_plane/tests/sds.rs: kept panes share one definition with offsets 0..4 min; a kept output without a pane isUnsupportedShape(replaces the rejection test).control_plane/tests/plan_workload.rs: the default capabilities keep query-time results, and the B3 workload selects five keptSummaryAggpanes.data_plane/tests/e2e_examples.rs::example4_b3: the binary over HTTP, three evaluations vs the executor, raw ranges fetched[5, 1, 1].cargo test -p control_plane -p data_plane(all pass, e2e 6 tests in 382 s debug),cargo fmt --all -- --check,cargo clippy --workspace --all-targets --locked -- -D warnings.