Operations Reviewed

Alerting principles

A page should mean that users are being hurt, or soon will be, or that another serious harm such as lost money or data is under way, and that a person needs to act now. Alert on symptoms users feel, use causes for diagnosis, and send everything that can wait to a ticket or a dashboard. Noise is not harmless: it trains people to ignore the pager.

On this page
  1. Pages, tickets and notifications
  2. What deserves a page
  3. Symptoms, not causes
  4. Symptoms by system type
  5. What a page should contain
  6. Fewer pages per problem
  7. Keeping noise down
  8. Worked example
  9. Common mistakes

Pages, tickets and notifications

Google’s SRE book defines an alert as a notification meant for a human, delivered as a page, a ticket or an email. PagerDuty’s principle is narrower: an alert is something that requires a human to act; anything else is a notification, and notifications should never wake anyone. Its published priorities are a useful starting point:

PriorityDeliveryResponsePagerDuty’s example
HighPage, any timeImmediate human actionA production service failing 75% of requests that automation cannot fix
MediumPage in business hours onlyWithin 24 hoursA disk expected to fill in 48 hours
LowLow-urgency alertAt some pointA certificate expiring in a week
NotificationRecorded, nobody notifiedNoneA deployment succeeded

The SRE book is sceptical of email alerts in particular: they are of very limited value and quickly fill with noise. A dashboard of ongoing, non-urgent problems usually serves better.

What deserves a page

The SRE book asks these questions of every paging rule:

And it sets four tests for a page: you should be able to react with urgency, which people can only do a few times a day before fatigue sets in; every page should be actionable; every response should need intelligence, because a page that merits a robotic response should be automated; and pages should be about a novel problem.

Does someone need to act on it? no Dashboard or log, or delete it yes Does safe, deployed automation fix it? yes Let it run; page if it fails no Are users, money or data at risk? no Ticket yes Must a person act before working hours? no Ticket or business-hours alert yes Page Does someone need to act on it? no → Dashboard or log, or delete it yes ↓ Does safe, deployed automation fix it? yes → Let it run; page if it fails no ↓ Are users, money or data at risk? no → Ticket yes ↓ Must a person act before working hours? no → Ticket or business-hours alert yes ↓ Page
A starting point, adapted from the questions in Google’s SRE book. Each labelled exit sends the signal somewhere quieter than the pager; only signals that pass every step should wake someone. “At risk” includes harm users can’t see, such as losing money or data, or the alerting pipeline itself failing.

Symptoms, not causes

A symptom is what is broken from the user’s point of view; a cause is why. Page on symptoms, and keep causes on dashboards to speed up diagnosis. A symptom alert says that something is wrong, not why, so the responder needs telemetry that can be broken down by endpoint, build, customer or host to find what the failing requests have in common.

Symptom: page on thisPossible causes: diagnose with these
Checkout requests failingDatabase refusing connections; a bad deploy; a payment provider outage
Search responses slowCPU saturation; a garbage-collection storm; a slow dependency; a cold cache
Orders not reaching the warehouse systemA stuck queue consumer; an expired credential; a full disk on the broker

Why symptoms:

The Prometheus documentation puts it the same way: alert on high latency and error rates as high up the stack as possible, page on latency at only one point in a stack, and don’t page separately on lower-level errors that will show up as user-visible ones. Note that symptom and cause depend on where you stand: slow database reads are a symptom to the database team and a cause to the front-end team.

Google’s second edition of the SRE book (2026) still favours paging on SLOs, but calls “alert on symptoms” the previous edition’s mantra and builds on it in two ways. A static threshold, such as 0.05% errors for every service, wakes someone when a few requests fail on a quiet service and is too lax for a busy one, so Google learns each service’s normal behaviour with statistics or machine learning and alerts on deviations from it. And it keeps cause alerts that remain useful, such as quota and resource usage, configured centrally for every service so that nobody forgets one. The binomial test in low traffic and very high SLOs is one such statistical threshold. Observability Engineering (2nd ed., 2026) takes the opposite view of learned thresholds and of tools that group or suppress floods of alerts: it treats them as managing noise that should have been removed at the source, by deleting alerts that don’t reliably mean users are affected.

When to alert on a cause

Symptoms by system type

SystemPage when
Online servingUser-visible errors or latency breach the SLO fast enough to matter. Burn-rate alerts express this directly.
Pipelines and streamsData takes long enough to get through that users or downstream systems are affected.
Batch jobsThe job has not succeeded recently enough, and the delay threatens user-visible results. Prometheus suggests allowing at least two full runs: for a job that runs every 4 hours and takes 1 hour, about 10 hours.
CapacityUsage is on course to run out before capacity can be added. A ticket if the work can safely wait for working hours; a page if it can’t, allowing for how long adding capacity takes and some margin.

Check per request type as well as in total: Prometheus notes that problems in low-traffic requests can be drowned out by high-traffic ones.

What a page should contain

PagerDuty’s guidelines for alert content:

In Prometheus, put these in annotations. This example extends the fast-burn page from the burn-rate guide with a summary, impact, dashboard and runbook link:

groups:
  - name: checkout
    rules:
      - alert: CheckoutErrorBudgetBurn
        expr: |
          job:slo_errors_per_request:ratio_rate1h{job="checkout"} > (14.4 * 0.001)
          and
          job:slo_errors_per_request:ratio_rate5m{job="checkout"} > (14.4 * 0.001)
        labels:
          severity: page
          team: checkout
        annotations:
          summary: "Checkout failed {{ $value | humanizePercentage }} of requests over the last hour"
          description: >
            Both the 1-hour and 5-minute error ratios exceed the fast-burn threshold
            for the 99.9% SLO (14.4x the budget rate). Customers see errors at payment.
          dashboard: https://grafana.example.com/d/checkout-slo
          runbook_url: https://runbooks.example.com/checkout/error-budget-burn

Fewer pages per problem

A network partition can make hundreds of instances fail the same check at once. Alertmanager has three tools to turn that into far fewer, more useful notifications:

An example routing and inhibition fragment; it omits the receiver definitions, which you must supply:

# Routing and inhibition fragment: define the receivers (pager, ticket queue) yourself.
route:
  receiver: checkout-tickets
  group_by: [alertname, cluster]   # one notification per alert name and cluster, not per instance
  group_wait: 30s
  group_interval: 5m
  repeat_interval: 4h
  routes:
    - matchers: [severity="page"]
      receiver: checkout-pager

inhibit_rules:
  # While a cluster is unreachable and paging, mute only the per-service
  # reachability alerts that it explains, in the same environment and cluster.
  - source_matchers: [alertname="ClusterUnreachable", severity="page", cluster=~".+"]
    target_matchers: [alertname=~"ServiceUnreachable|ProbeFailed", cluster=~".+"]
    equal: [environment, cluster]

Inhibition is easy to get dangerously wrong:

Keeping noise down

One caution from the Workbook: for alerts already based on SLOs and symptoms, loosening the threshold is rarely the right answer to being paged. The page means users were hurt; fix the system, or revisit the SLO deliberately.

Worked example

A raw count versus an error ratio

A checkout service with a 99.9% SLO over 30 days has a cause-style rule, “page when more than 50 errors a minute”, alongside the burn-rate page at 14.4× over 1 hour.

  1. Busy afternoon, 20,000 requests a minute, with 50 errors a minute. The count rule pages. The error ratio and burn rate are:50 ÷ 20,000 = 0.25%; 0.25% ÷ 0.1% = 2.5×
  2. At 2.5× the 30-day budget would last30 days ÷ 2.5 = 12d
  3. Quiet night, 30 requests a minute, and checkout fails completely. At most 30 errors a minute, so the count rule never fires. The burn-rate page’s 1-hour window crosses its threshold after1.44% ÷ 100% × 60 min = 51.8s

The count rule woke someone for a slow leak that a ticket could handle, and slept through a total outage. The ratio-based page did the opposite: no page in the afternoon, and a page at night in under a minute plus scrape and evaluation delays. At very low traffic the ratio needs the safeguards in the burn-rate guide.

Common mistakes

Sources: Google, Site Reliability Engineering, 1st ed., ch. 6 “Monitoring Distributed Systems”; The Site Reliability Workbook, ch. 8 “On-Call”; Site Reliability Engineering, 2nd ed. (2026), ch. 9 “Observability and Monitoring” (“From Static Thresholds to Intelligent Alerting”) and ch. 10 “Incident Management and On-Call” (“Optimal Paging Load”); Prometheus, Alerting, Alerting rules and Alertmanager; PagerDuty, Incident Response: Alerting Principles; Charity Majors, Liz Fong-Jones and George Miranda, Observability Engineering, 2nd ed. (2026), ch. 8 “Getting Started with Observability Analysis” (the core analysis loop) and ch. 11 “Using Service Level Objectives for Reliability” (what versus why, alerts added after incidents, AIOps).