Skip to content

feat: limit recent queries - #5682

Merged
javiermolinar merged 55 commits into
grafana:mainfrom
javiermolinar:limit-recent-queries
Nov 3, 2025
Merged

feat: limit recent queries#5682
javiermolinar merged 55 commits into
grafana:mainfrom
javiermolinar:limit-recent-queries

Conversation

@javiermolinar

@javiermolinar javiermolinar commented Sep 26, 2025

Copy link
Copy Markdown
Contributor

What this PR does:
This PR addresses an issue where queries using recent timestamps (especially "now") can return inaccurate or inconsistent results due to laggy replicas and incomplete data ingestion.

A new middleware operates transparently between the API layer and the queriers, ensuring that external interfaces remain unchanged while internal request processing becomes more robust and consistent.

This change ensures that Tempo queries return consistent, accurate results by avoiding the "dangerous zone" of very recent data that may be incomplete across replicas, while standardizing how time ranges are handled throughout the query pipeline.

Problem

When search and metrics queries use very recent end times (like time.Now()), they can hit incomplete data because:

  • Laggy replicas: Some replicas may not have received the most recent data yet
  • Ingestion delays: Data is still being processed and may not be immediately available
  • Inconsistent results: Different replicas return different results for the same query

This leads to unreliable query results.

Solution

Introduces configurable time for clamping the end range:

  • query_end_cutoff,: Prevents queries from using end times too close to "now" (defaults to 30s)

Key Behavioral Changes

  1. All requests now include explicit start/end parameters: Previously, requests without time ranges would be forwarded to queriers as-is. Now, the frontend middleware ensures every request to queriers includes clamped start and end parameters.

  2. "since" parameter handling: The search API's since parameter (e.g., since=1h) is now processed by the frontend and converted to explicit start and end parameters before forwarding to queriers

  3. GRPC requests with empty start/end: GRPC requests that previously had default/empty start and end times are now resolved to explicit timestamp values during the clamping process, ensuring consistent behavior across all query types.

Implementation Details

  • Pipeline Middleware: NewAdjustStartEndWare applies clamping to all incoming requests before they reach queriers
  • Parameter Normalization: All relative time parameters (since) are converted to absolute timestamps

Test Updates

Updated integration tests to account for the new clamping behavior:

  • Explicit Time Ranges: Tests now specify explicit start/end times instead of relying on defaults
  • Proper Buffers: Added time buffers in tests to avoid hitting the clamped regions
  • Timing Fixes: Resolved flaky tests caused by queries hitting incomplete recent data

Breaking Changes

None. This change is fully backward compatible:

  • Client APIs: Still accept the same parameters (including since) - the processing is internal
  • Querier Interfaces: Still receive the same parameter types, just with guaranteed populated values instead of potentially empty ones
  • GRPC/HTTP APIs: All existing endpoints work exactly the same from a client perspective

Not a single line of business logic has changed

Checklist

  • Tests updated
  • Documentation added
  • CHANGELOG.md updated - the order of entries should be [CHANGE], [FEATURE], [ENHANCEMENT], [BUGFIX]
joe-elliott and others added 3 commits September 18, 2025 13:51
Comment thread modules/frontend/frontend.go Outdated
javiermolinar and others added 5 commits October 7, 2025 16:20
Co-authored-by: Joe Elliott <joe.elliott@grafana.com>
Co-authored-by: Joe Elliott <joe.elliott@grafana.com>
default to the query_backend_after
@javiermolinar

Copy link
Copy Markdown
Contributor Author

@joe-elliott I was able to make it work without the extra config DefaultQueryStart in fact I've simplified most of the tests configs. Could you take it another look?

@joe-elliott joe-elliott left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

PR looking good close to merging. Can we go ahead and make the config change now? Also needs a changelog.

