increase() and delta() are both Prometheus functions for calculating the change in a counter metric, but they handle counter resets differently, and picking the wrong one can lead to drastically incorrect results.

Let’s see them in action. Imagine we have a simple counter metric http_requests_total that increments every time a web server handles a request.

First, let’s look at delta(). If we query delta(http_requests_total[5m]), Prometheus will simply subtract the value of http_requests_total at the beginning of the 5-minute window from its value at the end.

# Example counter values over time:
# T=0: http_requests_total = 100
# T=1m: http_requests_total = 110
# T=2m: http_requests_total = 120
# T=3m: http_requests_total = 130 (Counter resets to 0 here)
# T=4m: http_requests_total = 5
# T=5m: http_requests_total = 15

# Query: delta(http_requests_total[5m])
# Calculation: Value at T=5m (15) - Value at T=0 (100) = -85

As you can see, delta() just does a simple subtraction. When the counter resets (which happens periodically in real systems, e.g., when a service restarts), delta() will report a negative value, which is nonsensical for a counter that should only increase.

Now, let’s look at increase(). The query increase(http_requests_total[5m]) is designed to handle these counter resets gracefully. It looks at the counter’s value over the specified time range and calculates the total increase, assuming that any drop in value is due to a reset.

# Using the same counter values:
# T=0: http_requests_total = 100
# T=1m: http_requests_total = 110
# T=2m: http_requests_total = 120
# T=3m: http_requests_total = 0 (Counter reset)
# T=4m: http_requests_total = 5
# T=5m: http_requests_total = 15

# Query: increase(http_requests_total[5m])
# Calculation:
# - From T=0 to T=3m: (120 - 100) = 20
# - From T=3m to T=5m: (15 - 0) = 15  (Handles reset correctly by assuming start from 0)
# - Total increase = 20 + 15 = 35

increase() correctly identifies the reset at T=3m and calculates the increase from the last valid point before the reset (T=2m, value 120) to the end of the range (T=5m, value 15), accounting for the new value after the reset. It effectively sums up the increments, ignoring the artificial drop caused by the reset.

The core problem increase() solves is that hardware or software restarts cause counters to reset to zero. If you use delta() on a metric that has reset within your query window, you’ll get a negative number, which is obviously wrong for a metric that can only ever go up. increase() is designed to handle this by detecting the counter reset and calculating the increase from the last known value before the reset to the current value.

When you’re calculating rates (e.g., requests per second), you almost always want to use increase() as the base. For example, to get the average requests per second over the last 5 minutes, you’d use increase(http_requests_total[5m]) / 5. Using delta() here would give you a wildly inaccurate (and often negative) rate if a reset occurred.

The increase() function also takes an optional step_size argument. This is particularly useful if you’re using increase() in a recording rule or dashboard where you want to ensure the calculation is performed at a specific interval, even if the scrape interval is different. For instance, increase(http_requests_total[5m] offset 1m) would calculate the increase over the 5 minutes ending one minute ago.

One subtle point is how increase() handles the very first data point in a range. If the counter has never been seen before, increase() will return 0. It needs at least two data points to calculate an increase. This is usually not an issue in practice as Prometheus typically scrapes metrics regularly, providing multiple points.

The most common mistake is using delta() when you should be using increase(). This happens because delta() is simpler to understand conceptually – it’s just the difference between two points. However, for any metric that is a true counter and can reset, increase() is the correct tool for calculating the actual amount that has "increased" over a time period.

The next thing you’ll likely need to consider is how to properly aggregate these rate calculations across multiple instances or labels using sum() or avg().

Want structured learning?

Take the full Prometheus course →