Repository navigation
Manual windowing override (tumbling/sliding) in config.yaml #555
Description
Problem
asap-planner-rs's live planner is hardcoded to always emit tumbling
windows. should_use_sliding_window() (planner/window.rs:11-14)
unconditionally returns false
WindowType::Sliding already exists in asap_types::enums and is exercised
by the offline optimizer/cost-model code (optimizer/candidate_gen.rs,
cost_model.rs), but never reachable from the live planner paths that
asap-tools/experiments actually drives.
What this issue covers
Add a manual windowing override to config.yaml, threaded through to the
planner, so an experiment can explicitly choose tumbling vs. sliding windows
(and a slide granularity) instead of always getting tumbling:
windowing:
type: "tumbling" # or "sliding"
slide_divisor: 4 # only meaningful when type == "sliding";
# slide_interval_ms = window_size_ms / slide_divisor- Global override (not per-query-group) for now — matches
sketch_parameters's existing global-only shape. Per-aggregation-id
control is the ideal case but out of scope here (tracked separately). - PromQL + SQL paths:
ControllerConfig/SingleQueryProcessor→
set_window_parameters(), andSQLControllerConfig/
SQLSingleQueryProcessor→compute_sql_window(). ElasticDSL excluded —
nothing inasap-tools/experimentsgenerates its controller config today. slide_divisormust evenly divide each query's computedwindow_size_ms
(which varies per query — it's derived from that query's ownt_repeat_ms
/step_ms, not a global constant) — error loudly, never round.- Fail-fast: if any one query in the workload can't legally take a
sliding window under the chosen divisor, plan generation aborts entirely
rather than silently punting that query to the raw backend. This is a
deliberate experiment setting, not an automatic optimizer decision — a
silent fallback would quietly corrupt the cost/latency comparison the
experiment exists to make.
Blocked by #554
Shipping this override before sliding-window queries can actually be served
correctly (beyond the narrow single-window-exact-match case) means
windowing.type: sliding would produce plans that fail at query time for
almost any real workload query. See #554 for why, and for the
execution-side work this depends on.
Definition of done
- Config plumbing + validation + fail-fast behavior, both PromQL and SQL
paths. - Unit tests for the plumbing itself (config parses; divisor-validation
errors correctly; fail-fast behavior) — these don't depend on Sliding window execution: support multi-window merge/subtract in query engine #554
and can be written now. - Not required here: an end-to-end "sliding query actually returns
correct data" test. That belongs to Sliding window execution: support multi-window merge/subtract in query engine #554, since it's the thing that
proves execution works, not candidate generation — this issue is
scoped to generating the candidates/config, not executing them.
Related
- Complementary to feat: Optimization-based sketch/streaming config selection #405 (optimization-based automatic config selection) —
this is the manual stand-in for what feat: Optimization-based sketch/streaming config selection #405 would eventually choose
automatically, not a duplicate of it. - Full grilling decisions log (rationale for every choice above) attached as
a comment on this issue.
Activity
milindsrivastava1997 commentedon Aug 20, 2026
Sliding window manual override — grilling decisions log
Status: Planning only. Nothing implemented. Blocked on a separate issue
(window-serving execution support, "Issue B" below) before any code lands.
Goal: run a tumbling-vs-sliding-window experiment via
asap-tools/experiments/experiment_run_e2e.py, comparing window types (andsizes) at the cost/latency level. Arroyo is out of scope entirely — it's
deprecated, and the planner's
should_use_sliding_window()hardcoded-offswitch (
asap-planner-rs/src/planner/window.rs:11-14) exists only becausesliding windows used to crash it.
See [[sliding-window-multi-window-merge-blocker]] for the technical trace of
why sliding windows aren't usable today beyond the narrowest case, and for
the cross-reference to issue #405.
This doc records the design decisions from the
/grillingsession, for theeventual issue descriptions and PR.
Decisions
D1 — Override granularity: global, not per-query-group
One
windowing:setting inconfig.yamlapplies to the whole experimentrun, same shape as the existing
sketch_parameters:block. Not per-query-group(unlike
t_repeat_ms/step_ms/range_duration_ms, which already supportper-
QueryGroupoverrides).Why: the experiment sweeps window type/size across whole runs (one hydra
multirun leg = one window config), not within a single run. Per-query-group
control has no current use case and would roughly double the plumbing.
Ideal case (not this work): per-aggregation-id overrides — deferred to
Issue C below, since it applies equally to
sketch_parameters(alsoglobal-only today) and to windowing.
D2 — Slide interval specified as a divisor, not absolute ms
slide_interval_ms = window_size_ms / slide_divisor, computed after eachquery's own
window_size_msis derived (window_size_msdiffers per query —it's a function of that query's
t_repeat_ms/step_ms, not a globalconstant). An absolute
slide_interval_msoverride wouldn't divide evenlyinto every query's window size in general.
D3 — Config shape
Top-level key, mirroring
sketch_parameters:'s placement. No new casingconvention needed —
WindowTypealready deserializes from"tumbling"/"sliding"directly.D4 — Scope: PromQL + SQL, not ElasticDSL
ControllerConfig(config/input.rs:11-31) →SingleQueryProcessor(
planner/promql.rs) →set_window_parameters()(planner/window.rs).SQLControllerConfig(config/input.rs:141-147) →SQLSingleQueryProcessor(planner/sql.rs) →compute_sql_window()(structurally a duplicate of
set_window_parameters(), same invariants,same relaxation, currently hardcoded
WindowType::Tumblingatsql.rs:269).generate_controller_client_configs()(PromQL,experiment_utils/config.py:340) andgenerate_sql_planner_input()(SQL,config.py:830, already extended once forsketch_parametersby PR fix(tools): pin TZ=UTC across for ClickHouse experiments #514 —same pattern applies here).
ElasticDSLControllerConfigexists in Rust(
elastic_dsl/generator.rs,elastic_dsl/controller.rs) and is a realasap-planner --query-language elastic_querydslCLI mode, but nothing inasap-tools/experimentsgenerates that config — noexperiment_run_elastic*.py, no Python generator function. Wiring it wouldtouch code nothing in the experiment pipeline calls today.
D5 — Validation: error loudly, never round
If
slide_divisordoesn't evenly divide a query'swindow_size_ms, that's aplanner error (
ControllerError/Result<_, String>), same style as everyexisting invariant check in
window.rs/sql.rs("must be a multiple of ..."etc.). No silent rounding to a nearby millisecond value.D6 — Failure mode: fail-fast across the whole plan
If any one query in the workload can't legally take a sliding window under
the chosen global
slide_divisor, plan generation aborts entirely — it doesnot silently punt that query to the raw backend (unlike the existing
enable_punting/should_be_performantpath for genuinely unsupported queryshapes). Rationale:
windowing.type: slidingis a deliberate, explicitexperiment setting, not an automatic optimizer decision — a query silently
falling back to unaccelerated serving would quietly corrupt the cost/latency
comparison the experiment exists to make.
D7 — Sequencing: blocked on execution-side support
Shipping the override before sliding-window queries can actually be served
correctly (beyond the single-window-exact-match case) means
windowing.type: slidingwould produce plans that fail at query time foralmost any real workload query. Building the override is held until that
lands. See Issue split below.
D8 — Relationship to issue #405
#405 ("Optimization-based sketch/streaming config selection") is the tracked
replacement for automatic planner decision-making generally (sketch type,
params, window config, query method), via a MIP-based optimizer. It already
documents
Sliding: W < range_a → Infeasibleas a deliberate v1 modelingchoice in its own cost formulation — not just an unimplemented case.
Per discussion: #405 stays the design/tracking issue for the optimizer
project as a whole. The windowing work here gets its own issues (below),
not folded into #405, because #405 is about automatically choosing configs
via cost optimization, while this work is about manually controlling
window type/size as an experiment knob — a different, complementary axis.
Both new issues cross-reference #405 (Issue B extends its feasibility-table
assumption about sliding; Issue A is the manual stand-in for what #405 would
eventually choose automatically).
Issue split
Issue A — Manual windowing override (candidate generation / planner side)
The config plumbing itself: D1–D6 above.
windowing: {type, slide_divisor}in
config.yaml→ControllerConfig/SQLControllerConfig→ planner emitsthe right
window_type/window_size_ms/slide_interval_msper aggregation.Blocked by Issue B (D7) — the plan this generates isn't safely runnable
until B lands.
Definition of done:
errors correctly; fail-fast behavior) — these don't depend on Issue B and
can be written now.
returns correct data" test — that's Issue B's responsibility, since it's
the thing that proves execution works, not candidate generation.
(Resolved during grilling: the split is exactly "generating candidates"
(A) vs. "actually executing them" (B), so correctness-of-execution testing
belongs to B.)
Issue B — Sliding-window query execution (multi-window merge/subtract)
The query-engine-side work: relax
capability_matching.rs'swindow_compatibleSliding rule beyond exact-match, implement merge (formergeable sketch types) / subtract (for subtractable ones) across multiple
stored sliding-window buckets in
simple_engine's query-serving path,update
cleanup.rs's Sliding branch to be window-count-aware, and resolvethe epoch/slide-interval alignment question for exact-match lookups. Full
technical trace in [[sliding-window-multi-window-merge-blocker]]. Extends
#405's feasibility-table assumption about sliding windows. Needs its own
/grillingsession — deliberately not designed further here.Definition of done (tentative, to be refined in its own session):
data_range_msa multiple ofwindow_size_ms, mirroring tumbling's existing rule) return correct data.aggregation → assert correct results. This is the test Issue A explicitly
defers to B.
Issue C — Per-aggregation-id parameter overrides (ideal case)
Both
sketch_parameters(today) andwindowing(once A ships) areglobal-only overrides. The ideal is per-aggregation-id control — a detail
the planner emits, not something users author queries around, but currently
inaccessible as an override target. Tracks the gap; no design work done on
it yet.
Open items
record until closer to implementation — pending.
docs(design): refine sliding-window alignment validation and PR stack