Skip to main content
Aggregation operators in Prometheus let you reduce an instant vector into a new instant vector by combining several time series into one (or fewer) values. Common use cases include computing the sum, min, max, average, or count across a set of time series. This guide explains:
  • What aggregation operators do
  • How to group results using by(...)
  • How to exclude labels using without(...)
  • Practical examples with http_requests and node_cpu_seconds_total
See also: Prometheus Aggregation Operators

Aggregation operators overview

Aggregation operators operate across all series in an instant vector by default. The most common are:
Aggregation reduces multiple time series into fewer series. If you need to retain distinctions (e.g., per path or per instance), use by(...) to group by label(s) before aggregation.

Basic examples: sum, max, avg

Given the following http_requests instant vector:
  • Sum across all series:
  • Max across all series:
  • Average across all series:
By default these operations aggregate over every distinct time series in the instant vector (i.e., every combination of labels).

Grouping with by(...)

Use by(<label1>, <label2>, ...) to keep the specified labels and aggregate across all others. This is how you “group by” a label. Example: sum by path
This groups the results by the path label and sums all series that share the same path. Example: sum by method
You can pass multiple labels to by(...) to aggregate by combinations (e.g., by(instance, method)).

Excluding labels with without(...)

without(...) is the inverse of by(...). It aggregates across all labels except the ones listed. Use it when you want to drop specific labels and collapse across the rest. Example:
If you want to aggregate all series while preserving instance and method labels, you can do:
This is equivalent to sum by(instance, method) (http_requests).
Be careful: aggregation removes labels not listed in by(...) (or not excluded by without(...)). If those labels are important for identifying series, include them in by(...).

Real-world: node_cpu_seconds_total examples

Consider node_cpu_seconds_total, which typically has labels like cpu, instance, mode, and job. If you run:
Prometheus will return a single value summing across all instances, CPUs, and modes — usually not what you want for per-node visibility. Example excerpt of raw time series:
If you want the total CPU seconds per instance (i.e., per target), group by instance:
This returns one summed value per instance, aggregating across cpu and mode. If you want per-instance and per-CPU totals, group by both:
That yields values like:
  • instance A, cpu 0
  • instance A, cpu 1
  • instance B, cpu 0
  • instance B, cpu 1
If you prefer to exclude cpu and mode and aggregate everything else, use without(...). For example, to aggregate into per-instance totals via without:
This drops cpu and mode from the result, leaving the aggregation keyed by the remaining labels (e.g., instance and job).

Quick tips

  • Use by(...) to preserve the labels you care about.
  • Use without(...) to drop specific labels and aggregate across the rest.
  • Aggregation dramatically changes the dimensionality of your data — including or excluding labels will affect alerting and dashboarding logic.
  • When building dashboards, prefer aggregations that match the level of granularity you want to visualize (per-instance, per-pod, per-cluster, etc.).

Watch Video

Practice Lab