Skip to content

fix(query-engine): charts span the service pages' longest presets - #2325

Open
Makisuo wants to merge 1 commit into
mainfrom
fix/timeseries-range-ceiling
Open

Makisuo wants to merge 1 commit into
mainfrom
fix/timeseries-range-ceiling

Conversation

@Makisuo

@Makisuo Makisuo commented Nov 7, 2026 •

Copy link
Copy Markdown
Collaborator

Problem

The services list, service detail, service map and releases pages offer time presets up to 12 months, but the query engine refused every /execute timeseries over 31 days. The services table waits on its sparklines, so picking a long range showed "Couldn't load services / Time range too large":

  • 3mo, 6mo and 12mo always failed.
  • "Last 1 month" failed too whenever the calendar month was 31 days and crossed a DST change (Oct 7 to Nov 7 this year is 31 days plus an hour).

Fix

  • New MAX_TIMESERIES_RANGE_SECONDS (367 days: a calendar year, a leap day and a DST hour). maxRangeSecondsForKind("timeseries") returns it.
  • validateExecute applies it to timeseries and to the services facets, which read the 365-day service overview rollups. Every other kind keeps the 31-day ceiling, and lists (7d) and breakdowns (30d) keep their own.
  • Raw spans and logs have a 30-day TTL, so a long timeseries that cannot use a rollup still scans at most about 30 days of raw data.
  • The public v2 timeseries endpoints still document and enforce 31 days. That is unchanged.

Verification

  • New tests in QueryEngineService.test.ts: a 12-month (plus DST hour) grouped all-metrics timeseries runs, and a 3-month breakdown is still refused with "Time range too large".
  • QueryEngineService.test.ts (47) and limits.test.ts (11) pass. packages/query-engine typecheck is clean.

No UI change, so there are no screenshots.

🤖 Generated with Claude Code


Autofix with [code]smith
Open in [code]smith · Need help on this PR? Tag @codesmith-bot with what you need.

The services, service detail, service map and releases pages offer presets up
to 12 months, but every timeseries through /execute was refused past 31 days.
The services table waits on its sparklines, so 3mo/6mo/12mo (and 1mo across a
DST change) showed "Couldn't load services / Time range too large".

Timeseries and the services facets read the 365-day rollups, so they now get a
367-day ceiling. Lists, breakdowns and other kinds keep theirs.
@coderabbitai

coderabbitai Bot commented Nov 7, 2026

Copy link
Copy Markdown

Warning

Review limit reached

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Next included review available in 22 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used all 4 included reviews currently available.

Learn how review limits work.

Review configuration:

Run configuration

  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 3fd33ce5-a67e-4abf-9586-a27dbd1c2f68
Commits

Reviewing files that changed from the base of the PR and between e6907cf and 032ac1d.

Files selected for processing: 3

  • packages/backend/src/services/warehouse/QueryEngineService.test.ts
  • packages/query-engine/src/limits.ts
  • packages/query-engine/src/runtime/query-engine.ts
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

Share

@maple-review-bot

maple-review-bot Bot commented Nov 7, 2026 •

Copy link
Copy Markdown

Maple review

🟡 Confidence 6/10 · needs attention. Held at 6 because a performance warning is open.
1 warning −1 · 1 note · tests partial −1 · risk medium

Gives timeseries charts a 367-day ceiling so the service pages' 12-month presets stop failing, and shares it with the services facets. The widening also reaches sources with no year-long rollup (metrics_*, product_events), which now accept raw scans that were previously refused.

  • MAX_TIMESERIES_RANGE_SECONDS (367 days) replaces the 31-day ceiling for timeseries
  • validateTimeRange takes a maxRangeSeconds argument defaulting to the general ceiling
  • Services facets get the wide ceiling through executeRangeCeiling
  • Alerts and the public v2 endpoints keep 31 days

Findings

🟠 Warning · F1 · executeRangeCeiling widens timeseries over raw metrics and product_events

performance · packages/query-engine/src/runtime/query-engine.ts:850-852

Every timeseries now passes the 367-day ceiling, but only traces reads a 365-day rollup. A 12-month window over metrics_* (90-day retention) or product_events (365-day fact table, queried raw) used to fail fast and now scans up to a year of rows in one query. The limits comment claiming rollup-less sources keep 30 days does not hold for either.

