Generated banner for Promql
Generated logo for Promql

Promql

Grafana LabsOfficialPublished by Grafana Labs

  • Skill
  • Tool integration
  • Cloud and DevOps
  • Apache-2.0
  • No issues found

From the author

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.
— the description by Grafana Labs

AutoGineer summary

Written by AutoGineer from the skill’s own files, not by the author

This skill provides a structured approach to mastering PromQL, the query language for Prometheus and compatible systems like Grafana Mimir. It covers essential query patterns, including rate calculations, histogram quantiles, aggregation techniques, and ratio math with safety guards. Beyond basic syntax, it offers guidance on performance optimization, such as cardinality management, recording rule implementation, and debugging common query issues like slow performance or incorrect data results.

What it does

  • Provides patterns for common metrics like request rates, error ratios, and p95 latency.
  • Explains how to correctly aggregate data and use histogram quantiles.
  • Offers techniques for debugging slow queries and high-cardinality issues.
  • Demonstrates how to migrate dashboard queries to efficient recording rules.
  • Includes math for SLO tracking and burn-rate alerting.
  • Provides validation workflows to test query syntax and data existence.

When to use it

  • When you need to write or debug complex PromQL queries for monitoring.
  • When troubleshooting incorrect metric results like skewed p95 latency.
  • When optimizing slow-running dashboard queries.
  • When investigating high-cardinality issues that impact system performance.
  • When setting up alerting based on SLOs and error budgets.

Advantages

  • Reduces common errors like divide-by-zero or incorrect aggregation order.
  • Improves query performance through recording rule best practices.
  • Provides a clear playbook for identifying and mitigating cardinality spikes.
  • Standardizes naming conventions for recording rules.

Usage examples

“Calculate the 5xx error rate per service.”
Provides the expression: sum(rate(http_requests_total{status_code=~'5..'}[5m])) by (service) / (sum(rate(http_requests_total[5m])) > 0).
“Why is my histogram_quantile returning NaN?”
Identifies the common mistake of omitting 'by (le)' in the inner aggregation and provides the corrected syntax.
“How do I convert a slow dashboard query into a recording rule?”
Provides a step-by-step YAML template for defining the recording rule and verifying the new metric.
“How can I find which label is causing high cardinality?”
Provides a cardinality-hunting playbook using count and topk queries to isolate noisy labels.

Install

  1. Download the skill as a ZIP:

    https://autogineer.com/agent-skills/grafana/promql/download
  2. Unzip it into the cross-client skills folder of your project:

    mkdir -p .agents/skills && unzip promql.zip -d .agents/skills

Documentation by Grafana Labs

PromQL Query Patterns

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.

Prerequisites

  • A Prometheus / Mimir / Grafana Cloud endpoint to query (/api/v1/query or via Grafana Explore)

  • The PromQL pattern library in references/patterns.md

Common Workflows

1. Write + validate a query
# 0. Point at your Prometheus/Mimir. For Grafana Cloud, use the metrics endpoint
#    and add basic auth (-u "<metrics_user>:<token>") to each curl below.
PROM=http://localhost:9090   # or https://prometheus-prod-XX.grafana.net/api/prom

# 1. Sketch the query — for "5xx error rate per service":
EXPR='sum(rate(http_requests_total{status_code=~"5.."}[5m])) by (service)'

# 2. Validate syntax + that the metric/labels exist
curl -sG --data-urlencode "query=${EXPR}" \
  "$PROM/api/v1/query" | jq '.status, (.data.result|length)'
# Expect: "success" and result count > 0. If 0 — check label spelling and scrape activity:
curl -sG --data-urlencode "match[]=http_requests_total" "$PROM/api/v1/series" | jq '.data | length'

# 3. Sanity-check the magnitude — open Grafana Explore, paste the expr,
#    confirm the values look right against a known ground truth (k6 run, log count, etc.)
2. Common patterns to copy

Per-status request rate (aggregate AFTER rate):

sum(rate(http_requests_total{job="api"}[5m])) by (status_code)

p95 latency (must keep le in the inner aggregation):

