After connecting ObsrvHQ to enough different stacks, you start noticing patterns. Teams are different sizes, use different monitoring setups, operate different kinds of services. But the noise shapes are surprisingly consistent. We see the same three fatigue archetypes appear in almost every environment, and together they account for the majority of the suppression work we do.
Writing this down because teams often assume their alert noise is a unique property of their specific architecture. It usually is not. The noise is structural, and understanding the structure is the first step toward addressing it.
Pattern 1: duplicate escalation chains
This one is almost universal. A service has two or more alert rules watching overlapping conditions. One rule is from three years ago, watching request error rate on a specific endpoint. Another was added when the team adopted SLO-based alerting, watching burn rate on the same error budget. They fire on the same incidents. PagerDuty receives both, creates two incidents, and both escalate through the same on-call rotation.
The engineer wakes up at 2:47am and acknowledges the first incident. They investigate, find the issue, and resolve it. Forty minutes later the second incident escalates because nobody acknowledged it. They get a second page for the same thing they already fixed.
PagerDuty has deduplication features, but they work on exact event key matching. Two alert rules with different names and different query structures don't deduplicate, even if they're watching the same underlying condition. The deduplication has to happen earlier in the pipeline, before the escalation policy fires.
What ObsrvHQ does here: during baseline learning, we detect firing correlation between alert rules. Two rules that consistently fire within the same 5-minute window, on the same service, share a suppression group. When both fire simultaneously, the second escalation is held until the first is acknowledged or resolved. If the engineer resolves through the first incident, the second never escalates. If they don't acknowledge within the configured window, both escalate separately. The human stays in control; we just remove the duplicate page when the engineer has already demonstrated awareness.
Pattern 2: self-healing CPU and memory spikes
This is the most common single source of overnight noise in microservice environments. A service spikes CPU to 85% for 3-4 minutes, trips the alert threshold, generates a page, and resolves on its own before the engineer even picks up their phone. By the time they look at the dashboard, CPU is back at 40% and there's nothing to investigate.
These spikes have a clear fingerprint: short duration, complete self-resolution, no downstream error rate change, no latency increase. They happen regularly during GC pauses in JVM services, during batch processing windows, during connection pool warm-up after a deploy. They are a normal property of the service, not an incident.
The problem is that most threshold rules don't have this context. A rule that says "fire if CPU > 80% for 2 consecutive minutes" cannot distinguish between a self-resolving GC pause and a real saturation event. Both look the same at threshold-crossing time.
Baseline learning adds the temporal dimension the threshold lacks. We know this service spikes to 85% every 4 hours for 2-3 minutes, and it always resolves. When it happens again, the pattern matches. The page fires into a review queue rather than immediately escalating. If the spike extends beyond its typical duration, or if error rate starts to climb alongside it, suppression releases and the page escalates normally. That's the boundary: we suppress the pattern we know, not the deviation from it.
We're not saying you should tolerate CPU spikes indefinitely. If the spikes are getting longer or more frequent, that's a capacity signal worth acting on during business hours. But waking an engineer at 3am for a 3-minute GC pause is not the right response to that capacity signal.
Pattern 3: post-deploy alert storms
The third pattern is the most disruptive by raw page volume: the post-deploy storm. A team ships a release at 5:30pm Friday. In the 15 minutes following the deploy, 12 separate alert rules fire: latency spikes during pod restart, error rate jumps during connection drain, resource metrics fluctuate during scale events. All of this is expected deploy behavior. None of it is an incident. But PagerDuty sees 12 firing alerts and dutifully sends 12 notifications.
This is a structural property of rolling deploys in containerized environments. The transition period between old and new pods creates transient metric anomalies that look exactly like incidents. Threshold-based rules have no concept of "this environment is currently in a known transition state."
There are two approaches to this. The first is deploy window suppression: if you push deploy events into ObsrvHQ (via webhook or CI/CD integration), we can apply a configurable suppression window around each deploy. Alerts that fire within that window are held in review rather than escalating immediately. The window default is 12 minutes, configurable per service based on your observed stabilization time.
The second approach, which works without explicit deploy event integration, is storm pattern detection. When more than N alert rules fire within a short window across the same service cluster, ObsrvHQ treats this as a potential storm event and holds escalation on all of them. The engineer gets a single "storm detected" notification rather than 12 separate pages. They can investigate or dismiss with a single action.
A mid-size SaaS team we worked with during early access was seeing 30-50 PagerDuty incidents on every Friday evening deploy. Their on-call rotation had started declining Friday deploy windows entirely because the noise load was unsustainable. After connecting deploy events and setting appropriate stabilization windows, that same deploy generates 2-3 actual escalations when something genuinely fails, and nothing when the deploy is clean. That's still not zero overhead, but it's a manageable signal.
What these three patterns have in common
Each of these patterns is a case where the alerting system lacks context that a human engineer has. The engineer knows their duplicate alert rules. They know their JVM services have GC spikes. They know deploys are noisy. The rules don't know any of this because rules are static and context is dynamic.
The fix at the rule level is hard: you'd need to maintain the rules constantly to encode current context, and the context changes faster than most teams can update rules. The fix at the suppression layer is more durable: learn the patterns from the metrics, encode the context automatically, and update it continuously as the service evolves.
Addressing all three patterns doesn't require replacing your escalation tooling. PagerDuty's routing and escalation policies are still doing their job. The suppression layer upstream simply narrows what PagerDuty sees to the signals that actually need a human response. That's the division of work: escalation tools escalate, suppression tools decide what's worth escalating.