Skip to content

rqe-optimizer: let mergeable finer-group deployments serve coarser RAQEs #187

Description

@milindsrivastava1997

What to build

Extend the optimizer so that a deployment keyed by a finer grouping can serve a RAQE at a coarser grouping when the sketch family has sound merge semantics for the roll-up. For example, a deployment by (service, endpoint) may serve a query by (service) by merging its endpoint states per service. Treat this as a derived readout: the planner must choose it only when its modeled accuracy and latency satisfy the RAQE's SLAs and its total cost beats the alternatives.

Do not make this a blanket subset-of-labels rule. Families without valid roll-up semantics remain ineligible.

Acceptance criteria

  • Candidate eligibility can represent a valid finer-to-coarser grouping relationship for explicitly supported mergeable sketch families, while preserving exact-grouping eligibility for all other families.
  • The cost and SLA model prices the roll-up read, including child states merged per parent group and its transient memory/latency.
  • Accuracy used for the roll-up corresponds to the merged coarse-group answer rather than assuming the fine-group estimate is directly reusable.
  • The mixed-grouping scenario can select one fine-grained deployment for both RAQEs when that plan is cheaper and SLA-valid.
  • Tests demonstrate a valid shared roll-up plan and rejection for unsupported or non-mergeable families.

Related

Blocked by

None - can start immediately

