Instant vector
basicA set of time series, each with a single sample at the evaluation timestamp. The most common return type.
http_requests_total
# → one value per matching series, "now" A modern reference for the Prometheus query language — types, selectors, operators, aggregations, functions, time syntax, and the gotchas you only learn at 3am. Beginner sections first, advanced as you scroll.
A set of time series, each with a single sample at the evaluation timestamp. The most common return type.
http_requests_total
# → one value per matching series, "now" Each series carries a window of samples. You can't graph one directly — feed it to rate(), avg_over_time(), etc.
http_requests_total[5m]
# → all samples in the last 5 minutes A single floating-point number. Returned by literals and the scalar() function.
3.14
scalar(sum(up)) Currently used only as function arguments. You can't query a string.
"five minutes" The bare name selects every series that shares it.
node_cpu_seconds_total =Exact string match. Most common matcher in everyday queries.
http_requests_total{job="api", method="GET"} !=Exclude a label value. Useful for filtering out a noisy instance or status.
http_requests_total{status!="200"} =~RE2 regex, fully anchored automatically. Great for OR-ing several values.
http_requests_total{status=~"5.."}
up{job=~"api|web|worker"} !~Series whose label does not match the pattern.
requests_total{path!~"/health.*"} An empty string matches series where the label is unset. Pair with = or !=.
# series WITHOUT an env label
up{env=""}
# series that DO have one
up{env!=""} The metric name lives in the special __name__ label, so you can regex-match it too.
{__name__=~"node_cpu_.*", cpu="0"} Shifts the evaluation time backward. @ pins it to a Unix timestamp.
http_requests_total offset 5m
# pin to a specific moment
http_requests_total @ 1672531200 Combine integer + unit. Units can be chained, biggest first, no spaces.
5m # 5 minutes
1h30m # 1.5 hours
7d # 7 days
1y2w # 1 year 2 weeks
# units: ms s m h d w y Square brackets after a selector capture all samples in that window.
node_network_receive_bytes_total[5m] [range:resolution] — evaluates an instant-vector expression over a range, like a recording rule on the fly. Resolution is optional.
max_over_time(
rate(http_requests_total[5m])[1h:1m]
) Cost: subqueries re-evaluate the inner expression at each step. Prefer recording rules for hot paths.
@ start() / @ end()Pins evaluation to the start or end of the surrounding range query — handy for rendering "value at the moment of an alert".
http_requests_total @ start() sumAdd values across series. Almost always combined with by or without.
sum by (job) (http_requests_total) avgavg by (instance) (node_load1) min / maxmax by (job) (up) countNumber of series in each group. Use count_values for value buckets.
count by (job) (up == 1) by vs withoutby keeps only listed labels; without drops them and keeps the rest. Pick whichever is shorter to type.
sum by (code) (requests)
sum without (instance, pod) (requests) topk / bottomkK highest/lowest series per group — keeps labels, unlike sum.
topk(5, rate(http_requests_total[5m])) quantileφ-quantile (0–1) across series. For histogram quantiles, see histogram_quantile.
quantile by (job) (0.95, go_goroutines) stddev / stdvarPopulation standard deviation / variance across series in each group.
stddev by (cluster) (node_load1) groupReturns a constant 1 per group — useful as a left side in many-to-one joins.
group by (cluster, namespace) (kube_pod_info) rate(v range)Per-second average rate of a counter over the window. Resets are handled automatically. Use this for graphs and alerts on counters.
rate(http_requests_total[5m]) Window must contain at least 2 samples — make it ≥ 4× scrape interval.
irate(v range)Rate based on the last two samples only — reactive but spiky. Good for short-lived dashboards, bad for alerts.
irate(http_requests_total[1m]) increase(v range)Total counter increase over the window. Equivalent to rate × seconds, but reads more naturally.
increase(errors_total[1h]) delta(v range)First-to-last difference for a gauge. Don't use on counters (use increase).
delta(cpu_temp_celsius[2h]) histogram_quantile(φ, b)φ-quantile (0–1) from a classic histogram's _bucket series. Always pair with rate + a sum by (le, …).
histogram_quantile(0.95,
sum by (le, job) (
rate(http_request_duration_seconds_bucket[5m])
)
) predict_linear(v range, t)Linear regression — predicts the value t seconds from now. Classic disk-full alert.
predict_linear(
node_filesystem_avail_bytes[1h], 4 * 3600
) < 0 *_over_time(v range)Aggregate a range vector along the time axis (per series). Family includes avg / min / max / sum / count / quantile / stddev / last.
avg_over_time(cpu_usage[10m])
max_over_time(queue_depth[1h])
last_over_time(build_info[24h]) absent(v) / absent_over_timeReturns 1 when the input has no series — perfect for "did this metric stop reporting?" alerts.
absent(up{job="api"})
absent_over_time(up{job="api"}[5m]) changes / resetschanges counts value changes (gauges); resets counts counter resets in the window.
changes(leader_id[1h])
resets(process_start_time_seconds[1h]) label_replaceRewrite a label using a regex on another label. Most common use: aligning labels for a join.
label_replace(
up, "host", "$1", "instance", "(.*):.*"
) label_joinConcatenate label values into a new label using a separator.
label_join(up, "id", "/", "job", "instance") vector(s) / scalar(v)Bridge between scalar and vector worlds — useful in arithmetic against constants.
vector(1)
scalar(sum(up)) time()Unix timestamp (seconds) of the evaluation. Combine with process_start_time_seconds for uptime.
time() - process_start_time_seconds clamp / clamp_min / clamp_maxSqueeze values into a range. Handy for sanitizing dashboards.
clamp(cpu_pct, 0, 100) sort / sort_descSort the result vector by sample value. Affects table view, not graphs.
sort_desc(rate(errors_total[5m])) Vectors line up by matching label sets. Use on()/ignoring() + group_left/right for many-to-one joins.
requests{code="5xx"}
/ ignoring(code) group_left
requests rate() goes inside sum()Always: sum(rate(...)), never rate(sum(...)). Counters reset per series; aggregating first hides the resets and produces nonsense.
rate/increase need at least 2 samples. With a 30s scrape, [1m] is fragile. [2m] is the safe minimum, [5m] is conventional.
increase() can return non-integersPrometheus extrapolates to the window edges. increase(x[1h]) may report 4.32 even though counters are integers. Don't be alarmed.
rate / irate / increase / resets → counters. delta / deriv / predict_linear → gauges. Mixing them silently produces wrong numbers.
le when summing histogramshistogram_quantile needs the le label. sum by (le, …)(rate(..._bucket[5m])) — never drop it.
User IDs, request paths, and trace IDs as labels will burn your TSDB. Aggregate them away early in queries; never expose them on hot metrics.
[1h:1m] means 60 inner evaluations per output point. If you reach for one in a dashboard panel, it probably wants to be a recording rule.
If a / b drops to empty, the two sides have different labels. Use on(...) to whitelist matching labels, ignoring(...) to drop the noisy ones, and group_left/group_right for many-to-one.