Repository navigation
Workload: declare range-query step and span so Stage 2/3 plan pane sharing across steps and refreshes #757
Description
Problem, by example
Take a dashboard panel that refreshes every 30 s. Each refresh sends one range query:
GET /api/v1/query_range?query=histogram_quantile(0.99, sum by (le) (rate(http_request_duration_seconds_bucket[5m])))
&start=now-1h&end=now&step=60
Each refresh evaluates the expression at 61 steps, one per minute over the last hour. Consecutive steps overlap by 4 of their 5 minutes, and consecutive refreshes overlap by 59 of their 61 steps.
The workload cannot say this today. A QueryWorkloadEntry has a QueryRecurrence (OneTime, Repeated(RepeatedDemand::FixedInterval | FixedIntervalAt | Scheduled | EstimatedRate), Unknown). That describes how often ONE evaluation runs, but not that each request evaluates a range of span / step + 1 points. The best a deployment can declare is FixedInterval(30 s), which says one evaluation per 30 s.
As a result:
- Stage 3 under-prices every plan by about 61×. It prices one evaluation per refresh, not 61.
- Stage 3 cannot see that sharing pays off. It does not know that panes or kept query-time results are reused across steps and across refreshes, so it never credits that reuse. ASAPQuery-backend #825 measured this: a 5-step range request needed 9 kept-pane builds with sharing against 25 without, and fetched raw samples once instead of 9 times.
- Stage 2 cannot match the pane grid to the step. Panes must be aligned with the step to be readable at every step. The ASAPQuery-backend runtime forwards a request whose steps fall off the pane grid.
- Retention cannot cover the refresh. Kept results are evicted relative to the newest step. Each refresh of
[now−1h, now]therefore rebuilds the panes its earliest steps read. In #825's test, a repeated request rebuilt 3 of them.
Proposal
-
Declare the range shape in the workload. Add an optional range description to a repeated query, for example:
/// A query answered as a range request: each run evaluates the expression at every /// step in (end − span, end], e.g. a dashboard panel over the last hour at 1-minute steps. pub struct RangeEvaluation { /// Time between consecutive evaluation points, in milliseconds. pub step_ms: u64, /// Width of the range each request covers, in milliseconds. pub span_ms: u64, }
It is carried on
QueryWorkloadEntrynext torecurrence, which keeps meaning "how often a request runs". -
Stage 2 uses
step_msto choose pane widths that divide the step (or equal it), so every step can read the panes. -
Stage 3 prices
span_ms / step_ms + 1evaluations per request. It credits panes and kept results shared across steps, and across refreshes whenspan_msexceeds the refresh interval. Retention of kept results is priced forspan_ms, not just for the window. -
The installable plan carries the retention the runtime must use for kept results (at least
span_msplus the window), so the runtime stops evicting panes that the next refresh will read.
Scope and acceptance
- A workload entry with
RangeEvaluation { step_ms: 60_000, span_ms: 3_600_000 }changes Stage 3's per-request cost to cover 61 evaluations. A test pins the numbers. - With that declaration, Stage 2 selects pane widths aligned with the step.
- The installable plan reports the kept-result retention, and a runtime following it rebuilds no panes on a repeated refresh. ASAPQuery-backend #825's repeated B3 request is the check.
- PromQL frontends could later infer the range from
query_rangetraffic. That is out of scope here.
Related
ASAPQuery-backend #825 (range queries), #824 (kept query-time results), #754 (kept results almost never selected), #755 (installable plan).
Activity