Back to Intelligence

The 'It Must Be a Bug' Problem: Why Alert Fatigue Makes On-Call Teams Ignore Real Incidents

SA
AlertMonitor Team
October 29, 2026
10 min read

An astronomer recently made headlines for something IT people will find painfully familiar. His survey software flagged an object far beyond Neptune — possibly a dwarf planet, possibly the smallest of its kind ever detected. A genuinely rare find. His first reaction wasn't excitement. It was suspicion: this must be a bug. He had seen so many false positives from his pipeline that his brain defaulted to "the tool is broken" instead of "the tool found something."

If that reaction sounds familiar, it's because your on-call technicians have developed the exact same reflex. When a monitoring tool sends 400 emails a day and 395 of them are noise, the safe assumption becomes "this is probably nothing." And one night, it isn't nothing. It's a file server two days from a full disk, a failed RAID member, or a client's domain controller quietly dying — and the person holding the phone reads the alert, sighs, and mutters "that check always false-alarms."

Alert fatigue is not a volume problem that gets solved with thicker skin. It's a signal quality problem that gets solved with better alerting. Here's what that looks like in practice.

What Your Current Stack Actually Does With an Alert

Walk through the typical flow in a mid-size IT department or MSP running a standalone monitor (Nagios, Zabbix, PRTG) next to an RMM (NinjaOne, ConnectWise Automate, Datto RMM) and a separate helpdesk (ConnectWise Manage, Autotask, Freshservice):

  1. A check fires. It sends an email to a distribution list.
  2. The same check fires again on the next poll cycle. Another email. Identical.
  3. Twelve technicians see twelve copies of it. Nobody owns it.
  4. Whoever notices it first RDPs into the box, figures out what's wrong, and — if there's time — manually creates a ticket in the helpdesk so there's a paper trail.
  5. The SLA clock starts whenever a human gets around to it, or whenever a user calls. Not when the problem started.

Now layer on the classic failure modes:

The cascade. A core switch flaps for ninety seconds. Every downstream device fires an "offline" alert. Forty-seven alerts in a minute and a half, all describing one problem, with the root cause buried somewhere in the pile. Your tech mutes the channel to make it stop.

The repeater. A disk check configured with a static threshold re-fires every five minutes until someone acts. The file server disk warning from Tuesday is now email #14 of the same alert. It's also the alert that mattered most this week — and it's invisible under its own copies.

The flapper. One printer or one VPN tunnel has tripped and cleared three times a week for months. Everyone has learned to ignore it. Eventually it trips and stays tripped, and it's four hours before anyone checks.

The scheduled-change storm. Patch Sunday: 60 servers reboot on a schedule. Every one of them pages "host unreachable" at 2 a.m. Your monitoring tool has no idea a maintenance window exists.

Each of these trains your team the same way the astronomer was trained: rare-and-real looks exactly like constant-and-fake.

Why These Gaps Exist

It's not because your team configured things badly. The tools were never designed to talk to each other:

  • Siloed architectures. The network monitor, the RMM agent, and the helpdesk each maintain their own idea of what a "device" is. There's no shared object model, so an alert can't natively become a ticket with device history, SLA data, and client context attached.
  • Thresholds tuned for coverage, not signal. Default monitoring configs are built to never miss anything, which mathematically guarantees floods of false positives. Nobody tunes them because tuning 400 checks by hand is a week of work nobody has.
  • No awareness of planned state. Maintenance windows, change schedules, and known-noisy periods live in a spreadsheet. The monitor can't see them, so it can't suppress them.
  • Escalation as an afterthought. "Escalation" in most stacks means an email alias with everyone on it. There's no routing by severity, no time-based ladders, no client-specific policies for MSPs.

What It Actually Costs

  • Mean time to acknowledge. Alerts that arrive as undifferentiated email routinely sit 20–45 minutes before a human triages them. Overnight, longer. Your monitoring detected the problem in 30 seconds and then wasted its head start.
  • Real incidents dismissed as bugs. This is the expensive one. The one alert that gets written off as "known noise" and turns out to be real turns a 10-minute fix into a half-day outage — and the users always call before you notice.
  • SLA reporting you can't defend. When the ticket was created manually 40 minutes after the alert fired, your SLA numbers are fiction. You can't prove response times because the systems don't share a clock.
  • Burnout and attrition. On-call rotations where every shift means dozens of pointless interruptions produce techs who stop sleeping with their phone on. That's the exact person you need awake and sharp at 2 a.m.

