My question is this how rate will get calculated(my understanding is correct)?

Theoretically, it is correct (except in your example you have 6 datapoints, not 5). But the "magic" starts happening when you add start and end params to your query. In most cases, these two params will not exactly match t1 and t5 from your example, and Prometheus won't be able to capture one or more data points of yours:

In the example above, time window isn't perfectly aligned with real values. In this case, value of v1 will be missed, which would affect the result since increase will be calculated between v5 and v2. Knowing the avg interval between received values, Prometheus could assume that it didn't capture some of the values. So it will try to extrapolate the result by simply multiplying it by coefficient.

I'd recommend reading this great thread https://github.com/prometheus/prometheus/issues/3746.

I'd also recommend reading how alternative rate could work here https://medium.com/@romanhavronenko/victoriametrics-promql-compliance-d4318203f51e in "Better rate" section. Disclosure, I am one of the developers at VictoriaMetrics, so take it with a grain of salt.

Answer from hagen1778 on Stack Overflow
🌐
Google Groups
groups.google.com › g › prometheus-users › c › qmutsg1c55g
Increase without extrapolation
It basically computes the increase over 6 successive collections (7 successive points), then undoes the extrapolation. Ugly and requires you to take into account both collection and evaluation intervals (and hope they never change), but it works. This is not resilient to jitter, and is not ...
🌐
Google Groups
groups.google.com › g › prometheus-users › c › _aK7im7elUs
Why does increase() return fractional results for integer-valued metrics?
Prometheus extrapolates `increase()` results - see https://github.com/prometheus/prometheus/issues/3746 for more details. There is an implementation, which returns exact results from increase() without extrapolation - https://victoriametrics.github.io/MetricsQL.html .
Discussions

