Skip to content
ExponaBLOG
PROMETHEUS, GRAFANA & MONITORING · DAY 074 / 100

promtool: a practical guide for modern backend engineers

The Prometheus command-line tool.

Expona Admin7 min read

Introduction

Most teams running Prometheus in production eventually face a moment of truth: a typo in an alert rule goes unnoticed until alerts start firing incorrectly, or a configuration change breaks the entire scrape setup minutes before a major deployment. We've all been there, and we've all learned the hard way that catching these issues early matters. promtool: a practical guide for modern backend engineers who want to prevent these scenarios is what this article is about. The Prometheus command-line tool is your first line of defense, offering straightforward commands to validate configs, test rules, and even query metrics from the terminal before they reach production.

In this piece, we'll walk through the most valuable promtool workflows that actually save time in real deployments, backed by concrete examples from teams running high-volume monitoring infrastructure.

Check config before deploys

Configuration files are the foundation of Prometheus, and a single syntax error or misplaced indentation can take down your entire monitoring stack. Rather than finding out during a deploy or worse, in production, you can validate your configuration locally using promtool.

The most common use case is checking the main Prometheus configuration file:

yaml
promtool check config prometheus.yml

This command parses your YAML, validates the structure, and reports any errors. It checks for missing required fields, invalid scrape configurations, and inconsistencies in service discovery settings. If your config is valid, you'll see a clean success message. If not, you get a specific line number and description of the problem.

Here's a realistic example. You're adding a new scrape target for a Redis exporter and accidentally forget the targets field:

yaml
global:
  scrape_interval: 15s

scrape_configs:
  - job_name: 'prometheus'
    static_configs:
      - targets: ['localhost:9090']
  
  - job_name: 'redis'
    static_configs:
      # Missing 'targets' field here
      - labels:
          instance: 'redis-primary'

Running promtool catch this instantly:

yaml
$ promtool check config prometheus.yml
FAILED: scrape_configs[1] 'redis': config validation failed: targets is empty

You can integrate this check directly into your CI/CD pipeline as a pre-deployment gate. Many teams add it to their Makefile or deployment script:

yaml
validate-prometheus:
	promtool check config prometheus.yml
	@echo "✓ Prometheus config is valid"

deploy: validate-prometheus
	# Deploy logic here

This prevents invalid configurations from ever reaching your staging or production environment, reducing incident response time and giving your team confidence in config changes.

Check rules for syntax

Prometheus recording and alerting rules are equally critical. A syntax error in your alert rules means alerts won't fire, and your team won't know until something actually breaks. promtool rules check validates rule files before deployment.

The command syntax is straightforward:

yaml
promtool check rules alert-rules.yml

This verifies the YAML structure and also performs basic semantic validation: checking that rule names are unique within a file, that alert rules have both expr and for fields, and that duration values are properly formatted.

Consider a typical alert rule file with multiple rules:

yaml
groups:
  - name: api_alerts
    interval: 30s
    rules:
      - alert: HighErrorRate
        expr: rate(http_requests_total{status=~"5.."}[5m]) > 0.05
        for: 5m
        labels:
          severity: critical
        annotations:
          summary: "High error rate detected"
      
      - alert: ServiceDown
        expr: up{job="api-service"} == 0
        for: 1m
        # Missing 'annotations' - still valid, but often flagged as a best practice issue
        labels:
          severity: page

Running the validation:

yaml
$ promtool check rules alert-rules.yml
Checking alert-rules.yml
✓ all rules are valid

More importantly, if you have a typo like expr: missing or a malformed duration, you catch it immediately:

yaml
$ promtool check rules bad-rules.yml
FAILED: parsing alert-rules.yml: line 10: field 'for' has invalid duration 'bad-value'

Just like with configs, include this in your deployment pipeline to prevent rule changes from silently breaking your alerting system.

Test rules against sample data

Validating syntax is step one. Testing that your rules actually fire correctly with real or simulated data is step two. promtool test rules allows you to unit test alert and recording rules against sample prometheus data.

This is where monitoring truly becomes engineering: you define test cases, assert that rules evaluate as expected, and catch logical errors before rules hit production.

To use this feature, you need a test file that defines sample data points and expected rule evaluations. Here's an example test setup:

yaml
rule_files:
  - alert-rules.yml

evaluation_interval: 1m

tests:
  - interval: 1m
    input_series:
      - series: 'http_requests_total{job="api",status="500"}'
        values: '1+1x10'  # 1, 2, 3, ..., 11 at 1m intervals
      - series: 'http_requests_total{job="api",status="200"}'
        values: '100+0x10'  # 100, 100, ..., 100
      - series: 'http_requests_total{job="api"}' 
        values: '101+1x10'  # Total requests
    
    alert_rule_test:
      - eval_time: 5m
        alerting_rules:
          - alert_name: 'HighErrorRate'
            exp_alerts:
              - exp_labels:
                  job: 'api'
                exp_annotations:
                  summary: 'High error rate detected'
      
      - eval_time: 10m
        alerting_rules:
          - alert_name: 'HighErrorRate'
            exp_alerts: []  # No alert expected here

Then run the test:

yaml
$ promtool test rules rule_tests.yml
Executing rule test groups
api_alerts:  PASSED

This approach helps catch logic errors like incorrect thresholds or PromQL expressions that don't match your actual metrics. For teams managing dozens of alert rules, automated rule testing becomes as essential as unit testing application code.

Query instant metrics from the terminal

Sometimes you need to quickly verify a metric value or debug a PromQL expression without leaving the command line. promtool query instant lets you run instant queries directly against a Prometheus server.

The syntax is:

yaml
promtool query instant http://localhost:9090 'up{job="api-service"}'

This returns the current value of the up metric for your API service, formatted as a table. It's particularly useful when:

  • You're debugging a PromQL expression before putting it in a rule
  • You need to verify a metric exists and is being scraped correctly
  • You're on-call and need to quickly check a metric from an SSH session
  • You want to automate metric queries in scripts without pulling in the full Prometheus client library

For example, during a deployment, you might want to verify that a new exporter is reporting correctly:

yaml
$ promtool query instant http://prometheus.prod:9090 'redis_connected_clients{instance="redis-primary"}'
redis_connected_clients{instance="redis-primary"}  42

You can also use it in shell scripts for conditional logic:

yaml
#!/bin/bash
ERROR_RATE=$(promtool query instant http://prometheus.prod:9090 'rate(http_requests_total{status="500"}[5m])' | grep -oP '\d+\.\d+' | tail -1)

if (( $(echo "$ERROR_RATE > 0.1" | bc -l) )); then
  echo "Alert: High error rate detected ($ERROR_RATE)"
  # Trigger mitigation
fi

This bridges the gap between ad-hoc monitoring queries and automated alert responses, giving you flexibility in operational workflows.

Common mistakes

  • Forgetting to validate before committing: Teams often skip the validation step during development and only catch issues during code review or deployment. Make it a habit to run validation locally every time you modify a config or rule file.
  • Validating against the wrong Prometheus version: If your promtool version differs significantly from your production Prometheus, you might miss compatibility issues. Keep your tools in sync with your production deployments.
  • Not testing with realistic data: Rule tests are most valuable when they reflect actual scrape intervals and metric cardinality. Use sample data that mirrors your production environment closely.
  • Ignoring warnings: promtool doesn't always fail on warnings (like missing annotations), but these often indicate logical errors. Treat warnings seriously, not as optional noise.
  • Running queries without a timeout: When querying live Prometheus servers, always be aware that slow queries can impact your monitoring system. For critical diagnostic queries, use a timeout parameter if available.

Key takeaways

  • Use promtool check config and promtool check rules as pre-deployment gates in your CI/CD pipeline to catch syntax errors before they reach production.
  • Implement unit tests for alert and recording rules using promtool test rules, treating rule logic with the same rigor as application code.
  • Leverage promtool query instant for quick debugging and operational tasks from the terminal or in automation scripts.
  • Integrate promtool validation into your development workflow and deployment pipeline, not as an afterthought but as a core part of your monitoring-as-code practice.
  • Keep promtool and Prometheus versions aligned across your team to avoid subtle compatibility surprises.
ShareXLinkedInReddit

Found this useful? Support the writing.

Buy me a coffee
Written by
Expona Admin
Site administrator

Comments

Loading comments…

Leave a comment

Comments are reviewed before they appear. Be kind and stay on topic.

Related articles