When Did the World Change? Changepoint Detection From Page's CUSUM to Bayesian Online Inference
CUSUM has been provably optimal since 1986, yet on the first human-annotated changepoint benchmark a detector that never reports a change beat most of the field under default settings. Seventy years of changepoint theory, from Page's cumulative sum to Bayesian run-length posteriors, is a story about what you are willing to assume, and what each assumption buys you in detection delay.
In the first benchmark built from human-annotated real-world series, a baseline that always answers "no change happened" scored an average F1 of 0.645 on univariate data with default settings, higher than nine of the thirteen real methods it was compared against (van den Burg & Williams, 2020, arXiv:2003.06222). The best default performer was the oldest method, binary segmentation from 1974. None of this contradicts theory. CUSUM is exactly optimal for the problem it was designed for, and has been known to be since 1986. The trouble is that the problem carries assumptions, and most production failures come from those assumptions rather than from the algorithm.
Changepoint detection asks when the process generating a series stopped being the same process. The methods split along two axes that matter more than any algorithmic detail: must you decide now, as each point arrives, or can you look at the whole series afterwards; and how much do you claim to know about the before and after distributions?
Why this matters: Every changepoint detector trades detection delay against false alarms, and the exchange rate is set by what the method assumes: a known baseline, a known shift size, a segment model, a penalty, a hazard rate. Knowing which assumption a detector is spending lets you predict how it will fail on your data before it pages anyone at 3 a.m.
TL;DR
- CUSUM is exactly optimal for a narrow question. Page's 1954 recursion \(S_t = \max(0, S_{t-1} + \ell_t)\) minimises worst-case detection delay at a fixed false-alarm rate when both pre- and post-change distributions are known (Lorden 1971 asymptotically, Moustakides 1986 exactly).
- Accumulation beats thresholds on small shifts only. CUSUM with \(k = 0.5\), \(h = 4\) (336 observations between false alarms) detects a 1σ shift in 8.4 on average, a 3σ Shewhart chart in about 44; at a 3σ jump Shewhart wins, 2.00 to 2.19.
- Offline segmentation is penalised optimisation. Exact optimal partitioning is \(O(n^2)\); PELT prunes it to expected \(O(n)\), but only when the number of changes grows linearly with series length.
- BOCPD replaces a threshold with a posterior over run length, at linear cost per step unless pruned. Tuned, it topped the 2020 benchmark, though not significantly ahead of binary segmentation.
- Defaults dominate. Kernel changepoint analysis scored F1 0.124 on defaults and 0.686 tuned.
- Production wins are offline and human-reviewed. MongoDB replaced a threshold system where about 100 auto-filed tickets yielded one useful one with changepoint review at an estimated 40 to 80 percent false-positive rate.
At a Glance
flowchart LR
X["Stream or series"]:::blue --> Q{"Decide now or afterwards?"}:::slate
Q -->|"online, known before and after"| C["CUSUM or Shiryaev-Roberts"]:::purple
Q -->|"online, unknown after"| B["BOCPD run-length posterior"]:::purple
Q -->|"offline, whole series"| O["Penalised segmentation"]:::purple
C --> A1["Alarm time"]:::teal
B --> A2["P(change) per step"]:::teal
O --> A3["Segment boundaries"]:::teal
A1 --> R["Assumption risk"]:::rose
A2 --> R
A3 --> R
classDef blue fill:#1e40af,stroke:#3b82f6,stroke-width:1px,color:#fff
classDef purple fill:#6d28d9,stroke:#a78bfa,stroke-width:1px,color:#fff
classDef teal fill:#0e7490,stroke:#22d3ee,stroke-width:1px,color:#fff
classDef rose fill:#be123c,stroke:#fb7185,stroke-width:1px,color:#fff
classDef slate fill:#334155,stroke:#64748b,stroke-width:1px,color:#e2e8f0Each family is only as good as its model of "no change".
From the Factory Floor to the Run-Length Posterior
Walter Shewhart's control charts of the 1920s judged each sample alone against three-standard-deviation limits. That catches a machine gone suddenly wrong and misses one drifting by 1σ, where every point looks ordinary.
E. S. Page's answer was to stop judging points and start accumulating evidence (Page, 1954, "Continuous Inspection Schemes", Biometrika). His cumulative sum adds up small deviations and forgets them when they stop pointing the same way.
Albert Shiryaev framed the question as Bayesian: a change time with a geometric prior, and the stopping rule minimising expected delay under a false-alarm constraint (Shiryaev, 1963). S. W. Roberts reached a related statistic comparing control charts (Roberts, 1966, Technometrics); the names are now joined as Shiryaev-Roberts. Gary Lorden supplied the minimax criterion that made CUSUM a theorem (Lorden, 1971), George Moustakides proved it exactly optimal under that criterion (Moustakides, 1986), and Moshe Pollak proposed a rival criterion with a randomised Shiryaev-Roberts start (Pollak, 1985).
Offline, Scott and Knott's recursive splitting (1974, Biometrics) became binary segmentation. Exact dynamic programming over segmentations was made practical by PELT (Killick, Fearnhead & Eckley, 2012, arXiv:1101.1438). And in 2007 Adams and MacKay (arXiv:0710.3742) and, independently, Fearnhead and Liu wrote down exact online recursions over the time since the last change.
timeline
title Changepoint detection, 1954 to 2020
1954 : Page publishes CUSUM in Biometrika
1963 : Shiryaev frames quickest detection with a geometric prior
1971 : Lorden proves CUSUM asymptotically minimax
1974 : Scott and Knott introduce binary segmentation
1985 : Pollak criterion and randomised Shiryaev-Roberts
: Moustakides proves exact CUSUM optimality in 1986
2007 : Adams and MacKay publish BOCPD
2012 : PELT makes exact penalised segmentation near linear
2014 : Twitter EDM breakout detection runs daily in production
2020 : van den Burg and Williams annotated benchmark
: MongoDB reports E-Divisive in performance CI[IMAGE: Two stacked panels over the same 200-point series with a 1σ mean shift at t=120. Top: raw points with Shewhart 3σ limits, no point outside. Bottom: CUSUM statistic near zero until t=120, then climbing past h=4 around t=128. Caption: "The same shift is invisible to a pointwise rule and obvious to an accumulator."]
How Sequential and Retrospective Detection Actually Work
The likelihood ratio underneath everything
Let observations be independent with density \(f_0\) before an unknown time \(\nu\) and \(f_1\) from \(\nu\) on. The classical detectors are all built from the per-observation log-likelihood ratio
negative in expectation before the change and positive after. Its post-change mean is the KL divergence \(I = D_{\mathrm{KL}}(f_1 \,\|\, f_0)\), the evidence each new observation contributes. For a Gaussian shift from \(\mu_0\) to \(\mu_0 + \delta\) with variance \(\sigma^2\),
The \(\delta/2\) is CUSUM's reference value \(k\). It is not picked by taste; it falls out of the likelihood ratio, so a detector for a 1σ shift uses \(k = 0.5\sigma\). The quadratic in \(I\) explains why small shifts are expensive: halve the shift and each sample carries a quarter of the evidence.
Page's recursion is a maximum over unknown change times
With \(\nu\) known, the test would sum \(\ell_t\) from \(\nu\) to now. It is unknown, so take the most favourable candidate, which collapses to a one-line recursion because the best start either extends yesterday's or restarts today:
The reset to zero is the mechanism. Without it the sum is a random walk with negative drift, and post-change evidence must first climb out of a deep hole. With it, the statistic idles near zero and climbs the moment the drift turns positive. A free by-product is the change-time estimate: the last time \(S\) touched zero before the alarm.
What "optimal" means, precisely
False alarms are measured by the average run length to false alarm, \(\mathrm{ARL}_0 = \mathbb{E}_\infty[T]\), the expected stopping time when no change occurs. Delay needs a definition, and the definition is where the field argues. Lorden took the pessimist's view, the worst change time and the worst pre-change history:
Among all rules with \(\mathrm{ARL}_0 \ge \gamma\), CUSUM minimises \(\bar{D}\) asymptotically, with
and Moustakides showed the optimality is exact for every \(\gamma\). It is a scaling law, not a design tool: for \(\gamma = 336\) and a 1σ shift (\(I = 0.5\)) it predicts 11.6 observations against an exact 8.4. What it gets right is the shape of the trade. False alarms are bought logarithmically; delay is paid inversely in KL divergence.
Pollak found conditioning on the worst history too pessimistic and averaged over it instead, taking \(\sup_\nu \mathbb{E}_\nu[T - \nu \mid T \ge \nu]\). The natural statistic there sums likelihood ratios over candidate change times rather than maximising:
Under no change \(R_n - n\) is a zero-mean martingale, so stopping at \(R_n \ge A\) guarantees \(\mathrm{ARL}_0 \ge A\). Pollak proved that starting \(R_0\) from the statistic's quasi-stationary distribution is third-order asymptotically optimal. Whether it was strictly minimax stayed open for twenty-five years, until Polunchenko and Tartakovsky gave a counterexample in which the strictly optimal rule is Shiryaev-Roberts started from a specially designed deterministic point (Polunchenko & Tartakovsky, 2010, Annals of Statistics 38(6)). Two criteria, two "best" procedures.
Even ARL0 is contested: Mei (Sequential Analysis, 2008) showed it can be infinite for schemes with finite delay under mixture pre-change models. A plainer caution: ARL is a mean of a roughly geometric distribution, so a detector with ARL0 of 336 fires within its first 100 in-control observations about a quarter of the time (\(1 - (1 - 1/336)^{100} \approx 0.26\)).
Retrospective segmentation as penalised optimisation
Offline, the question becomes where the boundaries are. Truong, Oudre and Vayatis organise every offline method into a segment cost, a search method, and a penalty or constraint on the number of changes (Truong et al., 2020, Signal Processing 167, arXiv:1801.00718). With changepoints \(\tau_{1:m}\) and per-change penalty \(\beta\):
For a Gaussian mean change, \(\mathcal{C}\) is within-segment squared error. Optimal partitioning solves this exactly via \(F(t) = \min_{s < t}\,[F(s) + \mathcal{C}(y_{(s+1):t}) + \beta]\), which is \(O(n^2)\). PELT adds a pruning rule: if
(\(K = 0\) for a negative log-likelihood cost), then \(t\) can never again be the optimal last change and is deleted for good. Killick and colleagues prove expected linear cost under a condition that deserves more attention: the number of changes must grow linearly with series length. With a fixed number of changes their supplementary simulations show cost is no longer linear, and the no-pruning worst case stays \(O(n^2)\).
Binary segmentation finds the single best split, keeps it if the gain beats \(\beta\), and recurses, at \(O(n \log n)\). Truong et al. name its weakness: each split is estimated on a segment that may still contain other changes, so close changes are located imprecisely.
Kernels, and changes in anything
A squared-error cost cannot see a change in variance or shape. Harchaoui and Cappé (2007) moved the cost into a reproducing-kernel Hilbert space, where with a characteristic kernel a mean change in the embedding is a change in the whole distribution:
Arlot, Celisse and Harchaoui added a model-selection penalty, proved an oracle inequality, and detected changes with constant mean and variance, at up to \(O((C_k + D_{\max})\,n^2)\) time (Arlot et al., 2019, JMLR 20, arXiv:1202.3878). Quadratic cost plus a bandwidth and penalty constants is what that flexibility costs.
BOCPD: a posterior over when the regime began
BOCPD tracks the run length \(r_t\), the observations since the last change. Under hazard \(H\) (constant \(1/\lambda\) for geometric segment lengths) it grows by one with probability \(1 - H\) or resets with probability \(H\):
With a conjugate model each run length carries a few sufficient statistics, so every step is exact. Per-step time and memory are linear in the data seen; Adams and MacKay prune run lengths with tail mass below \(10^{-4}\), giving average cost on the order of the expected run length while the worst case stays linear (Adams & MacKay, 2007).
The conceptual difference from CUSUM is the post-change law. CUSUM needs \(f_1\) in advance; BOCPD needs only a prior over what a new segment looks like and learns it after the change. The worked example below prices that flexibility in samples.
Seeing It in Motion
Most operational bugs live in the detector's lifecycle transitions.
stateDiagram-v2
[*] --> Calibrating
Calibrating --> Monitoring : baseline fixed
Monitoring --> Accumulating : S rises above 0
Accumulating --> Monitoring : S resets to 0
Accumulating --> Alarm : S reaches h
Alarm --> Triage : estimate change time
Triage --> Calibrating : real change, new baseline
Triage --> Monitoring : false alarm, reset SLibraries leave the Triage to Calibrating edge to you: after a real change the old \(\mu_0\) is wrong.
Offline tools follow the decomposition ruptures is built around:
flowchart TB
subgraph Cost["Segment cost"]
C1["L2 mean shift"]:::purple
C2["Kernel RBF"]:::purple
end
subgraph Search["Search method"]
S1["Optimal partitioning"]:::slate
S2["PELT pruning"]:::emerald
S3["Binary segmentation"]:::amber
end
subgraph Stop["Model complexity"]
P1["Penalty beta per change"]:::slate
P2["Fixed number of changes"]:::slate
end
Y["Complete series"]:::blue --> Cost
Cost --> Search
Search --> Stop
Stop --> Z["Changepoint list"]:::teal
classDef blue fill:#1e40af,stroke:#3b82f6,stroke-width:1px,color:#fff
classDef purple fill:#6d28d9,stroke:#a78bfa,stroke-width:1px,color:#fff
classDef teal fill:#0e7490,stroke:#22d3ee,stroke-width:1px,color:#fff
classDef amber fill:#b45309,stroke:#fbbf24,stroke-width:1px,color:#fff
classDef emerald fill:#047857,stroke:#34d399,stroke-width:1px,color:#fff
classDef slate fill:#334155,stroke:#64748b,stroke-width:1px,color:#e2e8f0A regression-hunting pipeline:
sequenceDiagram
participant CI as CI perf runs
participant Store as Result store
participant Det as Changepoint job
participant Rev as Human reviewer
participant Tix as Ticket queue
CI->>Store: append latency per commit
Store->>Det: full history per test
Det->>Det: E-Divisive or PELT over series
Det->>Rev: ranked candidate changepoints
Note over Rev: many candidates are noise
Rev->>Tix: file confirmed regressions
Rev-->>Det: acknowledge, suppress re-alerts[IMAGE: Heatmap of a BOCPD run-length posterior, x-axis time, y-axis run length on a log scale, diagonal ridges dropping to zero at each detected change. Caption: "Each diagonal is a regime growing older; each drop to zero is a detected change."]
By the Numbers
Run lengths for a one-sided CUSUM on standardised Gaussian data with \(k = 0.5\), against a two-sided 3σ Shewhart chart:
| True shift (σ) | CUSUM \(h=4\) | CUSUM \(h=5\) | Shewhart 3σ | Faster |
|---|---|---|---|---|
| 0 (false alarms) | 336 | 931 | 370 | n/a |
| 0.5 | 26.7 | 38.0 | 155 | CUSUM, about 6x |
| 1.0 | 8.38 | 10.4 | 43.9 | CUSUM, about 5x |
| 2.0 | 3.34 | 4.01 | 6.30 | CUSUM |
| 3.0 | 2.19 | 2.57 | 2.00 | Shewhart |
Sources: computed for this article with the Brook-Evans Markov-chain method and checked against the NIST/SEMATECH e-Handbook, 6.3.2.3.1, which agrees in every cell except \(h=5\) at 0.5σ (NIST prints 30.0; the chain gives 38.0). The 1σ CUSUM value was also confirmed by 20,000 simulated runs (8.39).
The evidence on real data comes from the Turing benchmark: 37 series, each annotated by five people, scored with package defaults ("Default") and with the best score over a hyperparameter grid chosen knowing the answers ("Oracle"). Univariate averages:
| Method | Default cover | Default F1 | Oracle cover | Oracle F1 | Search cost |
|---|---|---|---|---|---|
| binseg (1974) | 0.672 | 0.698 | 0.774 | 0.873 | \(O(n \log n)\) |
| pelt (2012) | 0.652 | 0.674 | 0.772 | 0.864 | expected \(O(n)\) |
| bocpd (2007) | 0.594 | 0.662 | 0.783 | 0.886 | \(O(n)\) per step |
| kcpa (kernel) | 0.069 | 0.124 | 0.608 | 0.686 | \(O(n^2)\) |
| ecp (energy) | 0.470 | 0.560 | 0.693 | 0.773 | permutation tests |
| zero (no changes) | 0.566 | 0.645 | 0.566 | 0.645 | none |
Sources: van den Burg & Williams, 2020, Table 2, where median annotator agreement is reported as about 0.8 (cover) and 0.9 (F1); complexities from Truong et al., 2020, Killick et al., 2012 and Arlot et al., 2019. The authors stress that Oracle scores are unattainable in practice.
The zero baseline's score reflects, in the authors' words, that "many methods return a large number of false positives." And kcpa's jump from 0.124 to 0.686 says the method is not bad; its defaults are.
[IMAGE: Slope chart from each method's Default F1 (left) to its Oracle F1 (right), with the zero baseline as a flat reference line at 0.645. Caption: "The gap between default and tuned performance is larger than the gap between methods."]
A Concrete Example
Ten standardised latency residuals, in-control mean 0 and standard deviation 1, watching for a 1σ increase, so \(\ell_t = x_t - 0.5\). Unknown to the detector, the mean moved to 1 at \(t = 6\). Run CUSUM with \(h = 4\) (ARL0 about 336), Shiryaev-Roberts on the same ratios, and a 3σ Shewhart rule.
| \(t\) | \(x_t\) | \(\ell_t\) | \(S_t\) | \(R_t\) | Shewhart |
|---|---|---|---|---|---|
| 1 | 0.2 | −0.3 | 0 | 0.74 | no |
| 2 | −0.5 | −1.0 | 0 | 0.64 | no |
| 3 | 0.9 | 0.4 | 0.4 | 2.45 | no |
| 4 | −0.3 | −0.8 | 0 | 1.55 | no |
| 5 | 0.1 | −0.4 | 0 | 1.71 | no |
| 6 | 1.4 | 0.9 | 0.9 | 6.66 | no |
| 7 | 0.8 | 0.3 | 1.2 | 10.34 | no |
| 8 | 1.9 | 1.4 | 2.6 | 46.0 | no |
| 9 | 1.6 | 1.1 | 3.7 | 141.2 | no |
| 10 | 1.2 | 0.7 | 4.4 | 286.3 | no |
- Steps 1 to 5. Four of five increments are negative, so \(S\) is pinned at zero. The blip at \(t = 3\) lifts it to 0.4 and the next point wipes it out: isolated evidence decays instead of compounding.
- Step 6, the change. \(x_6 = 1.4\) gives \(S_6 = 0.9\). A value that high occurs about 8 percent of the time with no change; alone it means nothing.
- Steps 7 to 9. Every increment is positive: 1.2, 2.6, 3.7. Even \(x_7 = 0.8\), below the new mean, adds evidence because it exceeds \(k = 0.5\).
- Step 10, the alarm. \(S_{10} = 3.7 + 0.7 = 4.4 \ge 4\). Delay is five observations, luckier than the 8.4 average.
- Estimating when. \(S\) last touched zero at \(t = 5\), so the change is placed at \(t = 6\). Exactly right.
- Shiryaev-Roberts multiplies instead of resetting and grows geometrically after the change. Threshold \(A = 100\) alarms at \(t = 9\); \(A = 300\) has not alarmed by \(t = 10\). Compare detectors at matched ARL0, never at matched numbers.
- Shewhart never fires: the largest value is 1.9.
Offline, squared error around the overall mean 0.73 is 6.08. The best single split is after \(t = 5\) (means 0.08 and 1.38), cutting error to 1.86, a gain of 4.23. Binary segmentation agrees on where; whether it declares a change depends on \(\beta\). A BIC-flavoured \(2 \ln 10 = 4.61\) rejects the split, \(\ln 10 = 2.30\) accepts it. On ten points, the penalty decides.
Finally BOCPD, given what CUSUM knew about the past (200 prior in-control points at mean 0) but not the post-change mean: a new segment's mean has a \(\mathcal{N}(0, 1)\) prior, hazard \(1/100\). The posterior probability that the old regime still holds is 0.96 at \(t = 5\), 0.85 at \(t = 8\), and 0.56 at \(t = 10\). When CUSUM alarms, BOCPD is near even odds, because CUSUM was told the shift size and BOCPD had to learn it. If the real shift differs from the assumed one, that advantage can reverse.
[IMAGE: Three aligned plots over t = 1 to 10: CUSUM S_t with a dashed line at h = 4 crossed at t = 10; log10 R_t with dashed lines at A = 100 and A = 300; BOCPD probability of the old regime falling from 0.99 to 0.56. A band marks the true change at t = 6. Caption: "Same ten points, three detectors, three moments of conviction."]
Where It Breaks
The baseline is an estimate
Every CUSUM figure above assumes \(\mu_0\) and \(\sigma\) are known. In practice they come from a calibration window. Underestimate \(\sigma\) by 10 percent and the \(h = 4\) design that promised ARL0 of 336 delivers about 166 by the same Markov-chain calculation: twice the false alarms. A rolling baseline fixes that and absorbs slow drift instead, so it is never detected.
Autocorrelation fakes persistence
Run-length theory assumes independence. Latency and traffic are positively autocorrelated, so consecutive deviations agree far more often than independence predicts, and CUSUM accumulates them as evidence. The remedy is to model seasonality and AR structure and monitor residuals. But a richer model is not automatically a better detector: in the benchmark, bocpd with a constant-mean Gaussian per segment beat prophet, which models trend and seasonality.
Misspecified tails turn outliers into changepoints
Under a Gaussian likelihood one 6σ outlier is so improbable that BOCPD opens a new segment for it. Knoblauch, Jewson and Damoulas replaced the update with a β-divergence and report cutting changepoint false discovery rates "from more than 90% to 0%" on real data (Knoblauch et al., 2018, NeurIPS, arXiv:1806.02261). Yet the benchmark ranked the robust variant below plain bocpd on average: robustness to outliers and accuracy on typical data are different targets. Twitter's EDM made the same bet with medians, because existing techniques were "not robust in the presence of anomalies" (James, Kejariwal & Matteson, 2014, arXiv:1411.7955).
The penalty is the model
Offline, \(\beta\) sets the number of changes, and the example flipped on \(\ln n\) versus \(2\ln n\). BIC-style penalties assume piecewise i.i.d. data under the chosen cost; when that fails they over-segment. PELT's linear time also has a precondition, changes growing with the series, which a decade of quiet data with two real shifts violates.
Permutation tests are non-deterministic
E-Divisive judges significance by random permutations. Engineers at DataStax building Hunter found "the results of Hunter were non-deterministic and varied from run to run" and switched to a Student's t-test (Fleming et al., 2023, arXiv:2301.03034). An alert that vanishes on re-run destroys trust fast.
After the alarm
A CUSUM reset to zero on the old baseline re-alarms within about \(h/I\) samples of a real change; only re-estimating the baseline stops it. BOCPD handles this better, since the new regime simply becomes the current run.
[IMAGE: Two CUSUM traces on an AR(1) series with phi = 0.6 and no change: raw data crossing h = 4 repeatedly, AR residuals staying mostly near zero. Caption: "Autocorrelation fakes the persistence CUSUM is built to detect."]
Alternative Designs
| Design | How it works | Key advantage | Key limitation | Best when |
|---|---|---|---|---|
| Shewhart | Threshold each point at 3σ | Fastest on large jumps | ARL about 44 at 1σ | Sudden failures |
| CUSUM | Max over change times, reset at 0 | Exactly minimax for known laws | Needs shift size and baseline | Known metric and shift |
| Shiryaev-Roberts | Sum over change times | Clean ARL0 bound | Less intuitive thresholds | Change after long quiet period |
| Binary segmentation | Greedy split, recurse | Best default score in 2020 | Imprecise on close changes | Retrospective, few changes |
| PELT | Pruned exact penalised DP | Optimal, near linear | Penalty choice | Long series, many changes |
| Kernel CPD | Penalised DP in an RKHS | Any distributional change | \(O(n^2)\), bandwidth tuning | Variance or shape changes |
| BOCPD | Posterior over run length | Probabilities, unknown post-change law | Hazard and prior sensitivity | Online, unknown regimes |
| E-Divisive / EDM | Energy distance, permutation test | Nonparametric, robust | Slow, non-deterministic | Noisy ops and perf metrics |
Two questions decide: must you decide online, and do you know the post-change distribution? Knowing both, CUSUM wins by theorem. Knowing neither but able to wait, penalised segmentation is the default, and binary segmentation is a hard baseline. BOCPD earns its cost when a calibrated probability is the output.
How It Is Used in Practice
Performance regression hunting is the clearest success. MongoDB runs E-Divisive means over each performance test's history in CI (Daly et al., 2020, ICPE, arXiv:2003.00584). Over five months their earlier threshold system filed 2,393 tickets, of which 160 were escalated and 24 judged useful: "on average 100 tickets in the first project reduced down to 1 useful ticket." The changepoint system found every regression those tickets tracked, and a sampled audit put its false-positive rate between 40 and 80 percent depending on how ambiguous cases were counted. Humans review every candidate.
Ops breakouts. Twitter's BreakoutDetection package implemented E-Divisive with Medians, which the paper describes as 3.5 times faster than a prior technique and "currently used on a daily basis at Twitter" (James et al., 2014). Its repository is archived.
Toolkits. Meta's Kats, released by Facebook's Infrastructure Data Science team in 2021, ships CUSUM, BOCPD and robust-statistic detectors side by side (Kats repository). ruptures implements the Truong decomposition in Python, and the R changepoint package supplied the defaults the 2020 benchmark used.
Two patterns recur: offline detection over a trailing window whenever hours of delay are acceptable, because it sees both sides of a candidate change; and a ranked review queue with suppression state instead of a pager.
[IMAGE: Mock performance dashboard: latency per commit over 300 commits with two changepoint markers, and a side panel ranking candidates by magnitude with Accept and Dismiss buttons. Caption: "In production, a changepoint is a candidate for a human, not an alert."]
Insights Worth Remembering
-
The reference value is a product decision. \(k = \delta/2\) drops out of the likelihood ratio, so choosing \(k\) means choosing the smallest shift worth acting on.
-
False alarms are bought logarithmically; delay is paid in KL divergence. Making false alarms ten times rarer costs a fixed number of samples. Halving the shift quadruples the delay.
-
"Optimal" always names a criterion. CUSUM is exactly optimal under Lorden's worst case; under Pollak's criterion even the long-assumed optimal procedure turned out not to be strictly minimax.
-
CUSUM's speed is borrowed from its assumptions. In the worked example it alarmed while BOCPD still gave the old regime 56 percent, only because CUSUM was told the post-change mean.
-
"Never fire" is a serious baseline. It beat nine of thirteen methods on default F1 in the only human-annotated benchmark. Test every detector against doing nothing.
-
Tuning explains more than method choice. kcpa moved from 0.124 to 0.686 with tuning, while the top tuned methods were statistically indistinguishable.
-
Online is the expensive special case. Most production successes run offline over a window with a human in the loop.
Open Questions
How should a detector be tuned without labels? The benchmark authors call for automated tuning to close the Default-Oracle gap. No study has yet shown a label-free penalty or hazard selection that reliably approaches oracle performance on real data.
Is the ground truth stable enough? On the businv series annotators broadly agree on three changes, yet the best tuned method reached only 0.650 F1. Whether that reflects weak methods or a noisy consensus is unsettled.
Where does robustness belong? Robust likelihoods, robust statistics and post-hoc filtering all claim to cut outlier-driven false positives, but no head-to-head study compares them on the same operational data.
Is ARL0 the right currency for fleets? Ten thousand metrics each with ARL0 of 1,000 still produce ten false alarms per sampling interval. Windowed false-alarm probabilities are argued for; which criterion best predicts on-call burden is an open empirical question.
Do learned detectors beat classical ones on real series? The 2020 benchmark predates most deep and self-supervised detectors. As of September 2026, no benchmark of comparable scope shows them beating tuned binary segmentation on annotated real-world data.
Sources and Further Reading
- Page, E. S. (1954). "Continuous Inspection Schemes." Biometrika, 41(½), 100-115. doi:10.1093/biomet/41.1-2.100
- Shiryaev, A. N. (1963). "On Optimum Methods in Quickest Detection Problems." Theory of Probability and Its Applications, 8(1), 22-46. doi:10.1137/1108002
- Roberts, S. W. (1966). "A Comparison of Some Control Chart Procedures." Technometrics, 8(3), 411-430. doi:10.1080/00401706.1966.10490374
- Lorden, G. (1971). "Procedures for Reacting to a Change in Distribution." Annals of Mathematical Statistics, 42(6), 1897-1908. doi:10.1214/aoms/1177693055
- Pollak, M. (1985). "Optimal Detection of a Change in Distribution." Annals of Statistics, 13(1). doi:10.1214/aos/1176346587
- Moustakides, G. V. (1986). "Optimal Stopping Times for Detecting Changes in Distributions." Annals of Statistics, 14(4). doi:10.1214/aos/1176350164
- Polunchenko, A. S., & Tartakovsky, A. G. (2010). "On Optimality of the Shiryaev-Roberts Procedure for Detecting a Change in Distribution." Annals of Statistics, 38(6), 3445-3457. doi:10.1214/09-AOS775
- Scott, A. J., & Knott, M. (1974). "A Cluster Analysis Method for Grouping Means in the Analysis of Variance." Biometrics, 30(3). doi:10.2307/2529204
- Killick, R., Fearnhead, P., & Eckley, I. A. (2012). "Optimal Detection of Changepoints With a Linear Computational Cost." JASA, 107(500), 1590-1598. arXiv:1101.1438
- Adams, R. P., & MacKay, D. J. C. (2007). "Bayesian Online Changepoint Detection." arXiv:0710.3742
- Knoblauch, J., Jewson, J., & Damoulas, T. (2018). "Doubly Robust Bayesian Inference for Non-Stationary Streaming Data with β-Divergences." NeurIPS. arXiv:1806.02261
- Arlot, S., Celisse, A., & Harchaoui, Z. (2019). "A Kernel Multiple Change-point Algorithm via Model Selection." JMLR, 20. arXiv:1202.3878
- Truong, C., Oudre, L., & Vayatis, N. (2020). "Selective Review of Offline Change Point Detection Methods." Signal Processing, 167, 107299. arXiv:1801.00718
- van den Burg, G. J. J., & Williams, C. K. I. (2020). "An Evaluation of Change Point Detection Algorithms." arXiv:2003.06222
- James, N. A., Kejariwal, A., & Matteson, D. S. (2014). "Leveraging Cloud Data to Mitigate User Experience from 'Breaking Bad'." arXiv:1411.7955
- Daly, D., Brown, W., Ingo, H., O'Leary, J., & Bradford, D. (2020). "Change Point Detection in Software Performance Testing." ICPE 2020. arXiv:2003.00584
- Fleming, M., Kołaczkowski, P., Kumar, I., Das, S., McCarthy, S., Pattabhiraman, P., & Ingo, H. (2023). "Hunter: Using Change Point Detection to Hunt for Performance Regressions." arXiv:2301.03034
- NIST/SEMATECH. e-Handbook of Statistical Methods, 6.3.2.3.1, "Cusum Average Run Length." itl.nist.gov
Free to read, no ads, no sign-up. If it was useful you can buy me a coffee.