14 min read

Prometheus Grafana Alerting and Burn Rate Design

Prometheus Grafana Alerting and Burn Rate Design

We've all lived through it: getting paged at 3 AM because a server's CPU hit 85% for two minutes, only to log in and find out everything is completely fine. Static threshold alerts like these are the fastest way to burn out an on-call rotation. They generate endless alert fatigue, wake engineers for non-actionable blips, and—worst of all—often completely miss the slow, creeping latency regressions that actually impact users. The fix? Stop alerting on resource metrics and start alerting on symptoms. By adopting the Multi-Window Multi-Burn-Rate alerting methodology (popularized by Google's SRE teams), you can configure Prometheus and Grafana to page you only when your real-time error budget is actually burning down.

What Are SLIs, SLOs, and Error Budgets in SRE Alerting Architecture?

SLIs, SLOs, and Error Budgets form the foundational framework of Site Reliability Engineering alerting by defining measurable performance indicators, target availability goals, and acceptable failure allowances for production applications. A Service Level Indicator (SLI) is a quantifiable metric that measures the real-time quality of a service, such as the ratio of successful HTTP requests to total requests or the 99th percentile request latency. A Service Level Objective (SLO) sets the target threshold for an SLI over a rolling compliance period like thirty days, declaring that the service must satisfy performance goals for a specified percentage of total requests.

SLI SLO Error Budget Fundamentals

The Error Budget represents the mathematical inverse of your SLO, defining the maximum allowable unreliability your application can experience over the compliance window. For instance, if an API service defines an availability SLO of 99.9% over thirty days, its error budget is 0.1% (100% - 99.9%). If the service receives ten million total requests during those thirty days, the engineering team can experience up to ten thousand failed requests before breaching their service level agreement.

Error budgets establish a clear quantitative boundary for balancing feature development velocity against system stability. When a service retains plenty of error budget, development teams can push new software deployments aggressively. Conversely, when error budget drops toward zero, deployment freezes take effect until system stability recovers.

Here is a calculation example demonstrating availability SLO and error budget mathematics over a 30-day window:

+-----------------------------------------------------------------------------------+
| 30-Day Rolling Window (Total Requests: 10,000,000)                               |
+-----------------------------------------------------------------------------------+
| Target Availability SLO: 99.9%  =====>  Successful Requests Goal: 9,990,000     |
| Total Error Budget:      0.1%   =====>  Max Allowed Failed Requests: 10,000        |
+-----------------------------------------------------------------------------------+
| Burn Rate 1x   =====> Consumes 100% Error Budget exactly in 30 days (13.8 req/hr)  |
| Burn Rate 14.4x ====> Consumes  2% Error Budget in 1 Hour (Urgent Page Alert)     |
+-----------------------------------------------------------------------------------+
Advertisement

How Does Multi-Window Multi-Burn-Rate Alerting Prevent Alert Fatigue?

Multi-Window Multi-Burn-Rate alerting prevents alert fatigue by requiring error rates to breach consumption thresholds simultaneously across both short and long time evaluation windows before firing an alert. Traditional single-window alerts suffer from inherent trade-offs: short evaluation windows (like five minutes) trigger false positives on temporary traffic spikes that resolve on their own, while long evaluation windows (like six hours) delay critical notifications during severe outages and reset slowly after issues are resolved.

Multi-Window Multi-Burn-Rate Architecture

Multi-burn-rate design resolves these limitations by measuring error budget consumption velocity across multiple time windows. A burn rate of 1x means your application will consume exactly one hundred percent of its error budget over the thirty-day compliance window. A burn rate of 14.4x indicates that your application is consuming error budget fourteen times faster than normal, burning through two percent of the total error budget in just one hour.

To ensure high alert precision, the multi-window approach requires two conditions to be met simultaneously: the long window verifies that a significant amount of error budget has been consumed, while the short window verifies that the failure event is actively ongoing. Requiring both conditions prevents sending paging notifications for brief transient errors that have already stopped.

Here is a standard SRE Multi-Burn-Rate matrix mapping severity routes to burn rate thresholds:

Alert Severity LevelError Budget BurnedLong Window SizeShort Window SizeBurn Rate MultiplierTarget Notification Route
Critical Page2% Error Budget1 Hour5 Minutes14.4x Burn RatePagerDuty / On-Call SRE
Warning Page5% Error Budget6 Hours30 Minutes6.0x Burn RatePagerDuty / Secondary
Ticket / Warning10% Error Budget3 days6 Hours1.0x Burn RateJira Ticket / Slack Channel

How Do You Write PromQL Rules for Latency and Error Rate Burn Rates?

You write PromQL rules for latency and error rate burn rates by defining recording rules to pre-calculate request rates over various time windows, followed by alerting rules that evaluate burn rate multipliers against target error budgets. Pre-calculating raw request rates using Prometheus recording rules reduces CPU query overhead on your Prometheus server during alert evaluation loops.

PromQL Alerting Rule Definitions

The first step in implementing burn rate alerts is calculating the ratio of bad events to total events. For an availability SLI, bad events represent HTTP responses with 5xx status codes. For a latency SLI, bad events represent HTTP requests whose response latency exceeds your defined target threshold (for example, requests taking longer than 500ms).

Let me show you a complete Prometheus recording rule configuration file defining error rate metrics over multiple time windows:

groups:
  - name: service_sli_recording_rules
    rules:
      # 5-minute error rate ratio
      - record: job:http_requests_error_rate:ratio_rate5m
        expr: |
          sum(rate(http_requests_total{status=~"5.."}[5m])) by (job)
          /
          sum(rate(http_requests_total[5m])) by (job)

      # 1-hour error rate ratio
      - record: job:http_requests_error_rate:ratio_rate1h
        expr: |
          sum(rate(http_requests_total{status=~"5.."}[1h])) by (job)
          /
          sum(rate(http_requests_total[1h])) by (job)

      # 30-minute error rate ratio
      - record: job:http_requests_error_rate:ratio_rate30m
        expr: |
          sum(rate(http_requests_total{status=~"5.."}[30m])) by (job)
          /
          sum(rate(http_requests_total[30m])) by (job)

      # 6-hour error rate ratio
      - record: job:http_requests_error_rate:ratio_rate6h
        expr: |
          sum(rate(http_requests_total{status=~"5.."}[6h])) by (job)
          /
          sum(rate(http_requests_total[6h])) by (job)

Once these recording rules exist in Prometheus, construct your alerting rules to evaluate the multi-window multi-burn-rate expressions:

  - name: service_slo_burn_rate_alerts
    rules:
      # Critical Page: 14.4x burn rate over 1h and 5m windows (2% budget in 1 hour)
      - alert: APIAvailabilityErrorBudgetBurnCritical
        expr: |
          (job:http_requests_error_rate:ratio_rate1h > (14.4 * 0.001))
          and
          (job:http_requests_error_rate:ratio_rate5m > (14.4 * 0.001))
        for: 2m
        labels:
          severity: critical
          tier: platform
        annotations:
          summary: "API Service consuming error budget rapidly (14.4x burn rate)"
          description: "API Service error rate is {{ $value | printf "%.4f" }} over 1 hour, consuming 2% of 30-day error budget."

      # Warning Ticket: 6x burn rate over 6h and 30m windows (5% budget in 6 hours)
      - alert: APIAvailabilityErrorBudgetBurnWarning
        expr: |
          (job:http_requests_error_rate:ratio_rate6h > (6.0 * 0.001))
          and
          (job:http_requests_error_rate:ratio_rate30m > (6.0 * 0.001))
        for: 15m
        labels:
          severity: warning
          tier: platform
        annotations:
          summary: "API Service consuming error budget steadily (6x burn rate)"
          description: "API Service error rate is {{ $value | printf "%.4f" }} over 6 hours, consuming 5% of 30-day error budget."

Notice how 14.4 * 0.001 converts the burn rate multiplier into an explicit error threshold for a 99.9% availability SLO (error_budget = 0.001). If your target SLO is 99.5% (error_budget = 0.005), update the PromQL multiplier to 14.4 * 0.005 (0.072 error rate threshold).

How Do You Configure Alertmanager Routing for Dynamic Alert Escalation?

You configure Alertmanager routing for dynamic alert escalation by defining a hierarchical routing tree in alertmanager.yml that matches alert labels like severity and tier to route notifications to designated receivers. Alertmanager acts as the central notification engine for Prometheus, handling alert deduplication, grouping, inhibition, and routing across external notification receivers like PagerDuty, Opsgenie, and Slack.

Alertmanager Routing and Severity Controls

The routing tree uses matchers arrays to filter incoming alerts based on label key-value pairs. Configuring group_by parameters allows Alertmanager to consolidate multiple simultaneous alerts originating from the same service tier into a single summary notification, preventing notification floods during large infrastructure outages.

Here is a complete alertmanager.yml configuration demonstrating multi-channel escalation routing:

global:
  resolve_timeout: 5m
  pagerduty_url: 'https://events.pagerduty.com/v2/enqueue'

route:
  group_by: ['alertname', 'cluster', 'service']
  group_wait: 30s
  group_interval: 5m
  repeat_interval: 4h
  receiver: 'slack-default'
  routes:
    - matchers:
        - severity = critical
      receiver: 'pagerduty-oncall'
      continue: true
    - matchers:
        - severity = warning
      receiver: 'slack-warnings'

inhibit_rules:
  - source_matchers:
      - alertname = NodeNetworkDown
    target_matchers:
      - alertname = APIAvailabilityErrorBudgetBurnCritical
    equal: ['cluster', 'instance']

receivers:
  - name: 'slack-default'
    slack_configs:
      - channel: '#devops-alerts'
        send_resolved: true
        text: "Alert: {{ .CommonAnnotations.summary }}
Description: {{ .CommonAnnotations.description }}"

  - name: 'pagerduty-oncall'
    pagerduty_configs:
      - service_key: 'pd-integration-key-production'
        severity: 'critical'

  - name: 'slack-warnings'
    slack_configs:
      - channel: '#sre-warning-tickets'
        send_resolved: true

The inhibit_rules section provides vital alert suppression capabilities. In this configuration, if an entire Kubernetes node experiences a network outage (NodeNetworkDown), Alertmanager automatically suppresses child service alerts like APIAvailabilityErrorBudgetBurnCritical on that node. Inhibiting downstream symptoms prevents on-call engineers from receiving dozens of redundant pages for a single root cause failure.

Advertisement

How Do You Build Grafana Alerting Dashboards for Real-Time SLO Visibility?

You build Grafana alerting dashboards for real-time SLO visibility by creating dashboard panels that visualize current error budget balances, historical burn rates, and active alert state thresholds. Dashboards serve as the primary operational workspace during incident response, allowing engineers to verify whether alert notifications correspond to real customer impact and estimate how many hours of error budget remain before SLO breach.

Grafana Alert Dashboard and SLO Visuals

A well-architected SRE dashboard features three primary visual zones: an executive summary row displaying top-level SLO compliance percentages, a middle row plotting multi-window error budget burn rate curves, and a bottom row displaying active Prometheus alert instances and system metrics. Using Grafana's Stat panel visualization allows you to color-code remaining error budget values, displaying green when budget exceeds fifty percent, yellow when budget drops below twenty percent, and red when budget is exhausted.

Here is a sample Grafana dashboard panel JSON definition tracking 30-day remaining error budget percentages:

{
  "type": "stat",
  "title": "30-Day Remaining Error Budget",
  "gridPos": { "h": 6, "w": 8, "x": 0, "y": 0 },
  "targets": [
    {
      "datasource": "Prometheus",
      "expr": "(1 - (sum(increase(http_requests_total{status=~"5.."}[30d])) / sum(increase(http_requests_total[30d])))) / 0.001 * 100",
      "format": "time_series",
      "legendFormat": "Remaining Budget %"
    }
  ],
  "fieldConfig": {
    "defaults": {
      "unit": "percent",
      "thresholds": {
        "mode": "absolute",
        "steps": [
          { "color": "red", "value": null },
          { "color": "yellow", "value": 20 },
          { "color": "green", "value": 50 }
        ]
      }
    }
  }
}

In addition to static visualization panels, Grafana Unified Alerting allows you to create alerting rules directly within the Grafana UI using multi-datasource queries. Grafana Alerting supports contact points, notification policies, and silences identical to Alertmanager, enabling platform teams to manage alerting policies alongside dashboard visualizations in unified user workflows.

How Do You Tune Alerting Thresholds and Test Burn Rate Rules?

You tune alerting thresholds and test burn rate rules by simulating synthetic traffic failures using load generators like k6, reviewing historical metric data, and running dry-run PromQL rule evaluations against Prometheus historical data. Before deploying new burn rate alerting rules to production, you must validate that rules trigger reliably under real failure conditions without firing false alarms during normal traffic shifts.

Synthetic testing involves generating artificial HTTP traffic using load testing tools while introducing controlled fault injections (such as forcing a subset of API requests to return HTTP 500 errors). Monitoring how quickly Prometheus evaluates recording rules and fires APIAvailabilityErrorBudgetBurnCritical alerts verifies that short window evaluation periods operate correctly under real traffic volume.

To perform dry-run rule testing against historical Prometheus metrics, use promtool, the official Prometheus rule testing CLI utility:

# 1. Validate syntax of Prometheus alerting rules file
promtool check rules rules/slo_alerts.yml

# 2. Run unit test suite against synthetic time-series test data
promtool test rules tests/slo_alerts_test.yml

Unit testing alerting rules with promtool involves defining synthetic time-series inputs in a YAML test file and declaring expected alert firing states at specific time offsets.

# Unit test file: tests/slo_alerts_test.yml
rule_files:
  - ../rules/slo_alerts.yml

evaluation_interval: 1m

tests:
  - interval: 1m
    input_series:
      - series: 'http_requests_total{job="api", status="200"}'
        values: '1000+1000x60'
      - series: 'http_requests_total{job="api", status="500"}'
        values: '0+50x60'
    alert_rule_test:
      - eval_time: 10m
        alertname: APIAvailabilityErrorBudgetBurnCritical
        exp_alerts:
          - labels:
              severity: critical
              tier: platform
            annotations:
              summary: "API Service consuming error budget rapidly (14.4x burn rate)"

Running unit tests in your CI/CD pipeline ensures that modifications to PromQL alerting rules or metric label schemas don't break alerting logic or introduce invalid PromQL syntax into production monitoring clusters. Combining Prometheus backend rules for critical SRE pages with Grafana alerting for operational team notifications yields a solid monitoring architecture.

What Are the Frequently Asked Questions About Prometheus Alerting Burn Rates?

Why shouldn't you use CPU or memory metrics for primary paging alerts?

You shouldn't use CPU or memory metrics for primary paging alerts because high resource utilization does not directly correspond to customer-facing application degradation. Modern applications are designed to use available CPU and memory resources efficiently under heavy traffic. Triggering pages on high CPU usage causes alert fatigue when applications run smoothly despite high resource consumption. Paging alerts should focus strictly on SLIs like latency, error rates, and availability that measure real user experience.

What is the difference between a 14.4x burn rate alert and a 6x burn rate alert?

The difference lies in the consumption velocity of your error budget and the urgency of the resulting notification. A 14.4x burn rate consumes two percent of your total thirty-day error budget in one hour, signaling a severe outage that requires immediate page escalation to an on-call engineer. A 6x burn rate consumes five percent of your error budget in six hours, indicating a slower degradation that requires attention within a few hours via warning notifications or ticketing channels.

How do you handle low-traffic services where small error counts cause large burn rate spikes?

You handle low-traffic services by incorporating minimum request count thresholds into your PromQL alerting expressions or extending short evaluation window sizes. On low-traffic services receiving only ten requests per minute, a single failed request represents a ten percent error rate, triggering false burn rate spikes. Adding and sum(rate(http_requests_total[5m])) > 5 ensures that burn rate alerts evaluate only when total request throughput is sufficient to yield statistically valid results.

How do you alert on latency SLOs using Prometheus histograms?

You alert on latency SLOs using Prometheus histograms by tracking the proportion of requests served faster than your latency threshold using le bucket labels. For example, if your SLO mandates that 95% of requests must complete under 200ms, your bad event ratio PromQL query is 1 - (sum(rate(http_request_duration_seconds_bucket{le="0.2"}[5m])) / sum(rate(http_request_duration_seconds_count[5m]))). This query evaluates the percentage of requests breaching your 200ms target.

What is the purpose of the for clause in Prometheus alerting rules?

The for clause (for example for: 2m) instructs Prometheus to wait until an alerting expression remains true continuously for the specified duration before transitioning the alert state from Pending to Firing. Using a short for clause prevents transient metric dropouts or single-scrape query anomalies from sending premature alerts to Alertmanager while allowing real sustained failure events to fire promptly.

How do you manage scheduled maintenance windows to prevent alerting alerts during deployments?

You manage scheduled maintenance windows by creating Silences in Alertmanager or Grafana Alerting during planned maintenance operations. An Alertmanager Silence matches alert labels (for example service="payment-api") and suppresses notifications for a defined timeframe. Silences can be created interactively via the Alertmanager Web UI or automated via API calls from CI/CD deployment scripts before executing maintenance tasks.

Should you configure alerting rules in Prometheus or in Grafana Unified Alerting?

Configuring core infrastructure and SRE error budget alerts directly in Prometheus rule files is recommended for high availability because Prometheus evaluates alerting expressions locally next to its time-series database. Grafana Unified Alerting is ideal for team-level dashboard alerts, multi-datasource correlations, and user-friendly alert management UI workflows. Combining Prometheus backend rules for critical SRE pages with Grafana alerting for operational team notifications yields a reliable monitoring architecture.

You Might Also Like

Share this article:

Stay Updated

Get the latest posts delivered straight to your inbox.

Free Developer Utilities

Free In-Browser Developer Tools

Clean AI CLI logs, build cron expressions, decode JWTs, and calculate chmod permissions offline.

Explore Tools
Advertisement