Search code examples
prometheuspromql

Why range vector selector cannot be applied in nested fashion (fails with error)


Range vector selector [1d] used on top of a result e.g rate(xyz[5m]) fails.

Let us suppose we need to find maximum request rate of a service over a time period fails with the error message bad_data: parse error: ranges only allowed for vector selectors

max_over_time(
  rate(
    istio_requests_total{service=~"cms"}[5m]
  )[1d] 
)

Solution

  • The problem is that request rate rate(istio_requests_total{service=~"cms"}[5m]) is not a raw value (value stored in TSDB), it is a derived value (result generated of a query). Range vector selector like [1d] selects ranges of time directly from TSDB.

    Option #1: You need to use prometheus subquery ([<duration>:<resolution>]) which allows you to run a range query (at specified or default resolution) on the subquery result. So use subquery as below

    max_over_time(
      rate(
        istio_requests_total{service=~"cms"}[5m]
      )[1d:] 
    )
    

    Option #2: The other option is to use recording rule for the rate expression rate(istio_requests_total{service=~"cms"}[5m]) and then use max_over_time(<recording_rule_rate_expression>[1d]).

    Usually subqueries are costly the creating a recording rule for inner query is good idea.