Search code examples
prometheuspromql

Prometheus topk function returning all results


I am trying to graph out the top 5 users by their login count in the last 24 hours. But when I use the below topk function, I am getting all the user login within that time range.

Query: topk(10, sum(my_app_login) by (User_Name) != 0)

enter image description here

How do I limit it to only top 10?


Solution

  • First of all, you need to enable instant query in Grafana. In this case Grafana will return only the last data point on the selected time range per each resulting time series instead of returning many data points per time series on the selected time range.

    Other considerations:

    • if my_app_login is a counter, then the following query should returns top users with the most login actions during the last 24 hours:
    topk(10, sum(increase(my_app_login[24h])) by (User_Name))
    

    Note that Prometheus may return fractional results from this query even if my_app_login contains only integer values. This is because of data model quirks for increase() function in Prometheus - see this comment and this article for details. If you need exact integer results, then take a look at MetricsQL from VictoriaMetrics.

    • if my_app_login is a gauge, which contains the number of app logins since the previous sample, then the following query should work:
    topk(10, sum(sum_over_time(my_app_login[24h])) by (User_Name))
    

    See sum_over_time() docs for more details.

    Note that topk(N, ...) function may return more than N time series when this function is used for building a graph over time (aka range query). This is because it returns top N time series independently per each timestamp on the graph. If you need no more than top N time series on the graph, then take a look at topk_max, topk_last and other topk_* functions from MetricsQL.