Skip to main content
Guide

Why your server monitoring is creating alert fatigue (and how to fix it)

The Reflex Team8 min19 May 2026

The Slack channel has 400 unread messages. #alerts-prod pings every time CPU crosses 70% for sixty seconds. Disk warnings fire at 80%, 85%, and 90% on the same partition. On-call mutes the channel. Then checkout actually breaks — and nobody notices for forty minutes because every alert looks like noise.

Alert fatigue is not a discipline problem. It is a signal design problem. Your monitoring is telling the truth about unimportant things and lying by omission about things that need a human.

Why it happens in Laravel fleets

Generic uptime monitors check HTTP 200 on / and declare victory while queues are dead and FPM is saturated. Host metrics without context page you for normal traffic spikes. Cron jobs that restart services create alert storms when the restart itself triggers a process-down warning.

Laravel adds layers: Horizon, scheduler, multiple queue workers, Octane if you run it, release-based deploys that briefly spike errors. Without deploy markers and symptom-based thresholds, every release looks like an incident and every incident looks like Tuesday.

Teams respond by raising thresholds until alerts never fire — then miss real outages. Or they route everything to PagerDuty and burn out senior engineers who quit within a year.

Diagnosis: audit your last thirty alerts

Pull your alert history and classify each firing:

  1. Actionable — a human or automation should have done something specific
  2. Informational — useful in a dashboard, wrong for a page
  3. False positive — normal operation misclassified as failure
  4. Duplicate — same root cause, five notifications

If more than half are informational or duplicate, your problem is routing, not infrastructure. If actionable alerts arrived after customers complained, your thresholds are too lazy or missing entirely.

Check whether alerts attach deploy context. If the last five pages correlate with releases, you need health-gated deploys, not louder sirens.

Manual fixes: redesign signals

Page on customer symptoms, not host trivia. Examples worth waking someone:

  • Checkout or login endpoint error rate above baseline
  • Queue age above SLA (password reset emails delayed)
  • PHP-FPM listen queue sustained high with 502 rate climbing
  • Disk above 95% on / or database volume

Examples that belong in a dashboard only:

  • CPU 70–85% during known batch jobs
  • Memory pressure during Composer deploy
  • Single slow request in FPM slow log

Auto-repair safe failures before paging. Stuck queue workers, full /tmp, expired opcache after deploy — these have known fixes. Run the playbook first; page only if repair fails or policy requires approval. Read how the Brain repair cycle works for the model Reflex uses.

Attach deploy markers. Every production deploy should emit a timestamped event. When error rates spike, on-call sees "deploy 2:14pm" instead of guessing.

Use escalation, not broadcast. First notification triggers automation. Second triggers on-call. Third triggers manager — not all three at once.

Example nginx log scrape for 502 rate is useful; paging on every single 502 is not. Aggregate over five minutes.

Config and tooling hygiene

Reduce noise at the source. Rotate logs so disk alerts are rare:

# logrotate — ensure nginx and php-fpm logs rotate daily
/var/log/nginx/*.log {
    daily
    rotate 14
    compress
    delaycompress
    notifempty
    sharedscripts
}

Tune FPM so "max children reached" is rare and meaningful when it happens — see PHP-FPM in production.

Silence known maintenance windows in your alert router. Document why each alert exists; delete alerts nobody can explain.

Run a quarterly alert budget: maximum pages per week per on-call engineer. If you exceed it, fix signals — do not add people.

Laravel-specific alert patterns worth keeping

  • Horizon status not running for more than two minutes
  • failed_jobs table growing faster than your cleanup policy
  • FPM listen queue sustained above zero with rising 502 rate in nginx access log
  • Scheduler last-run timestamp stale — use Laravel's schedule monitor or an external heartbeat
  • SSL expiry within fourteen days on production and staging hostnames

Route each to automation first where safe, human second where not.

How Reflex reduces fatigue

Reflex separates observation from incident. reflexd reports PHP-FPM pool pressure, queue depth, disk, and deploy events. The Brain evaluates playbooks: restart workers, clear safe temp paths, bounce FPM when policy allows — before opening a human incident.

Health-gated Pipeline deploys block promotion when post-deploy checks fail, so you stop paging about broken releases that should never have received traffic. Compare approaches in health-gated deployments.

Agencies managing many servers benefit from fleet-level dashboards with per-client tags — see server monitoring for Laravel agencies. Compare Reflex vs PagerDuty if your stack pages first and fixes never.

Run a thirty-day experiment: mute CPU alerts, keep symptom alerts, enable one auto-repair playbook. Count pages before and after. Most teams cut noise forty to sixty percent without missing real outages.

Review on-call feedback monthly — if engineers describe alerts as "ignored," your design failed regardless of uptime statistics. Alert quality is a product metric, not an ops afterthought.

Treat alert definitions like code: version control them, review in pull requests, and delete dead rules the same way you delete dead feature flags.

Noise is not a badge of thorough monitoring — it is a leading indicator that real outages will hide in plain sight.

Start a trial and rebuild alerting around repair, not noise.

Ready to stop firefighting your servers?

Try Reflex free for 14 days.