About the PromQL cheat sheet
PromQL is a small language with one concept that has to click before anything else makes sense: the difference between an instant vector and a range vector. An instant vector is one sample per series at a point in time. A range vector is a window of samples, produced by appending a duration in square brackets, and it cannot be graphed directly — it must be passed through a function like rate.
Almost every early PromQL error is this distinction. Applying rate to an instant vector fails; graphing a range vector fails; and the fix for both is to look at whether a duration selector is present where it belongs.
The other rule worth learning immediately is that rate and increase belong to counters, which only go up, while gauges are read directly. Applying rate to a gauge produces a plausible-looking line that means nothing.
Frequently asked questions
What is the difference between rate and irate?
rate averages across the whole window and is what you want for alerting and dashboards, because it smooths spikes and tolerates a missed scrape. irate uses only the last two samples, so it is far more responsive and far noisier. Use irate for zooming into a short incident, rate for everything else.
What window should I use with rate?
At least four times the scrape interval, so the window always contains several samples even if one scrape is missed. With a 30 second scrape, five minutes is a safe default. Too short a window produces gaps whenever a scrape fails; too long makes the query slow to respond to real change.
Why does my counter query show a huge spike?
Probably a counter reset that was not handled, or a target that restarted and began from zero. rate and increase account for resets automatically, which is exactly why you should never subtract raw counter values yourself. A spike after a deploy usually means raw arithmetic somewhere in the query.
How do I calculate a percentile from a histogram?
Use histogram_quantile over the rate of the bucket series, aggregating by the le label. The result is only as accurate as the bucket boundaries — if your buckets stop at one second and real latency is five, the estimate is meaningless. Check the bucket layout before trusting a p99.
Why is my query timing out?
Almost always cardinality. A query touching a metric with high-cardinality labels has to load an enormous number of series. Filter with label matchers as early as possible so fewer series are selected, and aggregate before joining rather than after. If a metric is unusably slow, the real fix is usually to remove a label at the source.
Need this managed for you, not just automated?
We're also a hands-on DevOps consultancy — Kubernetes, CI/CD, and cloud infrastructure.