Skip to content

PromQL: Prometheus Query Language Guide

DodaTech 3 min read

In this tutorial, you'll learn about PromQL: Prometheus Query Language Guide. We cover key concepts, practical examples, and best practices to help you understand and apply this topic effectively.

PromQL (Prometheus Query Language) is a functional query language that lets you select and aggregate time-series data in real time, providing the foundation for dashboards, alerts, and ad-hoc analysis.

What You'll Learn

In this tutorial, you will learn how to write PromQL queries using selectors, instant and range vectors, aggregation operators, and functions to calculate rates, averages, and percentiles from your metrics.

Why It Matters

Raw metrics are just numbers. PromQL transforms them into answers. Is CPU usage too high? What is the 99th percentile latency? How many requests failed in the last hour? Without PromQL, your Prometheus data is silent. With it, you can pinpoint performance issues, set precise alert thresholds, and build insightful dashboards.

Real-World Use

Durga Antivirus Pro uses PromQL to monitor scan latency. The query histogram_quantile(0.99, rate(scan_duration_seconds_bucket[5m])) tracks the 99th percentile scan time across all scanner nodes, triggering alerts when scans take longer than 30 seconds in the 99th percentile.

Instant Vectors and Range Vectors

The two fundamental data types in PromQL are instant vectors and range vectors.

Instant Vector

An instant vector is a set of time series with a single data point at the query evaluation time:

node_cpu_seconds_total

Expected output:

node_cpu_seconds_total{cpu="0", mode="idle"} 285193.42
node_cpu_seconds_total{cpu="0", mode="user"} 89234.11
node_cpu_seconds_total{cpu="0", mode="system"} 18234.56

Range Vector

A range vector selects a range of samples over a time window. Add a duration in brackets:

node_cpu_seconds_total[5m]

Expected output:

node_cpu_seconds_total{cpu="0", mode="idle"} [
  285193.42 @ 2026-06-21T10:00:00
  285208.15 @ 2026-06-21T10:00:15
  ...
]

Label Matching

Filter time series by label values using matchers in curly braces:

node_cpu_seconds_total{cpu="0", mode="user"}

Supported matchers: = (equals), != (not equals), =~ (regex match), !~ (regex not match).

Rate and Increase

The rate() function calculates the per-second average rate of increase for counter metrics over a time window:

rate(http_requests_total[5m])

For the total increase over the window, use increase():

increase(http_requests_total[1h])

Aggregation Operators

Aggregation operators combine multiple time series into fewer ones:

sum by (job) (rate(http_requests_total[5m]))

Other operators: avg, min, max, count, quantile, stddev, stdvar.

Histogram Quantiles

Use histogram_quantile() to calculate percentile values from histogram metrics:

histogram_quantile(0.95, rate(http_request_duration_seconds_bucket[5m]))

This returns the 95th percentile request duration over the last 5 minutes.

Common Mistakes

1. Forgetting rate() on Counters

Querying a counter directly shows an ever-increasing value. Always use rate() or increase() to make it meaningful.

2. Wrong Time Window

A time window that is too short (30 seconds) causes noisy data. A window that is too long (1 day) hides recent changes. Start with 5 minutes.

3. High Cardinality in Aggregation

Aggregating without a by() clause collapses everything into a single value, losing useful dimensions. Always specify the labels you need.

4. Regex Mistakes in Label Matchers

PromQL uses RE2 regex syntax. A missing escape or incorrect pattern returns no results. Test your regex with promtool.

5. Mixing Instant and Range Vectors

Some functions only accept range vectors (rate, increase). Passing an instant vector causes a parse error. Always check the expected type.

Practice Questions

1. What is the difference between an instant vector and a range vector? An instant vector has one data point per time series at the evaluation time. A range vector has multiple data points over a specified time window for each series.

2. Why must counter metrics be wrapped with rate()? Counters only increase. Without rate you see the cumulative total, not the rate of change. rate shows the per-second average increase.

3. How do you calculate the 95th percentile of request latency? Use histogram_quantile(0.95, rate(http_request_duration_seconds_bucket[5m])).

4. What does the sum by (job) operator do? It sums metric values grouped by the job label, collapsing all other labels.

5. Challenge: Write a query that returns the top 3 services by request rate, showing at least 100 requests per second, over the last 10 minutes.

What's Next

Apply your PromQL skills to create alerting rules that fire when metrics cross critical thresholds.

Built by the developers of Doda Browser, DodaZIP, and Durga Antivirus Pro.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro