The Multi-Pod Problem
A production service runs as many replicas. rate(http_requests_total[5m]) returns one line per pod — potentially dozens of overlapping lines on your graph. This is rarely what you want. You want the total traffic across all pods.
Aggregation operators collapse multiple time series into fewer time series.
Core Aggregation Operators
| Operator | Use Case |
|---|---|
sum |
Total across all series |
avg |
Average value |
min / max |
Lowest / highest value |
count |
Number of series (not values) |
topk(N, ...) |
The N highest-value series |
The by and without Clauses
These work like SQL GROUP BY. They control which labels survive the aggregation.
by (label1, label2) — Keep only the listed labels. Discard everything else. Summing the API server's request rate by (method, status) yields one time series per unique (method, status) combination. The instance, pod, and other labels are gone. You can now see GET-200 vs POST-500 traffic on a single clean graph.
without (label1) — Keep everything except the listed labels. Summing a request rate without (instance) is useful when you want to aggregate away just the pod identity but keep all other labels.
Practical Pattern: The Full Traffic Query
The pattern you will write dozens of times in your career: sum a rate-of-a-counter over a window, grouped by whichever dimension you care about — for example, total RPS across all pods, broken down by HTTP method. Memorize the shape: sum(rate(counter[window])) by (dimension).