Activity

  1. milindsrivastava1997 commented on Oct 9, 2026

    @milindsrivastava1997
    ContributorAuthor

    Design decisions (for review)

    Notation: a deployment grouped by G_d serves a RAQE grouped by G_r ⊂ G_d by merging each G_r group's fine states into one (a roll-up). L is the lookback, x the window, T the query interval. Example used throughout: KLL by (service, endpoint) (card = 50) serving p99 by (service) (card = 5), L = 1h, x = 1m.

    Each answer below is the decision. Please approve or push back.

    Scope

    • Out of scope: top-k and Hydra. Top-k heaps don't roll up: an item can be outside every child's top-k but in the parent's. Hydra returns estimates, not mergeable per-key KLLs.
    • ASAPQuery can't execute roll-ups yet. No feature flag: ASAPQuery pins a sketch-bench rev, and until it supports roll-ups it should error on a plan where a RAQE's grouping differs from its deployment's. Threading a flag into is_eligible would touch about 8 signatures.
    • Uneven fan-out (e.g. one service owning 46 of 50 endpoints) is split out to rqe-optimizer: read accuracy at the largest group's sample count, not the average #189: worst-group sample count, plus fan-out (comment). This issue uses averages.

    Q1. Which families can roll up?

    New FamilyProperties::mergeable_across_groups. The test for each family: does merging per-G_d states give the G_r answer?

    Family Merge across groups Decision
    exact-sum (Sum, Count), exact-min, exact-max add / min / max true
    exact-increase (RateOrIncrease) add increases (a coarse rate is sum by (G_r)) true
    hll, univmon-cardinality union true
    kll-percall, dd sketch merge true
    cms/countsketch heap top-k, univmon-topk heap merge loses items false
    hydra-kll none false

    is_eligible: groupings are equal, or the family is mergeable_across_groups and r.grouping ⊂ d.grouping. A coarse deployment never serves a finer RAQE.

    Q2. Which RAQEs decide a fine deployment's candidate windows?

    Today, windows, slides and heaps for grouping G come only from RAQEs grouped exactly by G. A fine x that doesn't divide the coarse RAQE's L can't be shared.

    Decision: for families that merge across groups, derive them from every RAQE with the same capability, metric and filter whose grouping ⊆ G. Other families (top-k) keep exact-grouping inputs, so their candidate count doesn't grow. No new groupings are invented: candidates exist only for groupings some RAQE uses.

    Q3. How is a roll-up read priced?

    Each merge folds two states into one. A query reads card(G_d)·L/x states and ends with card(G_r), so:

    merges = card(G_d) · L/x − card(G_r)
    

    (Check with 2 services × 2 endpoints and L/x = 3: 12 − 2 = 10. Folding windows takes 2 × 4 = 8 merges, then folding endpoints takes 1 × 2 = 2.)

    Phase Today Decision
    merge CPU card(G)·(L/x − 1)·c_mrg / T (card(G_d)·L/x − card(G_r))·c_mrg / T
    merge memory card(G)·m(L) card(G_r)·m(L)
    query CPU / output card(G)·… card(G_r)·…
    latency card(G)·c_qry + card(G)·(L/x−1)·c_mrg card(G_r)·c_qry + merges·c_mrg
    ingest, storage G_d unchanged
    • With G_r = G_d, every row reduces to today's formula.
    • A direct query (L == x) that rolls up still merges card(G_d) − card(G_r) states.
    • DD's accumulator m(L) is sized from a coarse group's values, λ·L / card(G_r).
    • Assumption: a cross-group merge costs the measured c_mrg, the same as a cross-window merge.

    Q4. How is roll-up accuracy computed?

    Input Today Roll-up
    DataShape data_shape[G_d] data_shape[G_r]
    N per group λ·L / card(G_d) λ·L / card(G_r)
    Merged instances (KLL only: it merges lossily, #131) L/x ⌈card(G_d) / card(G_r)⌉ · L/x

    DD, HLL and exact families merge exactly, so only the shape and N change for them. Past the merge counts the study measured, the existing theory fallback or rejection applies.

    Q5. How does the plan show a roll-up?

    Decision: no new field. A RAQE is a roll-up exactly when raqe.grouping_labels != deployment.grouping_labels. merged_instance_count stays L/x windows per fine group. small_problem.rs prints rolls up G_d → G_r on the RAQE line.

    Q6. Validating facts

    The merge count assumes card(G_r) ≤ card(G_d). Bad facts (e.g. card(service) = 60 > card(service, endpoint) = 50) would give negative merge CPU, which the MILP would treat as a discount.

    Decision: validate_facts requires card(X) ≤ card(Y) for every pair X ⊂ Y in cardinality. This generalizes the existing "more groups than series" check rather than clamping in the cost model.

    Q7. Tests

    Where Test
    tests/mixed_grouping.rs End to end, written first and failing on main: two quantile RAQEs by (service, endpoint) and (service) share one fine KLL deployment. Top-k at the same groupings keeps one deployment per grouping.
    candidates.rs Roll-up only to a subset grouping and only for mergeable families. Top-k serves only its own grouping. Fine candidates take windows from coarser RAQEs (L = 1h fine with L = 90m coarse gives a fine x = 30m), but top-k candidates don't.
    analytical_cost_model.rs Roll-up merge count, accumulators and latency, including a direct (L == x) roll-up.
    saturation.rs KLL roll-up reads the coarse shape, coarse N, and ⌈fan-out⌉·L/x merges.
    lib.rs Subset-cardinality validation.

    Existing tests all use equal groupings and must pass unchanged, which shows that plans without roll-ups don't move.

    🤖 Generated with Claude Code

  2. milindsrivastava1997 commented on Oct 9, 2026

    @milindsrivastava1997
    ContributorAuthor

    Change to Q1 (design comment): exact-increase (RateOrIncrease) does not roll up. Its mergeable_across_groups is false, because a rate rolled up to a coarser grouping isn't a meaningful query.

    Updated Q1 table:

    Family Roll up?
    exact-sum (Sum, Count), exact-min, exact-max yes
    hll, univmon-cardinality yes
    kll-percall, dd yes
    exact-increase (RateOrIncrease) no
    cms/countsketch heap top-k, univmon-topk no
    hydra-kll no

    The test candidates::tests::a_rate_serves_only_its_own_grouping covers it.

  3. added a commit that references this issue on Oct 9, 2026
    4bc0aa3
  4. added a commit that references this issue on Oct 9, 2026
    c20748e
  5. added a commit that references this issue on Oct 9, 2026
    eebaa9c
  6. added a commit that references this issue on Oct 10, 2026
    79d3983
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions