PromQL

    What Is PromQL?

    PromQL, short for Prometheus Query Language, is the functional query language built into Prometheus for selecting, filtering, and aggregating time-series metrics. Every dashboard panel, alerting rule, and recording rule in a Prometheus setup is ultimately a PromQL expression evaluated against the metrics the server has scraped.

    The language reads more like a set of chained transformations than a traditional query. A user selects a metric by name and label, narrows it with a time window or filter, then applies a function to turn raw samples into a rate, an average, or a threshold check. That structure is what lets a single line answer a question like “what is the 95th percentile request latency for this service over the last five minutes.”

    What Data Types Does PromQL Use?

    PromQL works with four data types, and understanding them is the fastest way to stop guessing at query errors.

    • Instant vector – a set of time series, each with a single sample at the same timestamp. This is what you get from a plain metric selector like http_requests_total.
    • Range vector – a set of time series where each series holds a range of samples over a time window, produced by adding a duration in brackets, such as http_requests_total[5m].
    • Scalar – a single numeric value with no labels or timestamp, often the result of an aggregation like count().
    • String – rarely used directly in queries, mostly present for internal function support.

    Most PromQL mistakes trace back to mixing these types incorrectly, such as trying to graph a range vector directly instead of running it through a function like rate() first.

    How Do You Write a Basic PromQL Query?

    A PromQL query starts with a metric name, which by itself returns an instant vector of every time series carrying that name.

    http_requests_total

    Adding a label filter narrows that selection to specific series:

    http_requests_total{job="api", status="500"}

    Wrapping the metric in a range selector and a function turns raw counters into a meaningful rate:

    rate(http_requests_total{status="500"}[5m])

    That last query answers a specific operational question: how many 500 errors per second has this service produced, averaged over the last five minutes. Aggregation operators like sum by (job) can then roll that rate up across every instance of a service.

    What Are the Most Common PromQL Functions and Operators?

    A small set of functions covers most day-to-day queries.

    • rate() and irate() calculate the per-second average rate of increase for a counter over a time window, which is how PromQL turns a constantly growing number into something graphable.
    • increase() returns the total increase of a counter over a time window rather than a per-second rate.
    • sum, avg, min, max, count are aggregation operators that collapse many time series into fewer, optionally grouped by or without specific labels.
    • histogram_quantile() calculates percentiles, such as p95 or p99 latency, from histogram metrics.
    • Binary operators (+, -, *, /, and comparison operators like > and ==) let you combine metrics or build thresholds directly into a query, which is how most alerting rules are written.

    What Are Common PromQL Mistakes and Limitations?

    High-cardinality label sets are the most frequent source of slow or expensive PromQL queries. A query that groups by a label with thousands of unique values, such as a raw user ID, forces Prometheus to compute across an enormous number of series.

    Counter resets are another common trap. Because rate() and increase() are designed to handle counter resets from process restarts, applying them to a gauge metric instead of a counter produces meaningless results.

    PromQL also has no native way to join data across unrelated metrics the way a SQL join would. Correlating a metric with a log line or a trace span requires a platform that unifies those signal types outside of PromQL itself, since the language only operates on the metrics store it was built for.

    FAQs

    No. PromQL is a functional language purpose-built for labeled time-series data, while SQL is a general-purpose language for relational tables. PromQL has no joins in the SQL sense and its entire model is built around metrics, labels, and time windows.

    rate() returns the per-second average rate of increase over a time window, while increase() returns the total increase over that same window. increase() is effectively rate() multiplied by the number of seconds in the window.

    The most common causes are a label filter that does not match any scraped series, a metric name typo, or a range vector selector used where the query expects an instant vector. Checking the raw metric with a plain selector before adding filters usually isolates the problem quickly.

    No. PromQL only operates on the time-series metrics stored inside Prometheus. Correlating a PromQL result with logs or traces requires a separate observability layer that ingests all three signal types together.

    A recording rule pre-computes a PromQL expression on a schedule and stores the result as a new time series. Teams use recording rules to speed up dashboards and alerts that would otherwise re-run an expensive query every time they load.

    Get started for free

    Completely free for 14 days, no strings attached.