Run the math on your own environment: a 40-client MSP with 3,500 managed endpoints can easily generate 800–1,000 raw alerts per day. After deduplication, correlation, and maintenance suppression, the number of alerts that genuinely require a human decision is typically 50–150. That 85–90% delta is an attention tax your team pays every single day.

How AlertMonitor Approaches It

AlertMonitor was built around the insight that fatigue comes from context-free alerts, not from alerting itself.

Every alert carries full context. Not "SRV-FS-02 disk warning" but: client, device, what changed, and what healthy looks like — "Meridian Dental / SRV-FS-02: D: volume at 6% free, declining ~2 GB/day, projected full in ~3 days. Baseline healthy is 22%. Shadow copy storage grew 40 GB this week." A tech can triage that in five seconds without opening a single other tool.

Smart deduplication collapses the noise. One issue produces one alert for its entire lifetime — not one per poll cycle. Related failures correlate into a single root-cause alert, so a switch flap is one page, not forty-seven.

Escalation policies that match reality. Multi-level on-call routing with time-based ladders: a P1 after hours pages the primary tech, escalates to secondary after 5 minutes, to the NOC manager after 10. A P3 disk-trend warning routes to a business-hours queue instead of waking anyone. MSPs get per-client routing so the right tech sees the right client.

Maintenance window suppression. Scheduled reboots, patch weekends, and vendor maintenance are declared once, and the platform stays quiet through them. Planned work produces zero pages.

Alert-to-resolution in one tool. Because monitoring, RMM, helpdesk, and patching share one platform: an alert auto-creates a ticket with the client's SLA clock started at detection time, device history attached, and a remote session one click away. The old workflow — notice email, check monitor, RDP, open ticket in the helpdesk, email the client — becomes a single pane.

Teams running this model report the same pattern: raw alert volume drops by an order of magnitude, mean time to acknowledge goes from tens of minutes to under five, and — most importantly — the team recalibrates. When a page arrives, it's real. Nobody says "must be a bug" anymore, because the pipeline doesn't cry wolf.

Practical Steps You Can Take This Week

1. Audit your alert volume honestly. For one week, classify every alert: real, false positive, duplicate, or noise. Most teams find 80–90% falls into the last three categories. Every duplicate and false positive you eliminate makes the remaining ones more credible.

2. Replace static disk thresholds with trend-based checks. A static "alert at 90% full" fires far too late on fast-growing volumes and far too often on stable ones. First, inventory what you're dealing with:

PowerShell
$servers = 'SRV-APP-01','SRV-FS-02','SRV-DB-01'
Get-CimInstance Win32_LogicalDisk -Filter 'DriveType=3' -ComputerName $servers |
    Select-Object SystemName, DeviceID,
        @{n='SizeGB';e={[math]::Round($_.Size/1GB,1)}},
        @{n='FreeGB';e={[math]::Round($_.FreeSpace/1GB,1)}},
        @{n='FreePercent';e={[math]::Round($_.FreeSpace/$_.Size*100,1)}} |
    Sort-Object FreePercent |
    Format-Table -AutoSize

Then measure the drain rate and project days-until-full — a far better alert trigger than a raw percentage:

PowerShell
$logFile = 'C:\Scripts\disk-history.csv'
$servers = 'SRV-FS-02','SRV-APP-01'
$today = Get-Date -Format 'yyyy-MM-dd'

$snapshot = Get-CimInstance Win32_LogicalDisk -Filter 'DriveType=3' -ComputerName $servers |
    Select-Object @{n='Key';e={ '{0}-{1}' -f $_.PSComputerName,$_.DeviceID }},
                  @{n='FreeGB';e={[math]::Round($_.FreeSpace/1GB,2)}},
                  @{n='Date';e={$today}}

$snapshot | Export-Csv $logFile -Append -NoTypeInformation