rate()/increase() extrapolation considered harmful
The problem [Feel free to skip ahead to the proposed solution, as I'm guessing the problem is widely understood. Or just read the last couple of paragraphs for a real-life example of the proble... More on github.com
🌐 github.com
56
January 26, 2018
Prometheus Counters - and how to deal with them
Very nice article. As you can see above, the result Prometheus returns is more exact than the one that we came up with, but it’s still not the right value (we know because of the controlled environment we set up). One thing I'd like to point out is the Prometheus extrapolation is more accurate overall, especially when aggregating things that move at a high rate. The trick is, if you're using sum() to add up rate()/increase() for several endpoints, you need the interpolated values to produce the most accurate total. Say you have these samples from a job of 3 targets with a scrape interval of 15 seconds. foo{i="A"} 0 @0.1 foo{i="B"} 0 @5.6 foo{i="C"} 0 @12.8 foo{i="A"} 5 @15.1 foo{i="B"} 2 @20.6 foo{i="C"} 14 @27.8 If you query at T=30 with an sum(increase(foo[30s])), interpolation is needed to align all the timestamps and values. It's important because Prometheus tracks data with float64 values, timestamps in milliseconds. The millisecond you submit a query is actually important as part of the calculation if you're using the default /graph interface. If you're using Grafana, they snap the timestamps based on the graph window range and the step interval configured. This is how Grafana avoids graph jitter when refreshing. Everything is aligned to 15 seconds. This would be more easily visualized with a picture, probably something useful to add to your article. EDIT: Another fun fact, you can change the ordering of by/without. It makes it nice when you want to break up a long query shorten the line length. For example: sum by (country) ( increase(orders_created_total[5m]) ) More on reddit.com
🌐 r/PrometheusMonitoring
2
7
May 20, 2019
increase() in Prometheus sometimes doubles values: how to avoid? - Stack Overflow
That's an increase of 1 over 2 minutes, which extrapolated over 4 minutes is an increase of 2 - which is as expected. Any metrics-based monitoring system will have similar artifacts, if you want 100% accuracy you need logs. ... Sign up to request clarification or add additional context in comments. ... This statement "Any metrics-based monitoring system will have similar artifacts, if you want 100% accuracy you need logs." Is factually incorrect, not only is this unique to Prometheus ... More on stackoverflow.com
🌐 stackoverflow.com
Why does increase() return a value of 1.33 in prometheus? - Stack Overflow
Prometheus developers are going to fix these issues - see this design doc. In the mean time try VictoriaMetrics - its increase() function properly returns the expected integer result without any extrapolation over integer counters. More on stackoverflow.com
🌐 stackoverflow.com
🌐
GitHub
github.com › prometheus › prometheus › issues › 3746
rate()/increase() extrapolation considered harmful · Issue #3746 · prometheus/prometheus
January 26, 2018 - Second, there is another workaround that only works for increase(foo[10s]), namely using foo - foo offset 10s. But there are a couple of problems with this approach: it doesn't handle counter resets and it's twice as slow because now Prometheus looks up foo twice.
Author: prometheus
🌐
DoiT
doit.com › home › blog › making peace with prometheus rate()
Making peace with Prometheus rate() | DoiT
February 17, 2023 - To get the increase over 60 seconds, we ask P8s to calculate one for 75 seconds (with that extra sample that usually falls between the buckets). Of course, Prometheus will extrapolate it to 75 seconds but we de-extrapolate it manually back to 60 and now our charts are both precise and provide us with the data one whole-minute boundaries as well.
🌐
Reddit
reddit.com › r/prometheusmonitoring › prometheus counters - and how to deal with them
r/PrometheusMonitoring on Reddit: Prometheus Counters - and how to deal with them
May 20, 2019 - If you query at T=30 with an sum(increase(foo[30s])), interpolation is needed to align all the timestamps and values. It's important because Prometheus tracks data with float64 values, timestamps in milliseconds.
🌐
Mail Archive
mail-archive.com › search
subject:"Re\: \[prometheus\-users\] Why does increase\(\) return fractional results for integer\-valued metrics\?"
Regards > > John > > On Mon, 22 Mar 2021 at 16:45, Aliaksandr Valialkin > wrote: > > > Prometheus extrapolates `increase()` results - see > > https://github.com/prometheus/prometheus/issues/3746 for more details. > > There is an implementation, which returns exact results from increase() > > without extrapolation - https://victoriametrics.github.io/MetricsQL.html .
Top answer
1 of 3
44

This is known as aliasing and is a fundamental problem in signal processing. You can improve this a bit by increasing your sample rate, a 4m range is a bit short with a 2m range. Try a 10m range.

Here for example the query executed at 1515722220 only sees the [email protected] and [email protected] samples. That's an increase of 1 over 2 minutes, which extrapolated over 4 minutes is an increase of 2 - which is as expected.

Any metrics-based monitoring system will have similar artifacts, if you want 100% accuracy you need logs.

2 of 3
21

increase() will always (approximately) double the actual increase with your setup.

The reason is that (as currently implemented):

  1. increase() is (as you observed) syntactic sugar for rate() i.e. it is the value that would be returned by rate() multiplied by the number of seconds in the range you specified. In your case, it is rate() * 240.
  2. rate() uses extrapolation in its computation. In the vast majority of cases a 4 minute range will return exactly 2 data points, almost exactly 2 minutes apart. The rate is then computed as the difference between last and first (i.e. the 2 points in your case) divided by the time difference of the 2 points (around 120 seconds in 99.99% of cases) multiplied by the range you requested (exactly 240 seconds). So if the increase between the 2 points is zero, the rate is zero. If the increase between the 2 points is 1.0, the computed rate() will be close to 2.0 / 240 and, as a result, the increase() will be 2.0.

This approach works mostly fine with counters that increase smoothly (e.g. if you have a more or less fixed number of signups every 2 minutes). But with a counter that rarely increases (as does your signups counter) or a spiky counter (like CPU usage) you get weird overestimates (like the increase of 2 you are seeing).

You can essentially reverse engineer Prometheus' implementation and get (something very close to) the actual increase by multiplying with (requested_range - scrape interval) and dividing by requested_range, essentially walking back the extrapolation that Prometheus does.

In your case, this would mean

increase(signups_count[4m]) * (240 - 120) / 240

or, more succinctly,

increase(signups_count[4m]) / 2

It requires you to be aware both of the length of the range and the scrape interval, but it will give you what you want: "ones for ones, and twos for twos, most of the time". Sometimes you'll get 1.01 instead of 1.0 because the scrapes were 119 seconds, not 120 seconds apart and sometimes, if your evaluation is closely aligned with the scrape some points right on the boundary might be included or not in a data point calculation, but it's still a better answer than 2.0.

Find elsewhere
🌐
GitHub
github.com › prometheus › prometheus › pull › 1161 › files
promql: Remove extrapolation from rate/increase/delta. by brian-brazil · Pull Request #1161 · prometheus/prometheus
This is an improvement from both a theoretical and practical standpoint. Theory: For simplicty I'll take the example of increase(). Counters are fundamentally lossy, if there's a counter reset or instance failure between one scrape and the next ...
Author: prometheus
Top answer
1 of 2
22

The challenge with calculating this number is that we only have a few data points inside a time range, and they tend not to be at the exact start and end of that time range (1 minute here). What do we do about the time between the start of the time range and the first data point, similarly the last data point and the end of the range?

We do a small bit of extrapolation to smooth this out and produce the correct result in aggregate. For very slow moving counters like this it can cause artifacts.

2 of 2
8

Prometheus calculates increase(foo_requests_total[1m]) at a timestamp t in the following way:

  1. It selects all the raw samples per each time series with foo_requests_total name on the time range (t-1m ... t]. Note that samples at the timestamp t-1m aren't included in the selection, while samples at the timestamp t are included in the selection.
  2. It calculates the difference d between the last and the first raw sample on the selected time range (Prometheus may also remove possible counter resets, but let's skip this step for the sake of clarity).
  3. It extrapolates the calculated difference d if the first and/or the last raw sample are located too far from the bounds of the selected time range.

The last step may result in fractional increase() values over integer counters as seen in the original question. See this issue for more details. Note also that increase() in Prometheus misses the difference between the first raw sample on the selected time range and the previous sample before the selected time range. This may result in smaller than expected increase() results.

Prometheus developers are going to fix these issues - see this design doc. In the mean time try VictoriaMetrics - its increase() function properly returns the expected integer result without any extrapolation over integer counters.

🌐
GitHub
github.com › prometheus › prometheus › issues › 15976
PromQL(histograms): Prevent extrapolation below zero · Issue #15976 · prometheus/prometheus
February 5, 2025 - Ideally rate(requests_total[5m]) and histogram_count(rate(request_duration_seconds[5m])) will yield precisely the same result. However, due to not blocking extrapolation below zero, the rate calculated through NHs can be higher.
Author: prometheus
🌐
Google Groups
groups.google.com › g › prometheus-users › c › PZ-fnZxSpOk
looks like rate/irate/delta/increase are not calculating consistent
January 28, 2021 - There is only one counter value increase (by one) within the window. All values are known and in the past. Also the window with 1m is larger then the series interval so there is no extrapolation needed but i would understand interpolation / downsampling deu to the 1m.
🌐
Promlabs
promlabs.com › blog › 2021 › 01 › 29 › how-exactly-does-promql-calculate-rates
PromLabs | Blog - How Exactly Does PromQL Calculate Rates?
January 29, 2021 - How exactly to calculate the increase given a fixed time window and some data points falling under that window is a matter of tradeoffs and imperfect approximations. Prometheus chooses an approach that aims to provide the most correct answer on average, given only the limited data under the provided window. Let's look in more detail at how it does this: What frequently confuses people is the extrapolating ...
🌐
GitHub
github.com › prometheus › prometheus › issues › 3806
Proposal for improving rate/increase · Issue #3806 · prometheus/prometheus
February 6, 2018 - On-the-fly query_range rate/increase calculations with each increase only included in one rate/increase point and without data loss (which is what Grafana provides support for). Currently there are 2 issues that prevent this from working: (a) one needs to be aware of the scrape interval in order to bump the range by that much; and (b) neither Grafana nor Prometheus support the kind of time arithmetic necessary to query rate(foo[1h+1m]).
Author: prometheus
🌐
Google Groups
groups.google.com › g › prometheus-users › c › jqEt-FkJo0o
overhead of rate vs increase
In terms of samples fetched from ... fetch all data points from storage. On the other hand, the increase() function would fetch the first and last data point + penultimate data points for interpolation/extrapolation....
🌐
MetricFire
metricfire.com › blog › understanding-the-prometheus-rate-function
How the Prometheus rate() function works | MetricFire
March 12, 2026 - The rate() function in Prometheus is a fundamental tool for monitoring systems, enabling users to calculate the per-second average rate of increase of counter metrics over a specified time range.
🌐
GitHub
github.com › prometheus › prometheus › issues › 17824
Feature request: a query function "increase()" variant that assumes new metrics to have started at 0 before the first value · Issue #17824 · prometheus/prometheus
January 9, 2026 - an increase variant, that assumes that a metric was at 0 at the beginning of the time range, if no samples exist there ... a delta function without extrapolation, that assumes that a metric was at 0 at the beginning of the time range, if no ...
Author: prometheus
🌐
GitHub
github.com › prometheus › prometheus › releases › tag › v3.14.0
Release 3.14.0 / 2026-08-17 · prometheus/prometheus
[FEATURE] PromQL: Allow rate() and increase() to use start timestamps as an alternative for rate extrapolation. Hidden behind the use-start-timestamps feature flag. #18619 · [FEATURE] TSDB: Add experimental support for encoding start timestamps ...
Author: prometheus
🌐
INNOQ
innoq.com › en › blog › 2019 › 05 › prometheus-counters
Prometheus Counters and how to deal with them – INNOQ
May 20, 2019 - Because of that, if we calculate the increase within this range vector, the result is 58 (76 - 18). Now, that’s not what Prometheus returns. The reason is (again according to the documentation) that the increase function tries to extrapolate missing values and estimate the values at the borders ...
🌐
GitHub
github.com › prometheus › prometheus › issues › 12967
Proposal for improving rate, increase, delta (based on xrate, xincrease) · Issue #12967 · prometheus/prometheus
October 11, 2023 - the first counter increase from the origin is counted rather than ignored; missed or late scrapes never lead to missing results; ... Here is a Design Doc with a detailed explanation including examples: Prometheus yrate (yrate, yincrease, ydelta): ...
Author: prometheus