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 a good approach. Generally this will overestimate by 16% as you're multiplying by 1.16. No, Prometheus in general is not resilient to jitter.
Discussions

increase() in Prometheus sometimes doubles values: how to avoid? - Stack Overflow
I've found that for some graphs I get doubles values from Prometheus where should be just ones: Query I use: increase(signups_count[4m]) Scrape interval is set to the recommended maximum of 2 min... More on stackoverflow.com
🌐 stackoverflow.com
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
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
Feature request: a query function "increase()" variant that assumes new metrics to have started at 0 before the first value
Proposal Hello :) Thank you for this awesome project! For alerting use cases, we often want to be alerted if an error/retry happens more than N times, as we then assume that the automatic retry fai... More on github.com
🌐 github.com
5
January 9, 2026
🌐
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 ...
Author: prometheus
🌐
Google Groups
groups.google.com › g › prometheus-users › c › _aK7im7elUs
Why does increase() return fractional results for integer-valued metrics?
If you just took the last sample without extrapolation it could be very old (for example 2 minutes for a slowly scraped endpoint). For the majority of cases looking at how things have been changing and extrapolating the forwards/backwards to when you need values is often sensible and gives ...
🌐
DoiT
doit.com › home › blog › making peace with prometheus rate()
Making peace with Prometheus rate() | DoiT
February 17, 2023 - This is a fork of Prometheus that adds xrate(), xincrease(), etc. functions that both add extra scrape (similar to as $__rate_interval will do) but will also apply de-extrapolation as we did in the last chapter example:
🌐
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 .
🌐
GitHub
github.com › prometheus › prometheus › pull › 1161
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 i...
Author: prometheus
🌐
Promlabs
promlabs.com › blog › 2021 › 01 › 29 › how-exactly-does-promql-calculate-rates
PromLabs | Blog - How Exactly Does PromQL Calculate Rates?
January 29, 2021 - 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 behavior of the rate() and increase() functions. As an example...
Find elsewhere
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.

🌐
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 - For example: sum by (country) ( increase(orders_created_total[5m]) ) ... Be cautious of Gauges though: Because of the scraping interval, you may not see every increase/decrease in a gauge.
🌐
INNOQ
innoq.com › en › blog › 2019 › 05 › prometheus-counters
Prometheus Counters and how to deal with them – INNOQ
May 20, 2019 - If we execute this query, we would expect to get the value 60 as a result, because our counter is increased by 1 every 5 seconds over the last 5 minutes. What we really get is something like 59.035953240763114.
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 › 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 - Proposal Hello :) Thank you for this awesome project! For alerting use cases, we often want to be alerted if an error/retry happens more than N times, as we then assume that the automatic retry failed. E.g. increase(cilium_errors_warning...
Author: prometheus
🌐
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
🌐
MetricFire
metricfire.com › blog › understanding-the-prometheus-rate-function
How the Prometheus rate() function works | MetricFire
March 12, 2026 - Aggregation operators calculate mathematical values over a time range. You can use Prometheus functions such as the ones below to aggregate over a given range vector: ... As another example, you can use the increase() Prometheus function to count the number of HTTP requests over the past 5 minutes, e.g.:
🌐
GitHub
github.com › prometheus › prometheus › issues › 12967
Proposal for improving rate, increase, delta (based on xrate, xincrease) · Issue #12967 · prometheus/prometheus
October 11, 2023 - Here is a Design Doc with a detailed explanation including examples: Prometheus yrate (yrate, yincrease, ydelta): Linear versions of rate(), increase() and delta(), based on xrate()
Author: prometheus
🌐
Google Groups
groups.google.com › g › prometheus-users › c › jqEt-FkJo0o
overhead of rate vs increase
to Prometheus Users · In terms of samples fetched from the DB which is a cost limiting factor in our set up, what is the overhead of rate() compared to increase(). Based on my reading so far, rate() requires all data points within the time range interval thus it will 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.
🌐
GitHub
github.com › prometheus › prometheus › issues › 3806
Proposal for improving rate/increase · Issue #3806 · prometheus/prometheus
February 6, 2018 - I'm creating a separate, hopefully more focused (and civil) issue in an attempt to start a discussion on the problems (as seen by me and a number of others) with and possible solutions for rate() and increase(). First, let me start by ac...
Author: prometheus
🌐
PagerTree
pagertree.com › learn › prometheus › promeql › counter rates & increases
Counter Rates & Increases | PagerTree
Learn how Prometheus handles counter resets with rate, irate, and increase functions.
🌐
GitMemory
gitmemory.com › issue › prometheus › prometheus › 3746 › 493676781
rate()/increase() extrapolation considered harmful - prometheus
It makes good sense that you need N+1 samples to compute rates at N points spaced at the polling interval without losing information. While it's true that Prometheus is not about drawing graphs, it sounds like the current rate behavior actually prevents me from getting "stable looking" rate graphs (unless I settle for the rather unsavory increase(foo[15s]) / 1.5 workaround.