$history = Import-Csv $logFile
$weekAgo = (Get-Date).AddDays(-7).ToString('yyyy-MM-dd')
foreach ($disk in $snapshot) {
    $past = $history | Where-Object { $_.Key -eq $disk.Key -and $_.Date -eq $weekAgo } | Select-Object -First 1
    if ($past) {
        $drainPerDay = [math]::Round(([double]$past.FreeGB - $disk.FreeGB),2)
        if ($drainPerDay -gt 0) {
            '{0}: {1} GB free, draining {2} GB/day - approx {3} days until full' -f $disk.Key, $disk.FreeGB, $drainPerDay, [math]::Round($disk.FreeGB/$drainPerDay,1)
        }
    }
}

Run the snapshot daily from Task Scheduler; after a week of history you get days-until-full for every volume. In AlertMonitor, that projection becomes the check — one meaningful "D: full in 3 days" alert instead of fourteen nightly threshold pages.

3. Auto-recover the boring 60% so it never pages anyone. A large share of "critical" alerts are one-command fixes: a stopped service, a hung process. Script the recovery and keep the escalation for genuine failures:

PowerShell
$watchlist = [ordered]@{
    'SRV-APP-01' = 'Spooler','W32Time'
    'SRV-DB-01'  = 'MSSQLSERVER'
    'SRV-RDS-01' = 'UmRdpService'
}

foreach ($server in $watchlist.Keys) {
    foreach ($name in $watchlist[$server]) {
        $svc = Get-Service -Name $name -ComputerName $server -ErrorAction SilentlyContinue
        if (-not $svc) { Write-Warning "$server : service $name not found"; continue }
        if ($svc.Status -ne 'Running') {
            Write-Warning "$server : $name is $($svc.Status) - attempting recovery"
            try {
                $svc | Start-Service -ErrorAction Stop
                "$server : $name recovered automatically"
            } catch {
                "$server : $name failed to start - escalate to on-call"
            }
        }
    }
}

In AlertMonitor the same idea is built in: attach an automated response to an alert, get an audit trail of exactly what ran, and only escalate when the self-healing action fails. Your techs only see the incidents a script couldn't fix.

4. Make escalation match severity, not just "an alert exists." Stop broadcasting everything to one alias. Define ladders per severity and per client. The shape of a sane policy:

YAML
escalation_policy: after_hours_critical
trigger: severity == critical AND outside_business_hours
steps:
  • notify: primary_oncall via: [push, sms] wait: 5m
  • notify: secondary_oncall via: [push, sms, phone] wait: 10m
  • notify: noc_manager via: [phone] repeat: 15m
Code

Everything below critical routes to business-hours queues. A P4 "backup job completed with warnings" should never wake a human.

**5. Declare maintenance windows for every planned change.** Patch Sunday, the ESXi host upgrade, the ISP maintenance slot — put them in the monitoring platform, not a spreadsheet. If a planned reboot pages your on-call, your on-call learns to ignore pages.

**6. Close the loop between alerts and tickets.** If your helpdesk doesn't know about an incident until a human manually creates a ticket, your SLA data is wrong and your backlog accounting is wrong. Alert-to-ticket automation with the clock starting at detection is non-negotiable for defensible reporting.

## The Standard to Hold Your Tools To

The astronomer in that story didn't dismiss his finding and move on. He checked it, verified it, and it turned out to be real — because his pipeline was quiet enough that when something rare appeared, it stood out immediately. That's the standard your alerting should meet.

The goal isn't fewer alerts for their own sake. It's this: when AlertMonitor pages your on-call tech at 2 a.m., the tech's first thought is "what's the fastest fix" — never "this must be a bug."

## Related Resources

[AlertMonitor Alert Management & On-Call Operations](https://alertmonitor.ai/platform/alert-management)
[AlertMonitor Platform Overview](https://alertmonitor.ai/platform)
[Book a Demo](https://alertmonitor.ai/contact)
[Alert Management & On-Call Operations Resources](https://alertmonitor.ai/blog/alert-management)
alert-fatiguealert-managementon-callescalation-policyalertmonitoron-call-escalationalert-deduplicationmsp-operations

Is your security operations ready?

Get a free SOC assessment or see how AlertMonitor cuts through alert noise with automated triage.