PromQL: PCA practice questions
PromQL is the query language of Prometheus, and nearly every query you write combines the same few building blocks: selectors, range vectors, functions, aggregation operators and binary operators with vector matching.
By Ibrahim Yesilay · Published · Updated
Independent community practice, not affiliated with or endorsed by CNCF or The Linux Foundation.
What PromQL covers in PCA
PromQL is the query language of Prometheus, and nearly every query you write combines the same few building blocks: selectors, range vectors, functions, aggregation operators and binary operators with vector matching.
An expression evaluates to one of four types. An instant vector holds one sample per series, all at the same timestamp. A range vector holds a range of samples per series. A scalar is a single floating point number, and the string type is currently unused. Writing a bare metric name such as http_requests_total returns an instant vector with the most recent sample of every series of that name, looking back at most five minutes by default. Label matchers narrow the selection: = and != test equality, while =~ and !~ test a regular expression, and those regular expressions are fully anchored, so env=~"foo" means the whole value must be foo. Appending a duration in square brackets, as in http_requests_total[5m], turns the selector into a range vector.
Functions that look at change over time need a range vector. rate() returns the per-second average rate of increase of a counter over the window, adjusts automatically for counter resets caused by restarts, and extrapolates to the ends of the window; it is the function for alerting and for graphing slow-moving counters. irate() uses only the last two samples, so it reacts faster and suits volatile, fast-moving counters on graphs. increase() returns the total increase over the window and is essentially rate() multiplied by the window length, so it can return fractions. For gauges the matching tools are deriv(), a per-second derivative calculated with simple linear regression, and delta(), the difference between the first and last value. The _over_time family, such as avg_over_time or max_over_time, aggregates each series across its own time window, giving every sample equal weight.
Aggregation operators work across series instead of across time. sum, avg, min, max, count, count_values, group, stddev, stdvar, quantile, topk and bottomk all take an optional by or without clause: by keeps only the labels you list, without drops the labels you list and keeps the rest. So sum by (job) (rate(http_requests_total[5m])) gives one per-second request rate per job, and topk(3, ...) returns the three series with the highest values.
Binary operators between two instant vectors match series whose label sets are identical. on() restricts matching to the listed labels and ignoring() leaves listed labels out; when one side has many series per match, group_left or group_right declares a many-to-one or one-to-many match. Comparison operators filter by default, which is why up == 0 returns only the targets whose last scrape failed. Adding bool, as in up == bool 0, returns 0 or 1 for every series instead.
Percentiles come from histograms. histogram_quantile(0.95, sum by (le) (rate(http_request_duration_seconds_bucket[5m]))) estimates the 95th percentile latency: the input buckets must carry the le label, rate() sets the time window, and le must survive any aggregation. Because the estimate is computed on the server from bucket counts, buckets from many instances can be summed first, something that is not possible with the quantiles a summary precomputes inside each process. timestamp() returns each sample's time in seconds since the epoch, and absent() returns 1 when a selector matches nothing, a common way to alert on missing data.
Key points
- Regex label matchers (=~, !~) are fully anchored at both ends.
- rate() handles counter resets and extrapolates; irate() uses only the last two samples.
- by keeps only the listed labels; without drops the listed labels and keeps the rest.
- Comparison operators filter series unless the bool modifier is added, which returns 0 or 1.
- histogram_quantile() needs the le label on its input, normally wrapped around rate() of the _bucket series.
Three sample questions
116 PCA questions on PromQL, 32 with explanations. How practice works
Question 1
- A.sum()
- B.rate()
- C.avg_over_time()
- D.increase()
Correct answer: B
rate() function calculates the per-second average increase of a counter over a specified range. It's commonly used for counters like http_requests_total.Question 2
- A.avg_over_time()
- B.histogram_quantile()
- C.quantile_over_time()
- D.topk()
Correct answer: B
histogram_quantile() function calculates quantiles (e.g., 95th percentile) from histogram buckets like http_request_duration_seconds_bucket.Question 3
up == 0 indicate?- A.All targets are healthy
- B.Some targets are down
- C.All metrics are missing
- D.Prometheus server is restarting
Correct answer: B
up metric indicates whether a target is reachable (1) or not (0). A condition up == 0 means some targets are unreachable/down.Practice this topic
Focus mode keeps every question on PromQL until you leave it. 10 free guest answers, then a free account; no credit card.
Or open PCA practice across all topics.
Sources
The explanation above was checked against these official documents.
- Prometheus docs: Querying basics (checked 2026-10-23)
- Prometheus docs: Query functions (checked 2026-10-23)
- Prometheus docs: Operators (checked 2026-10-23)
- Prometheus docs: Histograms and summaries (checked 2026-10-23)