Add a moving average to a Grafana dashboard
Smooth Prometheus rates with avg_over_time and an explicit subquery, or use InfluxQL MOVING_AVERAGE while keeping the original signal visible.
With a Prometheus data source, use avg_over_time to average samples over a moving window. If the input is another expression, such as rate, wrap it in a subquery. With an InfluxQL data source, use MOVING_AVERAGE.
Smooth a Prometheus rate
avg_over_time(rate(http_requests_total{job="frontend"}[1m])[5m:])
The inner expression estimates request rate over one minute. The subquery evaluates that expression repeatedly over five minutes, and avg_over_time averages those results. The colon in [5m:] is required for a subquery; omitting its resolution uses Prometheus's configured default evaluation interval.
The one-minute rate window is only an example. It must contain enough scrapes to produce a useful rate. A longer window may be appropriate for a slow scrape interval. You can make the subquery resolution explicit, for example [5m:30s], when you need consistent evaluation spacing.
For a gauge, a direct range selector is sufficient:
avg_over_time(queue_depth[5m])
Other window functions answer different questions. quantile_over_time(0.5, queue_depth[5m]) shows a median; max_over_time and min_over_time show the upper and lower envelope. A median is less affected by isolated spikes, but it is not an arithmetic moving average.
Use InfluxQL
For a Grafana data source configured to use InfluxQL:
SELECT MOVING_AVERAGE(MEAN("value"), 5)
FROM "metric"
WHERE $timeFilter
GROUP BY time($__interval)
This averages five successive grouped means. Its effective time window therefore changes when $__interval changes. The function belongs to InfluxQL; Flux and SQL data sources use their own syntax.
Choose the window for the decision
A longer window makes the trend smoother and slower to react. Overlay the unsmoothed series and its average so that brief spikes remain visible. Use raw peaks as well as trends for capacity analysis. Choose alert windows around the failure you need to detect rather than assuming that a particular duration suits every service.
FAQ
Why does an expression followed by [5m] fail? A range selector attaches directly to a vector selector. A computed expression needs subquery syntax, such as rate(http_requests_total[1m])[5m:].
Can this produce an exponential moving average? No. avg_over_time is a simple average. Prometheus's double exponential smoothing function is a different algorithm, with version and feature-flag requirements; the older name holt_winters is not a drop-in EMA. Choose an implementation that matches the smoothing definition you need.
Sources
This guide is based on the documentation below; the examples have not been tested against a live deployment.
Contact us
Join the community
to join the community
Try Guance
Start online and pay only for what you use.
Get startedChoose a Guance plan