Live demo

14 series in. 4 alerts out.

One unit-economics book, four customer segments, 60 days, 14 series. On day 42 one segment stopped paying for itself. Revenue grew through the entire window, orders and average order value never moved, and blended gross margin stayed inside its normal band. Find the segment.

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
52
alerts sent · alert if |Δ| > 2.5σ vs 7-day mean
Of those, false
24
fired before anything was wrong
This engine
4
alerts sent, all correct
Noise reduction
92%
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
Contribution margin per order
segment=resellers
$18$12−34.6%99.9%CUSUM
Shipping cost per order
segment=resellers
$7.36$11+49.4%99.9%CUSUM
Support cost per customer
segment=resellers
$2.22$4.03+81.3%99.9%CUSUM
Refund rate
segment=resellers
3.14%7.82%+150%99.9%CUSUM

Show your work

Contribution margin per order · segment=resellers

Baseline
$18
After changepoint
$12
Change
−34.6%
Confidence
99.9%
CUSUM (Page 1954)
The series60 daysdashed line = baseline mean · red = detected changepoint
$10$15$20changepointJun 29Aug 27
The CUSUM accumulatorsmall deviations stack slowly; a real shift stacks fast
h = 0.154 (decision boundary)0.360

Baseline mean μ = 0.0012 and σ = 0.0386, both computed from the first two thirds of the day-over-day percentage changes. The slack k = 0.0193 is half a sigma, and the decision boundary h = 0.1544 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 |Δ| > 2.5σ vs 7-day mean fired 7 times across this one metric, including 2 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

M
MarginAPP#eng-alerts
🔴 Contribution margin per order dropped −34.6%segment=resellers
Baseline
$18
Now
$12
Confidence
99.9%
Started
Aug 11
Book
unit economics (4 segments)
Segment
resellers
Break
Aug 10
Orders in window
374,400
Likely cause · Four cost-side metrics on the reseller segment break on the same day and no other segment moves. Shipping cost per order and support cost per customer rise together, which points at a mix change rather than a rate card change, and the refund rise arrives with them. Revenue kept growing through the whole window and blended gross margin moved under half a point, so nothing in the monthly review would have surfaced this.
  1. 1.Pull reseller orders since Aug 10 and check discount code usage against the partner allow list.
  2. 2.Break shipping cost per order by destination zone to confirm the mix shift.
  3. 3.Recompute reseller CAC payback with the new contribution margin before renewing the partner terms.
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.