Back to Blog
    Incident ManagementUpdated August 3, 202615 min read

    Alert Fatigue: Smart Alerting for On-Call Teams

    By AmirReliability & Network Engineering
    Share
    Alert Fatigue: Smart Alerting for On-Call Teams

    The page at 03:12 is the seventh of the night. The first six were a check flapping on a single region, a disk crossing 80% on a host that has sat at 79% for a year, and four notifications about the same failed deploy. By the seventh, acknowledging has stopped being a decision — it's a reflex performed half-asleep, and the person doing it could not tell you what the alert said.

    That's alert fatigue, and it is usually described as a human problem: people are tired, people should care more. It isn't. It's a measurement problem. Every one of those six alerts is countable, attributable to a specific check, and deletable. Teams stay fatigued not because the noise is mysterious but because nobody owns the job of measuring it.

    What alert fatigue actually costs

    A study by PagerDuty found that 49% of on-call engineers experience alert fatigue, leading to slower response times and, ironically, more missed critical incidents.

    The mechanism is worth being precise about, because it explains why "just be more careful" fails. Noise doesn't make people miss alerts by making them careless. It trains a rational response: when 90% of pages require no action, the fastest correct strategy for the other 10% is to acknowledge first and read later. That habit is invisible in your metrics until the one page that mattered gets the same treatment.

    It shows up in three places you can already see:

    • Acknowledgement time drifts upward, because the alert has to compete for attention. This is the MTTA and MTTR damage, and it's the easiest to quantify.
    • Escalations stop meaning anything. Once the secondary is paged on routine noise, a genuine step-2 escalation carries no information.
    • People leave the rotation. Off-hours interruption load is one of the most cited reasons engineers refuse on-call, and it costs more than any monitoring tool.

    The fix isn't fewer monitors. Monitor everything you can afford to — the cost of alert fatigue comes from what you notify on, and those are separate decisions. Detection should be broad; notification should be narrow.

    Diagnose the noise before you tune anything

    Most alert-noise projects start with someone raising thresholds by instinct. Measure first — one week of alert history is enough to build this table for your own team:

    Signal How to compute it Healthy range What a bad number means
    Alerts per on-call shift Total notifications ÷ shifts Under 5 The rotation is a queue, not an exception path
    Actionability rate Alerts that led to a human action ÷ total Above 80% Most pages are informational and shouldn't be pages
    Self-resolving rate Alerts that cleared before anyone responded ÷ total Under 10% You're alerting on transients; the system healed itself
    Top-3 concentration Share of volume from your three noisiest checks Under 30% A handful of checks is producing most of your fatigue
    Off-hours pages per engineer per week Pages outside business hours ÷ engineers Under 2 The rotation is unsustainable regardless of anything else
    Repeat rate Alerts firing on the same cause more than 3× in a week Near zero You have a known problem being re-announced instead of fixed

    The ranges are starting points to argue with, not laws. The number that matters most is top-3 concentration, because it's the one that makes the work tractable: in most teams a small number of checks generates the majority of the noise, so the first week of cleanup is a short list rather than a re-architecture.

    The actionability test

    Every alert has to answer one question:

    Does this require a human to make a decision in the next N minutes?

    There are only three honest answers, and they map to the three things you can actually do:

    Answer What it is Where it goes
    Yes, now An alert Paging channel, on-call
    Yes, but not tonight A notification Team chat, business hours
    No Information Dashboard or ticket — not a notification

    The third row is where most fatigue is manufactured. "Deploy completed", "backup finished", "certificate renews in 30 days", "CPU at 75%" — all useful, none of them requiring a decision. They belong on a dashboard you look at deliberately, or in a weekly digest. Routing them to the same channel as a paging alert doesn't just add volume; it teaches people that the channel is low-stakes.

    If an alert can't produce a specific answer to "what would you do about this right now?", it isn't an alert. Which severity it gets and which channel it goes to is a separate decision — that's the severity and routing question, and it only applies to the rows that survive this test.

    The five sources of noise, and the fix for each

    1. Transients treated as incidents

    A single failed check could be a network hiccup between your probe and your server. Alerting on it is alerting on the internet's weather.

    The fix is confirmation logic, not a higher threshold:

    • Duration: a CPU spike lasting 10 seconds is normal; one lasting 10 minutes is a problem. Require the condition to persist.
    • Consecutive failures: require 2–3 failed checks before notifying.
    • Multi-region confirmation: for external checks, require failure from more than one probing node before declaring an outage. A single node failing is more likely to be about that node.

    This alone usually removes most of the self-resolving rate above, and it costs you very little detection time — three 60-second checks is a three-minute delay on a real outage, against dozens of false pages avoided.

    2. One cause, many alerts

    A database primary goes down and you get eleven notifications: the database check, the six services that depend on it, the API latency alert, and two synthetic checks. Eleven pages, one incident, one action.

    The fix is dependency awareness and grouping — suppress dependent alerts when their upstream is already failing, and collapse alerts sharing a cause into a single notification thread. Where your tooling can't express the dependency, alert on the user-facing symptom rather than on every component beneath it. One "checkout is failing" page is worth more than eleven component pages, and it's also the classification that severity levels are meant to be based on.

    3. Alerts nobody owns

    An alert with no owner is never tuned and never deleted. It fires, someone acknowledges it, and the cycle repeats for two years.

    Every notifying check needs a named owner — a person or a team, recorded where the check is configured, not in a wiki nobody opens. The owner's job isn't to respond to every firing; it's to answer "should this still exist?" at review time. Unowned alerts are the ones that survive every cleanup, because deleting something nobody understands feels riskier than muting it.

    4. Thresholds at the resource limit instead of at the risk of impact

    "Disk at 90%" is a threshold set where the resource runs out, not where you need to act. On a slow-filling volume it's a month of warning; on a log partition during an incident it's four minutes — the same number, two completely different alerts.

    Alert on the trend, not the level: projected time to exhaustion is the actionable form ("this volume fills in under 12 hours"). The same logic applies to error rates and latency — a static threshold either fires constantly during normal peaks or misses a slow degradation entirely. This is what anomaly detection is for: comparing behaviour against the pattern for that host at that hour rather than a number you guessed once.

    5. Planned work

    Deployments, migrations, and reboots generate exactly the signals you built alerts to catch. If planned work reaches the paging channel, you're training people to assume any alert during business hours is probably a deploy.

    Maintenance windows suppress notifications for specific services during a defined period. The discipline that matters is scheduling them before the work, which means the deploy process has to include it — a maintenance window created after the pages go out has already done the damage.

    Make the surviving alerts carry a diagnosis

    An alert that says "Server is down" is barely useful. One that says "Server is down: disk /var/log is 100% full, causing MySQL to crash" tells you exactly what to fix.

    This matters for fatigue and not just for speed. A vague alert forces the responder to open a laptop and investigate before they can even judge whether it's real, which makes every page expensive regardless of severity. An alert carrying the failing condition, the recent values, and a link to the check's history can often be triaged from a phone screen in fifteen seconds — and a cheap page is a page people don't resent.

    Three things every notification should include: what failed (specific condition and value), what it affects (service, not just hostname), and where to look next (a link to the check, dashboard, or runbook). Root cause analysis turns alerts from symptoms into diagnoses.

    The review ritual that keeps it from coming back

    Cleanup is not a project you finish. Noise regrows every time someone adds a check during an incident and never revisits it. What keeps volume down is a recurring review with teeth:

    1. Every two weeks, list the top 10 alerts by volume. Not by severity — by count.
    2. Each one gets a verdict: fix, downgrade, or delete. "Leave it" is not on the list. If it fired ten times and produced no action, it isn't earning its place.
    3. Default to delete. An alert you deleted and later miss is one commit to restore. An alert that trains people to ignore their phone costs you the next real incident.
    4. Track alerts per shift as a number the team owns, the way you'd track error budget. When it rises, cleanup gets scheduled — not discussed.

    Ten minutes every two weeks is enough. The reason to make it a ritual rather than a heroic quarterly effort is that the heroic version always loses to whatever is on fire that week.

    A worked example

    One team's alert volume over six weeks of doing exactly the above:

    Week 0   Baseline
             214 notifications / week, 38 to the paging channel
             Actionability rate 21%. Top 3 checks = 61% of volume.
    
    Week 1   Deleted 9 informational alerts (deploy + backup notices)
             Moved certificate expiry to a weekly digest
             214 -> 121 / week
    
    Week 2   Added 3-consecutive-failure + 2-region confirmation to
             external HTTP checks
             Self-resolving rate 34% -> 6%
             121 -> 74 / week
    
    Week 3   Grouped 11 dependent service checks behind the database check
             Assigned an owner to every remaining notifying check
             74 -> 52 / week
    
    Week 5   Replaced 4 static disk thresholds with time-to-full projection
             Maintenance windows added to the deploy pipeline
             52 -> 31 / week, 9 to the paging channel
    
             Actionability rate 21% -> 84%. MTTA 14 min -> 4 min.
             Zero incidents missed during the six weeks.
    

    The MTTA improvement is the part worth noticing. Nothing about detection changed — the checks run at the same interval and catch the same failures. Acknowledgement got four times faster because a page became rare enough to be worth reading.

    Mistakes that quietly make it worse

    Muting instead of deleting. A muted alert is still configured, still owned by nobody, and still there for the next person to un-mute during an unrelated incident. Mute is a tool for the next six hours, not a decision.

    Raising thresholds until nothing fires. This is the overcorrection, and it produces a monitoring setup that is quiet because it is blind. The goal is a high actionability rate, not a low alert count — one page a week that always matters beats zero pages and an outage your customers report first.

    Adding a channel instead of removing an alert. When the paging channel gets noisy, the instinct is to route some alerts to a new Slack channel. Now you have two channels, the same volume, and one that nobody has agreed to watch. Fewer alerts, not more destinations. Which channel each severity uses is a routing decision, and it doesn't solve volume.

    Alerting per host instead of per service. Twenty web servers behind a load balancer should not produce twenty alerts when a bad deploy hits all of them. Alert on the service-level symptom and let the per-host data live in the dashboard.

    Treating acknowledgement as resolution. If acknowledging silences an alert permanently, people will acknowledge to make the noise stop and the underlying condition will persist. Acknowledgement should mean "I'm on it", with re-alerting if the condition is still true later.

    Wiring it up in Xitoring

    The controls that matter for noise are all configuration, not engineering. Triggers support duration and consecutive-failure conditions, so transients never reach a human. Checks confirm from multiple probing nodes before declaring an external failure. Escalation policies define the ladder and its wait times, so an unacknowledged alert climbs on its own instead of being broadcast to everyone at once. Maintenance windows keep planned work out of the alert stream, and anomaly detection covers the degradation that static thresholds either miss or over-report.

    Channel assignment is where the routing table lives: over twenty notification channels mean informational alerts can go to chat or email while the genuinely urgent ones use something that interrupts. Plain-English root cause analysis puts the failing condition in the notification itself, which is what makes a page cheap to triage.

    The free plan covers 8 checks without a credit card — enough to instrument the handful of user-facing flows that deserve to wake someone, which is also the fastest way to find out how much of your current alert volume was never about them.

    Frequently Asked Questions

    What is alert fatigue?

    Alert fatigue is the desensitization that follows sustained exposure to alerts that don't require action. It isn't carelessness — it's an adaptation. When most pages need no response, acknowledging quickly and investigating later becomes the efficient strategy, and that habit then applies to the page that did matter. The practical definition is measurable rather than emotional: if your actionability rate is low and acknowledgement times are drifting up, you have alert fatigue regardless of how anyone feels about it.

    How many alerts per week is too many?

    Volume matters less than the share that need action. Under five notifications per on-call shift with an actionability rate above 80% is a healthy shape; twenty per shift where most need no action is not, even if none of them wake anyone. Two numbers to watch are off-hours pages per engineer per week — more than two is a retention problem — and the share of volume coming from your three noisiest checks, which tells you whether cleanup is a short list or a real project.

    How do I reduce alert noise without missing incidents?

    Cut non-actionable notifications first, since deleting a deployment notice cannot cause a missed incident. Then add confirmation logic — consecutive failures and multi-region agreement — which trades a couple of minutes of detection time for most of your false positives. Then group alerts that share a cause. Only after that should you touch thresholds on real conditions, and prefer trend-based conditions like projected time-to-full over static levels. Done in that order, the risky changes come last and against a much quieter baseline.

    Should I delete an alert that caught a real incident once?

    Usually yes, if it has produced dozens of non-actionable firings since. The relevant comparison isn't "did this ever help" but "does it help more than it costs" — and a noisy alert's cost is paid on every other alert, by making all of them less likely to be read. If the underlying condition genuinely matters, the answer is a better-formed alert on the user-facing symptom, not the preservation of a bad one that happened to fire on the right day.

    Does alert fatigue affect MTTR?

    It affects the acknowledgement stage most directly: when pages are routinely noise, they compete for attention and time-to-acknowledge rises. Because acknowledgement sits inside mean time to resolve, that delay lands in your MTTR without any change to how fast the fix itself happens — which is why cutting noise often improves response metrics more than any tooling change. Teams that measure the stages separately can see it clearly; teams that only track MTTR see a number that got worse for no visible reason.

    Stop guessing. Start monitoring.

    Get full infrastructure visibility in under 60 seconds. No credit card required.

    Start Free Trial