The correction is integrated into the TP (See the green boxes)
From expensive queries to recorded series #
Context. Your dashboard recomputes the same aggregates on every refresh. You will record them in dedicated series, using Prometheus's own metrics, with no other dependency.
Prerequisites: Docker Compose, curl and jq · Estimated time: 40 min
1. Start Prometheus
Why? Prometheus scrapes itself, so you immediately get real HTTP metrics.
Writedocker-compose.ymlandprometheus.yml. Enable hot reload and reference arules.ymlfile.See the correction
services: prometheus: image: prom/prometheus:latest command: - --config.file=/etc/prometheus/prometheus.yml - --web.enable-lifecycle ports: - "9090:9090" volumes: - ./prometheus.yml:/etc/prometheus/prometheus.yml:ro - ./rules.yml:/etc/prometheus/rules.yml:ro - ./tests.yml:/etc/prometheus/tests.yml:roglobal: scrape_interval: 5s evaluation_interval: 15s rule_files: - /etc/prometheus/rules.yml scrape_configs: - job_name: prometheus static_configs: - targets: ["localhost:9090"]2. Record a first aggregate
Why? Staged aggregation avoids re-reading raw series at every level.
Createrules.ymlwith the rate perjobandhandler, then the rate perjobreusing the previous rule. Also create an emptytests.yml(touch tests.yml), check, start and query the new series after a minute.See the correction
groups: - name: http_prometheus rules: - record: job_handler:prometheus_http_requests:rate5m expr: sum by (job, handler) (rate(prometheus_http_requests_total[5m])) - record: job:prometheus_http_requests:rate5m expr: sum by (job) (job_handler:prometheus_http_requests:rate5m)docker compose up -d docker compose exec prometheus promtool check rules /etc/prometheus/rules.yml curl -X POST http://localhost:9090/-/reload curl -s --get --data-urlencode 'query=job:prometheus_http_requests:rate5m' http://localhost:9090/api/v1/query3. Add a robust error ratio and a percentile
Why? Without care, the ratio stays empty until an error exists.
Add the5xxerror rate, the error ratio (which must be 0 with no errors) and the 95th percentile of the duration. Reload and check the health of the rules.See the correction
groups: - name: http_prometheus rules: - record: job_handler:prometheus_http_requests:rate5m expr: sum by (job, handler) (rate(prometheus_http_requests_total[5m])) - record: job:prometheus_http_requests:rate5m expr: sum by (job) (job_handler:prometheus_http_requests:rate5m) - record: job:prometheus_http_requests_errors:rate5m expr: sum by (job) (rate(prometheus_http_requests_total{code=~"5.."}[5m])) - record: job:prometheus_http_requests_errors:ratio_rate5m expr: | (job:prometheus_http_requests_errors:rate5m or job:prometheus_http_requests:rate5m * 0) / job:prometheus_http_requests:rate5m - record: job:prometheus_http_request_duration_seconds:p95_rate5m expr: | histogram_quantile(0.95, sum by (job, le) (rate(prometheus_http_request_duration_seconds_bucket[5m])))curl -s http://localhost:9090/api/v1/rules | jq '.data.groups[].rules[] | {name, health, evaluationTime}'4. Write the unit tests
Why? A wrong rule gives a plausible but wrong dashboard: only a test reveals it.
Intests.yml, cover two cases: 10% errors (ratio 0.1) and no errors (ratio 0). Run the tests, then remove theor ... * 0part of the ratio, see the second test fail, and put it back.See the correction
rule_files: - rules.yml evaluation_interval: 1m tests: - name: 10% errors interval: 1m input_series: - series: 'prometheus_http_requests_total{job="api",handler="/a",code="200"}' values: '0+54x10' - series: 'prometheus_http_requests_total{job="api",handler="/a",code="500"}' values: '0+6x10' promql_expr_test: - expr: job:prometheus_http_requests:rate5m eval_time: 10m exp_samples: - labels: 'job:prometheus_http_requests:rate5m{job="api"}' value: 1 - expr: job:prometheus_http_requests_errors:ratio_rate5m eval_time: 10m exp_samples: - labels: 'job:prometheus_http_requests_errors:ratio_rate5m{job="api"}' value: 0.1 - name: no errors, the ratio is 0 and not empty interval: 1m input_series: - series: 'prometheus_http_requests_total{job="api",handler="/a",code="200"}' values: '0+60x10' promql_expr_test: - expr: job:prometheus_http_requests_errors:ratio_rate5m eval_time: 10m exp_samples: - labels: 'job:prometheus_http_requests_errors:ratio_rate5m{job="api"}' value: 0docker compose exec prometheus promtool test rules /etc/prometheus/tests.yml5. Measure the gain
Why? An optimisation is measured.
Compare the samples read by the original query and by the recorded series, then find the evaluation time of your rules withprometheus_rule_group_last_duration_seconds. You should see a single sample for the recorded series and several hundred for the original query (the value depends on your instance).See the correction
for q in 'sum by (job) (rate(prometheus_http_requests_total[5m]))' 'job:prometheus_http_requests:rate5m'; do curl -s --get --data-urlencode "query=$q" --data-urlencode 'stats=all' \ http://localhost:9090/api/v1/query | jq .data.stats.samples.totalQueryableSamples done
Difficulty level : ●●●○○ (3/5)
My progress
Sign in to track your progress and take notes. Sign in
Course Glossary
Alerting
The process of notifying teams (via email, Slack, Teams) when a specific event, threshold breach, or anomaly is detected.
Architecture
The overall structural design of an IT system, defining its various components, their relationships, and the principles guiding its evolution.
OpenTelemetry
An open source framework providing standards, APIs, and SDKs to collect and export observability data (traces, metrics, logs) in an agnostic way.
Recommended Articles
Prometheus recording rules: speeding up your queries and dashboards
Understand and master Prometheus recording rules: evaluation, naming convention, pitfalls (ratios...
Bonnes pratiques Prometheus : métriques, cardinalité, règles et exploitation
Bonnes pratiques Prometheus : nommage des métriques, labels et cardinalité, intervalles de scrape...
Mesurer des SLI avec Prometheus
Implémenter des SLI de disponibilité et de latence avec Prometheus : métriques nécessaires, requê...
Mimir : ruler, Alertmanager et mimirtool
Évaluer des règles d'enregistrement et d'alerte dans Mimir, configurer l'Alertmanager multi-tenan...
Alerter sur les logs avec le Ruler de Loki
Mettre en place des alertes et des recording rules LogQL avec le Ruler Loki : configuration, fich...
Générer ses SLO Prometheus avec Sloth
Décrire un SLO en quelques lignes avec Sloth et générer automatiquement règles d'enregistrement m...
Thanos Ruler : règles et alertes sur la vue globale
Évaluer des règles d'enregistrement et d'alerte sur l'ensemble des clusters avec Thanos Ruler : c...
PromQL : introduction au langage de requête de Prometheus
Apprendre PromQL, le langage de requête de Prometheus : sélecteurs, rate, sum by, histogrammes et...
Écrire de bonnes règles d'alerte Prometheus (et les tester)
Concevoir des alertes utiles : alerter sur les symptômes, choisir for et les seuils, labels de sé...