histogram_quantile(0.95,
  sum(rate(http_request_duration_seconds_bucket[5m])) by (le, service))

Error rate with divide-by-zero guard:

sum(rate(http_requests_total{status_code=~"5.."}[5m]))
  / (sum(rate(http_requests_total[5m])) > 0)

Full library (recording rules, SLO burn-rate, offsets, cardinality hunt, native histograms): references/patterns.md.

3. Convert a slow dashboard query into a recording rule
# 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.

Common bugs

  • histogram_quantile returns NaN → forgot by (le) in the inner aggregation

  • "No data" → check the metric exists (/api/v1/series) and the window ≥ 4× scrape interval

  • Wrong rate magnitude → counter was aggregated before rate() (always rate() first)

  • Query timeout → series count too high; use topk(...) + a recording rule + drop high-cardinality labels (see references/patterns.md)

Resources

Files

SKILL.md

PromQL Query Patterns

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.

Prerequisites

  • A Prometheus / Mimir / Grafana Cloud endpoint to query (/api/v1/query or via Grafana Explore)

  • The PromQL pattern library in references/patterns.md

Common Workflows

1. Write + validate a query
# 0. Point at your Prometheus/Mimir. For Grafana Cloud, use the metrics endpoint
#    and add basic auth (-u "<metrics_user>:<token>") to each curl below.
PROM=http://localhost:9090   # or https://prometheus-prod-XX.grafana.net/api/prom

# 1. Sketch the query — for "5xx error rate per service":
EXPR='sum(rate(http_requests_total{status_code=~"5.."}[5m])) by (service)'

# 2. Validate syntax + that the metric/labels exist
curl -sG --data-urlencode "query=${EXPR}" \
  "$PROM/api/v1/query" | jq '.status, (.data.result|length)'
# Expect: "success" and result count > 0. If 0 — check label spelling and scrape activity:
curl -sG --data-urlencode "match[]=http_requests_total" "$PROM/api/v1/series" | jq '.data | length'

# 3. Sanity-check the magnitude — open Grafana Explore, paste the expr,
#    confirm the values look right against a known ground truth (k6 run, log count, etc.)
2. Common patterns to copy

Per-status request rate (aggregate AFTER rate):

sum(rate(http_requests_total{job="api"}[5m])) by (status_code)

p95 latency (must keep le in the inner aggregation):

histogram_quantile(0.95,
  sum(rate(http_request_duration_seconds_bucket[5m])) by (le, service))

Error rate with divide-by-zero guard:

sum(rate(http_requests_total{status_code=~"5.."}[5m]))
  / (sum(rate(http_requests_total[5m])) > 0)

Full library (recording rules, SLO burn-rate, offsets, cardinality hunt, native histograms): references/patterns.md.

3. Convert a slow dashboard query into a recording rule
# 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.

Common bugs

  • histogram_quantile returns NaN → forgot by (le) in the inner aggregation

  • "No data" → check the metric exists (/api/v1/series) and the window ≥ 4× scrape interval

  • Wrong rate magnitude → counter was aggregated before rate() (always rate() first)

  • Query timeout → series count too high; use topk(...) + a recording rule + drop high-cardinality labels (see references/patterns.md)

Resources

Requirements and compatibility

Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Kiro, OpenCode, Goose, Amp, Roo Code, JetBrains Junie, Factory Droid, Devin (ex-Windsurf), Mistral Vibe, OpenHands, Letta

“Works with” means the tool reads the open Agent Skills format; a skill written for one tool may use features others lack.

Security

No issues found by our static scan· No issues found

A static scan is not a guarantee. Skills are third-party content: review a skill before you let an agent use it.

Attribution and licence

Published by
Grafana Labs
Publisher
Grafana Labs (Official)
Source
grafana/skills · skills/grafana-core/promql · commit 8fb72a5
Licence
Apache License 2.0 (redistribution allowed)
  • LICENSE (added by AutoGineer from LICENSE)
  • ATTRIBUTION.md (written by AutoGineer)
Synced

AutoGineer is not affiliated with or endorsed by Grafana Labs or Grafana Labs.

Download ZIP

The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download promql.zip