Skip to content

Align yrate/yincrease/ydelta with Prometheus 3.x (start, end] semantics - #20

Open
ColinDKelley wants to merge 2 commits into
invoca-2.55.1/add-yratefrom
invoca-2.55.1/align-yrate-to-3x-range-boundary
Open

Align yrate/yincrease/ydelta with Prometheus 3.x (start, end] semantics#20
ColinDKelley wants to merge 2 commits into
invoca-2.55.1/add-yratefrom
invoca-2.55.1/align-yrate-to-3x-range-boundary

Conversation

@ColinDKelley

@ColinDKelleyColinDKelley commented Apr 19, 2026

Copy link
Copy Markdown

Summary

Flip the yrate family (yrate / yincrease / ydelta) range convention from [start, end) to (start, end] so that a sample whose timestamp lands exactly on a range boundary is attributed to the later range, never to both or neither.

Stacked on top of #22 (invoca-2.55.1/add-yrate).

Why now

Prometheus 3.x standardized on (start, end] for PromQL range selectors (see prometheus/prometheus#13213). This PR pre-aligns our yrate family with that convention so that when we eventually merge up to 3.x, yrate keeps producing the "right" answer under the same semantics the rest of the engine uses.

The xrate family, whose legacy [start, end] convention predates this decision, is deliberately untouched — its showcase tests exist to document that legacy behavior.

What changes

  • promql/functions.go: yIncrease loop now iterates t <= rangeEndMsec and treats t > rangeStartMsec as "in range". Docstrings on yIncrease and rangeFromSelectors updated with the new convention and a reference to upstream promql: Make range selections left-open and right-closed prometheus/prometheus#13213.
  • promql/promqltest/testdata/functions.test: three expected values in the "Comparison of rate vs xrate" showcase change — the only test cases in the repo that intentionally evaluate on boundary-aligned timestamps (25s and 75s with a 5s collection cadence).
evalmetricoldnewwhy
25s/bar0.10.12sample at t=25 (value 6) now in range
75s/foo0.060.02sample at t=25 (value 2) now attributed as "last before range"
75s/bar0.220.1same: sample at t=25 (value 6) now used as lastBeforeRange

All other yrate test cases — the big 1000+/2000+ block, the counter-reset block, and the ydelta block — use shifted eval times (49s, 29m, 24m, 19m) specifically to avoid boundary alignment, and are unchanged.

The linearity property yIncrease(p0) + yIncrease(p1) == yIncrease(p0 + p1) is preserved under the new semantics.

Test plan

  • go build ./... (clean)
  • go test -count=1 ./promql/... (all green, including showcase and ported 2.39.2 cases)
  • After merge, remove the matching branches/PRs on invoca-2.53.1 once this series supersedes them

@ColinDKelley
ColinDKelley changed the base branch from invoca-2.55.x/add-yrate to invoca-2.55.1/add-yrateApril 19, 2026 01:35
@ColinDKelleyColinDKelley changed the title Align yrate/yincrease/ydelta with Prometheus 3.x range semanticsAlign yrate/yincrease/ydelta with Prometheus 3.x (start, end] semanticsJul 8, 2026
@ColinDKelley
ColinDKelley marked this pull request as ready for review July 8, 2026 23:14
@ColinDKelley
ColinDKelleyforce-pushed the invoca-2.55.1/align-yrate-to-3x-range-boundary branch from 4bf7c40 to fc4e2f3CompareJuly 8, 2026 23:16
@ColinDKelley
ColinDKelleyforce-pushed the invoca-2.55.1/add-yrate branch from f9a1dbd to 9483ce1CompareJuly 9, 2026 22:27
@ColinDKelley
ColinDKelleyforce-pushed the invoca-2.55.1/align-yrate-to-3x-range-boundary branch 4 times, most recently from ac82c0a to 366ca82CompareJuly 10, 2026 00:22
ColinDKelleyand others added 2 commits July 9, 2026 19:25
Flip the yrate-family range convention from [start, end) to (start, end]
so that a sample whose timestamp lands exactly on a range boundary is
attributed to the later range, never to both or neither.
This matches the convention adopted upstream in Prometheus 3.x
(see prometheus#13213). The xrate family, whose legacy
[start, end] convention predates this decision, is unaffected.
Behavior change is confined to samples that land precisely on a range
boundary; all existing yrate test cases use shifted eval times to avoid
boundary alignment, so only the "Comparison of rate vs xrate" showcase
(which intentionally evaluates on boundaries at 25s and 75s) observes a
difference. The linearity property yIncrease(p0) + yIncrease(p1) ==
yIncrease(p0 + p1) is preserved under the new semantics.
Made-with: Cursor
Three values in the "Comparison of rate vs xrate" showcase change under
the new yrate range convention, all on boundary-aligned evals:
eval 25s yrate[50s] /bar: 0.1 -> 0.12 (sample at t=25 now in range)
eval 75s yrate[50s] /foo: 0.06 -> 0.02 (sample at t=25 now attributed
eval 75s yrate[50s] /bar: 0.22 -> 0.1 to the prior range)
These changes are the intended effect of attributing a boundary sample
to the later range rather than the earlier one. All other yrate/
yincrease/ydelta cases (big 1000+/2000+ block, counter-reset block,
ydelta block) use shifted eval times and are unaffected.
Made-with: Cursor
Co-authored-by: Cursor <cursoragent@cursor.com>
@ColinDKelley
ColinDKelleyforce-pushed the invoca-2.55.1/add-yrate branch from bf2d555 to 8dba4ffCompareJuly 10, 2026 02:27
@ColinDKelley
ColinDKelleyforce-pushed the invoca-2.55.1/align-yrate-to-3x-range-boundary branch from 366ca82 to 8e94af7CompareJuly 10, 2026 02:27
Sign up for freeto 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

@ColinDKelley