Skip to content

MAINTAINER DECISION: the plan-regression detector's "14-day" window only ever sees about 4-5 days of Query Store history on Darling stores with armed purges #3958

Closed

Description

@erikdarlingdata

MAINTAINER DECISION: the plan-regression detector's "14-day" comparison window sees about 4-5 days on Darling

Darling's PLAN_REGRESSION detector and its regressed-queries drill-down both compare a query's current plan against the best plan it ran within 14 days. The fact uses PgFactCollector.PlanRegressionWindowDays = 14 and binds TimeRangeStart.AddDays(-14) on last_execution_time; the drill-down binds the same AddDays(-14). The code comments give the purpose as "the days-old 'best plan' baseline".

On any Darling store whose retention policies are armed, the rows that window reads are gone after about 4 days. query_store_stats is one of the three raw tables TimescaleDB drops at TimescaleSupport.RawRetentionInterval = "4 days" (RawTierCoverage feeding RetentionPolicies). So a plan whose last execution was 5 to 14 days ago cannot serve as the baseline. That is exactly the case the 14-day window was written for: a query that ran well on plan A last week, switched to plan B four days ago, and has run only on B since, is never reported, because plan A's rows are purged.

Don't fix this as a side effect of anything. Either direction changes findings, so the choice belongs to the maintainer.

How this was established

The window's real length depends on the store

store raw query_store_stats retained what "14 days" actually reads
Darling, purges armed (the healthy steady state) 4 days (+ up to 1 chunk) ~4-5 days
Darling, raw purges held (the #1759 profile, until backfill) unbounded 14 days
Darling on plain PostgreSQL (no TimescaleDB, so no retention policy) unbounded 14 days
Lite (CollectorScheduleDefaults["query_store"] = 30-day retention, plus the parquet archive) 30 days 14 days

So the same detector answers a different question depending on the store's retention state, and Darling and Lite disagree on the same data.

The decision

  1. Make the window truly 14 days on Darling. That needs a source that retains 14 days of per-interval Query Store data. The latest-snapshot-per-interval table proposed in PLAN_REGRESSION's read deduplicates the whole raw Query Store slice every pass; keep the latest snapshot per interval as it is written #3953 could carry a 15-day horizon at interval-count cost; raising raw query_store_stats retention would multiply the store's largest QS hypertable by about 3.5. Findings change: more regressions, reported against baselines up to two weeks old.
  2. Document it as about 4 days, and set PlanRegressionWindowDays (and the drill-down's literal 14) to the raw horizon so the code says what it does. On stores with armed purges, findings are unchanged. On held-purge and plain-PG stores, findings change (fewer), and so do Lite's if Lite follows for parity.
  3. Leave it as is, with the store-dependent behaviour written down where the window is declared.

Related

Activity

  1. erikdarlingdata commented on Sep 23, 2026

    @erikdarlingdata
    OwnerAuthor

    Ruled (Erik, 2026-09-23): option 1. Make the window truly 14 days, through #3953's latest-snapshot-per-interval table with a 15-day horizon. Raising raw query_store_stats retention (about 3.5x) is not the route. Expect more PLAN_REGRESSION findings once this lands; catching those is what the detector is for. The work is sequenced after Thursday's release, with an adversarial design review before any code (see #3953).

  2. erikdarlingdata commented on Sep 23, 2026

    @erikdarlingdata
    OwnerAuthor

    Decided (Erik, 2026-09-23): option 1. The window becomes truly 14 days through #3953's table with a 15-day horizon. The implementation is tracked in #3953, so this decision issue closes.

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

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions