A single database outage can fire hundreds of alerts. This article shows how grouping, inhibition and silence work together to compress an alert storm into one actionable summary, with ready-to-use configuration examples.
At three in the morning, the primary MySQL node times out. That single failure triggers a cascade: "connection pool exhausted", "slow query detected", "order-service 5xx", "gateway timeout" — more than two hundred alerts flood the on-call engineer's phone. The person on duty cannot tell which one to look at first, let alone trace the root cause while the queue keeps growing.
The essence of an alert storm is simple: one root cause gets re-alerted across many dimensions. When a service goes down, its upstream, its downstream, the database it depends on and the host it runs on all begin reporting errors at once. If every alert notifies independently, the human on call is buried in noise, and the signal that actually matters gets lost inside it.
The fix is not "configure fewer alerts" — that just means you miss real incidents. The fix is teaching the alerting system to recognize a single root cause and notify exactly once, so the on-call engineer sees a summary instead of a wall of pages.
Grouping merges multiple alerts triggered by the same rule within a time window into a single notification. If "CPU usage > 90%" fires thirty times on one host, you receive one notification with the trigger count and the first-trigger timestamp attached, rather than thirty separate pages.
alert_rules:
- name: cpu-high
condition: cpu_usage > 90
for: 5m
grouping:
by: [host] # merge by host
window: 10m # merge triggers within 10 minutes
The grouping dimension is the key decision, and it is worth getting right. Merge by host and one broken machine reports once; merge by service and one broken service reports once. Too coarse and you lose important detail; too fine and you are right back in a storm. A practical rule of thumb: collapse business alerts by service first, then collapse single-machine resource alerts by host. If you are unsure, start with service — it almost always matches how your on-call is actually organized.
Inhibition silences lower-priority alerts that are caused by a higher-priority alert. When a host is down, "service unreachable on that host" carries no independent diagnostic value — it is a consequence, not a separate problem — so it should be suppressed.
inhibition:
- source: host-down # triggering condition
target: service-unreachable # suppressed alert
match: [host] # link by host
Keep inhibition rules conservative. Only suppress alerts that are necessarily caused by the upstream one — for example "host down" suppressing "service alert on that host", or "database unreachable" suppressing "API 5xx" on the services that depend on it. Do not link two alerts that merely happen to share a label; over-broad inhibition hides genuinely independent failures, and those are exactly the ones that catch you off guard during an incident.
Deploys, load tests and failovers are planned work, and the alerts they produce are mostly noise. Silence turns off notifications for a defined time window; the alerts themselves are still recorded and searchable, they simply do not wake anyone up.
silence:
- match: {service: "pay-service"}
start: "2026-10-12 00:00"
end: "2026-10-12 04:00"
comment: "payment service release"
Every silence window must carry a comment. During a retrospective you need to know why there were no alerts during that period; an uncommented silence is a landmine waiting for the next incident, because nobody will remember whether it was intentional. Set a team convention: no comment, no silence.
Start with grouping — the biggest win at the lowest risk — then inhibition, and finally silence as needed. Acceptance is easy to measure: take one real incident and compute the ratio of alerts fired to root causes. When that ratio drops from dozens to one or two, the noise reduction is working.
Once all three mechanisms are in place, an incident goes from "two hundred alerts" to "one summary plus one root cause", and the on-call engineer can localize the problem in under three minutes instead of spending the first hour sorting through pages. That hour, across a year of incidents, is the real return on this work.