Live demo

14 series in. 4 alerts out.

One tier-1 queue, four product areas, 60 days, 14 series. On day 44 a failure mode with no tag and no macro started arriving. Total ticket volume is flat for the whole window because these contacts displace others, CSAT held, and the backlog never grew. Find the area and the day.

Every number on this page is computed in your browser right now, by the same CUSUM and Bayesian changepoint code that runs in production. Nothing here is a screenshot.

The comparison that matters

Against the rule most teams actually ship

The standard configuration is a percentage or sigma threshold against a trailing mean, evaluated per metric. Run it over the exact same 14 series and count what lands in the channel.

Naive rule
87
alerts sent · alert if |Δ| > 15% vs 7-day mean
Of those, false
46
fired before anything was wrong
This engine
4
alerts sent, all correct
Noise reduction
95%
fewer messages, same catch

The false-alarm count is not a judgement call. The incident was injected at a known index, so every naive alert before that index is wrong by construction.

What the engine found

Detection run

Detection run4 alerts14 series tested · 4 fired · 0 suppressed by BH at FDR=0.05
MetricTrendBaselineNowChangeConfidenceMethod
Tickets mentioning topic
area=payments
26.63123.33+363%99.9%CUSUM
Escalation rate
area=payments
6.56%19.5%+197%99.9%CUSUM
Median handle time
area=payments
617.58s979.35s+58.6%99.9%CUSUM
First-contact resolution
area=payments
74.3%52.2%−29.8%99.9%CUSUM

Show your work

Tickets mentioning topic · area=payments

Baseline
26.63
After changepoint
123.33
Change
+363%
Confidence
99.9%
CUSUM (Page 1954)
The series60 daysdashed line = baseline mean · red = detected changepoint
8.5880151.42changepointJun 29Aug 27
The CUSUM accumulatorsmall deviations stack slowly; a real shift stacks fast
h = 0.863 (decision boundary)1.450

Baseline mean μ = 0.0217 and σ = 0.2158, both computed from the first two thirds of the day-over-day percentage changes. The slack k = 0.1079 is half a sigma, and the decision boundary h = 0.8632 is four. The accumulator runs on percentage changes rather than raw levels so a healthy growing series cannot drift across the boundary on its own.

What the naive rule did on this same series

alert if |Δ| > 15% vs 7-day mean fired 19 times across this one metric, including 11 before anything was actually wrong. The statistical pipeline sent one message, on the day the regime actually changed.

What lands in Slack

One message, with the work already done

S
SupportAPP#eng-alerts
🔴 Tickets mentioning topic jumped +363%area=payments
Baseline
26.63
Now
123.33
Confidence
99.9%
Started
Aug 13
Queue
tier-1 (4 areas)
Area
payments
Topic
unnamed cluster #7
First seen
Aug 12
Likely cause · A topic cluster with no tag and no macro starts appearing in payments tickets on Aug 12. First-contact resolution on that area falls at the same time, which is the signature of contacts arriving faster than the playbook does. Escalation rate and handle time follow. Total volume is flat because these contacts replace other payments contacts rather than adding to them, so nothing on the queue dashboard moved.
  1. 1.Read the 20 highest-similarity tickets in cluster #7 and name the failure mode.
  2. 2.Create the tag and a macro before the next shift so first-contact resolution recovers.
  3. 3.Send the cluster to the payments team with the Aug 12 date attached and ask what shipped.
AcknowledgeFalse positiveCUSUM · q < 0.0001 · BH-corrected

The written cause is generated only after the statistics confirm the change. The model never decides whether something is an anomaly — it explains one that has already been established. Getting that order backwards is how these products hallucinate.