Prometheus' 2.54.0 release added experimental support for using duration literals interchangeably with number literals in PromQL. Here's what this means and why it's useful.
Number and duration literals
Number literals in PromQL are simply spelled-out numeric floating point values such as 5
, 1.23
, 0xef
, or Inf
. Number literals are their own PromQL syntax tree node and thus represent a full PromQL (sub)expression. In practice, you usually see them being used in the context of binary operators or as function parameters. Let's look at a few examples.
Number literal examples
You could use a number literal as the first parameter to the topk()
aggregator to show the top 3 request rates:
topk(3, rate(http_requests_total[5m]))
You could also use number literals to convert a set of memory usages in bytes to mebibytes (MiB) and then only return the time series that represent usages greater than 20 MiB:
memory_usage_bytes / 1024^2 > 20
Duration literal examples
Duration literals are specifiers such as 5m
(5 minutes) or 1h5m30s
(1 hour, 5 minutes, and 30 seconds) that you allow you to select the desired duration for an operation. Up until now, duration literals couldn't be used as a standalone PromQL expression and were only allowed in special places of the PromQL syntax.
For example, as the data selection duration of a range vector selector:
http_requests_total[5m]
Or as the time-shifting duration parameter of an offset
modifier:
memory_usage_bytes offset 1w
Or as the range and resolution parameters of a subquery:
max_over_time(
rate(
http_requests_total[5m]
)[1d:15s] # Run the subquery over a 1-day range with a 15-second resolution.
)
Usability problem: Some numbers are semantically durations
However, there are cases in PromQL where number literals are semantically durations (usually in seconds), but where the PromQL syntax didn't allow you to use a duration literal syntax. Let's look at two prominent examples:
The second parameter of the predict_linear()
function is semantically a duration in seconds, telling the function how far into the future it should extrapolate a set of gauge values:
# Predict the value in 24 hours, based on the behavior of the last 4 hours.
predict_linear(disk_usage_bytes[4h], 24 * 60 * 60)
You may also want to compare one duration with another. For example, you could query for all hosts that have been running for more than 30 days:
time() - node_boot_time_seconds > 30 * 24 * 60 * 60
As you can see, having to write out durations in seconds like this can become cumbersome and error-prone.
The solution: Making number and duration literals interchangeable
Starting with Prometheus version 2.54.0, Darshan Chaudhary has added experimental support for using duration literals in place of numbers, and vice versa. The support is enabled by default, but may still change due to its experimental nature. As Prometheus generally advises keeping metrics in base units, and numeric durations also occur most commonly in seconds in PromQL, a given duration literal now translates into an equivalent number of seconds when used as a PromQL expression.
So the following are now equivalent in PromQL:
1s
and1
5m
and300
or5 * 60
10ms
and0.01
This means you can now write the above duration expressions more naturally:
predict_linear(disk_usage_bytes[4h], 24h)
And:
time() - node_boot_time_seconds > 30d
As a result, PromQL expressions involving numeric numbers will now be easier to write and understand.
Note: In Prometheus 2.54.0, the UI will still show a linter error for duration literals used as numeric PromQL expressions and not highlight them properly yet:
This has already been fixed in a followup Pull Request by Augustin Husson and should be working fine in the next Prometheus release.
Since the two syntactical elements are now interchangeable, you could even use a number as a duration now, like:
rate(http_requests_total[300])
However, this is generally not going to be as useful as the reverse case.
Note also that binary operations such as 1d * 30
are still only possible in places where the duration literal represents a full PromQL expression. So you still would not be able to query for something like memory_usage_bytes[1d * 30]
, since the contents of the square brackets are syntactically part of a range vector selector and not a full PromQL expression that can be multiplied with another number.
Conclusion
As we've seen, the new support in Prometheus 2.54.0 for treating number literals and duration literals interchangeably will make PromQL use cases involving numeric durations much more natural to read and write.
If you want to understand more about Prometheus and PromQL, you may also want to take a look at our Prometheus training courses, especially our Understanding PromQL training.
Comments powered by Talkyard.