Comment thread modules/frontend/frontend.go Outdated
return nil, fmt.Errorf("QueryBackendAfter (%v) must be greater than query end cutoff (%v)", cfg.Search.Sharder.QueryBackendAfter, cfg.QueryEndCutoff)
}
if cfg.QueryEndCutoff > cfg.Metrics.Sharder.QueryBackendAfter {
return nil, fmt.Errorf("QueryBackendAfter (%v) must be greater than query end cutoff (%v)", cfg.Metrics.Sharder.QueryBackendAfter, cfg.QueryEndCutoff)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

same check 2x? remove the second one?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

It´s not really duplicated since the QueryBackendAfter can be different for search and metrics. Nevertheless we already discussed moving this property up. I will remove the second one

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

oh, good call. i didn't notice. i'm good with the double check

@joe-elliott joe-elliott left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

one cleanup request, but looks good otherwise

@javiermolinar
javiermolinar merged commit bca3051 into grafana:main Nov 3, 2025
37 of 38 checks passed
ruslan-mikhailov pushed a commit to ruslan-mikhailov/tempo that referenced this pull request Nov 4, 2025
* add adjustRangeWare

Signed-off-by: Joe Elliott <number101010@gmail.com>

* improve code and added more tests

* fixes in the tests

* remove strict validation for now

* move the logic to the frontend

* fix integration tets

* add values explicitly

* fix query range tests

* fix unit tests

* fix more tests

* fix more tests

* disable for tags

* revert last commit

* do not apply when the start and end are missing for now

* try to fix more tests

* fix more tests

* fix more tests

* fix more tests

* bring back empty start end handling

* fix more tests

* fix multitenant tests

* fix https test

* fix api tests

* fix deployment tests

* simplify tests

* fix query range test

* fix another test

* remove commented code

* disable test

* fix search propagates

* fix search shard test

* fix another test

* last one?

* test querybackend after

* Update modules/livestore/config.go

Co-authored-by: Joe Elliott <joe.elliott@grafana.com>

* Update modules/frontend/frontend.go

Co-authored-by: Joe Elliott <joe.elliott@grafana.com>

* fmt

* Remove the new default start query parameter and
default to the query_backend_after

* remove precission since its not used

* cleanup test configs

* move config one level up

* changelog

* remove validation

* defaulted to 0

* manifest

* add more cutoff

---------

Signed-off-by: Joe Elliott <number101010@gmail.com>
Co-authored-by: Joe Elliott <number101010@gmail.com>
Co-authored-by: Joe Elliott <joe.elliott@grafana.com>
mattdurham pushed a commit to mattdurham/tempo that referenced this pull request Jun 18, 2026
* add adjustRangeWare

Signed-off-by: Joe Elliott <number101010@gmail.com>

* improve code and added more tests

* fixes in the tests

* remove strict validation for now

* move the logic to the frontend

* fix integration tets

* add values explicitly

* fix query range tests

* fix unit tests

* fix more tests

* fix more tests

* disable for tags

* revert last commit

* do not apply when the start and end are missing for now

* try to fix more tests

* fix more tests

* fix more tests

* fix more tests

* bring back empty start end handling

* fix more tests

* fix multitenant tests

* fix https test

* fix api tests

* fix deployment tests

* simplify tests

* fix query range test

* fix another test

* remove commented code

* disable test

* fix search propagates

* fix search shard test

* fix another test

* last one?

* test querybackend after

* Update modules/livestore/config.go

Co-authored-by: Joe Elliott <joe.elliott@grafana.com>

* Update modules/frontend/frontend.go

Co-authored-by: Joe Elliott <joe.elliott@grafana.com>

* fmt

* Remove the new default start query parameter and
default to the query_backend_after

* remove precission since its not used

* cleanup test configs

* move config one level up

* changelog

* remove validation

* defaulted to 0

* manifest

* add more cutoff

---------

Signed-off-by: Joe Elliott <number101010@gmail.com>
Co-authored-by: Joe Elliott <number101010@gmail.com>
Co-authored-by: Joe Elliott <joe.elliott@grafana.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

4 participants