Gate the wider ceiling on the timeseries sources that read a 365-day rollup (e.g. `query.source === "traces"` plus the services facets) and leave `metrics`, `logs` and `product_events` on `MAX_QUERY_RANGE_SECONDS`.
🔵 Note · F2 · facets/services half of executeRangeCeiling has no test

tests · packages/query-engine/src/runtime/query-engine.ts:850

The added tests cover a 12-month timeseries and a 3-month breakdown. Nothing pins the second arm of this condition: that the services facet rail is allowed a year while facets on traces, logs and errors stays at 31 days, which the services list page now depends on.

Add a case executing `{ kind: "facets", source: "services" }` over 12 months, and one keeping `{ kind: "facets", source: "traces" }` at the general ceiling.
🤖 Prompt to fix all 2 findings with an AI agent
Findings from an automated review of commit 032ac1d9d8860392532636b2c7fcdbaef9dbead8. Verify each one against the current code before changing anything, fix only those that still apply, and keep each fix to the lines it names.

---

F1 · Warning · performance · packages/query-engine/src/runtime/query-engine.ts:850-852
`executeRangeCeiling` widens timeseries over raw `metrics` and `product_events`
Every timeseries now passes the 367-day ceiling, but only `traces` reads a 365-day rollup. A 12-month window over `metrics_*` (90-day retention) or `product_events` (365-day fact table, queried raw) used to fail fast and now scans up to a year of rows in one query. The limits comment claiming rollup-less sources keep 30 days does not hold for either.
Suggested fix: Gate the wider ceiling on the timeseries sources that read a 365-day rollup (e.g. `query.source === "traces"` plus the services facets) and leave `metrics`, `logs` and `product_events` on `MAX_QUERY_RANGE_SECONDS`.

---

F2 · Note · tests · packages/query-engine/src/runtime/query-engine.ts:850
`facets`/`services` half of `executeRangeCeiling` has no test
The added tests cover a 12-month timeseries and a 3-month breakdown. Nothing pins the second arm of this condition: that the services facet rail is allowed a year while `facets` on traces, logs and errors stays at 31 days, which the services list page now depends on.
Suggested fix: Add a case executing `{ kind: "facets", source: "services" }` over 12 months, and one keeping `{ kind: "facets", source: "traces" }` at the general ceiling.

032ac1d · What was checked, coverage and telemetry details are on the Maple / review check. Reply "won't fix" to dismiss a finding, or mention @maple-review-bot to ask about one.

@maple-review-bot maple-review-bot Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 inline note from Maple's review. The score and summary are in the review comment above.


/** Timeseries and the services facets read the 365-day rollups; everything else gets the general ceiling. */
const executeRangeCeiling = (query: QuerySpec): number =>
query.kind === "timeseries" || (query.kind === "facets" && query.source === "services")

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Warning

executeRangeCeiling widens timeseries over raw metrics and product_events

F1 · Warning · performance

Every timeseries now passes the 367-day ceiling, but only traces reads a 365-day rollup. A 12-month window over metrics_* (90-day retention) or product_events (365-day fact table, queried raw) used to fail fast and now scans up to a year of rows in one query. The limits comment claiming rollup-less sources keep 30 days does not hold for either.

Gate the wider ceiling on the timeseries sources that read a 365-day rollup (e.g. `query.source === "traces"` plus the services facets) and leave `metrics`, `logs` and `product_events` on `MAX_QUERY_RANGE_SECONDS`.
🤖 Prompt to fix with an AI agent
In `packages/query-engine/src/runtime/query-engine.ts:850-852`: `executeRangeCeiling` widens timeseries over raw `metrics` and `product_events`.

Every timeseries now passes the 367-day ceiling, but only `traces` reads a 365-day rollup. A 12-month window over `metrics_*` (90-day retention) or `product_events` (365-day fact table, queried raw) used to fail fast and now scans up to a year of rows in one query. The limits comment claiming rollup-less sources keep 30 days does not hold for either.

Suggested fix: Gate the wider ceiling on the timeseries sources that read a 365-day rollup (e.g. `query.source === "traces"` plus the services facets) and leave `metrics`, `logs` and `product_events` on `MAX_QUERY_RANGE_SECONDS`.

Verify the problem exists at that location before changing it, and keep the fix to those lines.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant