npx skills add ...
npx skills add grafana/skills --skill promql
Write, validate, and optimize PromQL for Prometheus / Grafana Mimir / Grafana Cloud Metrics. Covers `rate` vs `irate` vs `increase`, label matchers and regex, `sum / avg / topk / by / without` aggregation, classic + native `histogram_quantile`, ratios with divide-by-zero guards, `absent` / `changes` for staleness, time offsets and `predict_linear`, recording-rule naming, SLO + burn-rate math, and a cardinality-hunting playbook. Use when writing a metric query, fixing wrong p95s, building an error-budget alert, debugging "query is slow", finding the noisy label that blew up cardinality, or migrating a dashboard query to a recording rule — even when the user says "calculate the error rate", "p99 latency", "sum by service", "why is this query slow", or "what's filling Mimir" without naming PromQL.
npx skills add grafana/skills --skill promql
Docs: https://prometheus.io/docs/prometheus/latest/querying/basics/
PromQL returns either an instant vector, a range vector, or a scalar.
Golden rule: rate() / increase() require a range vector ≥ 4× the scrape interval. 60s scrape → use [5m] minimum.
/api/v1/query or via Grafana Explore)references/patterns.mdPer-status request rate (aggregate AFTER rate):
p95 latency (must keep le in the inner aggregation):
Error rate with divide-by-zero guard:
Full library (recording rules, SLO burn-rate, offsets, cardinality hunt, native histograms): references/patterns.md.
histogram_quantile returns NaN → forgot by (le) in the inner aggregation/api/v1/series) and the window ≥ 4× scrape intervalrate() (always rate() first)topk(...) + a recording rule + drop high-cardinality labels (see references/patterns.md)sum(rate(http_requests_total{job="api"}[5m])) by (status_code)histogram_quantile(0.95,
sum(rate(http_request_duration_seconds_bucket[5m])) by (le, service))sum(rate(http_requests_total{status_code=~"5.."}[5m]))
/ (sum(rate(http_requests_total[5m])) > 0)# 1. Pick the slow expression, give it a recording-rule name
groups:
- name: http_request_rates
interval: 1m
rules:
- record: job:http_request_duration_p95:rate5m
expr: |
histogram_quantile(0.95,
sum(rate(http_request_duration_seconds_bucket[5m])) by (le, job))# 2. After rules load, verify the new metric exists
curl -sG --data-urlencode "query=job:http_request_duration_p95:rate5m" \
"$PROM/api/v1/query" | jq '.data.result | length' # → > 0
# 3. Verify it matches the original expression for at least one sample window
# (Both queries should produce the same value at the same timestamp.)
# 4. Replace the dashboard panel expression with the recording-rule metric.