← Back
Home › Systems › AI applications

metric-anomaly-detection

Learns what each metric normally looks like, including daily and weekly cycles, and alerts when a series leaves its expected band, for operators who cannot hand-tune thresholds on thousands of series.

Datadog Watchdog

Open the metric-anomaly-detection pagemetric-anomaly-detec… Gorilla XOR compressioncompression: Time-series codec: delta-of-delta timestamps plus XOR of consecutive float bit patterns, storing only changed bits; about 1.4 bytes per point.›Count-min sketchdata-structures: d rows of w counters estimate any item's frequency in a stream, overestimating by at most ε·N with probability 1-δ, in fixed tiny memory.›Quantile sketchesdata-structures: Mergeable quantile sketches: t-digest, DDSketch, HDR histogramsWindowed stream aggregationdistributed: Group events by event-time window per key, keep one partial aggregate per slice, and emit a window when the watermark passes its end.›Isolation forestmachine-learning: Score each record by how few random axis-aligned splits it takes to isolate it in a small forest of random trees; anomalies are few and different, so they isolate fast.›Arimastatistics: ARIMA/SARIMA forecasting: differencing, AR and MA terms, order selection, maximum-likelihood fitChange point detectionstatistics: CUSUM/E-divisive/PELT to find shifts in a time series mean or distributionExponential smoothing (ETS,Holt-Winters)statistics: Forecast by keeping a few running states (level, trend, seasonal) updated by a fraction of each forecast error; O(1) memory per series and a strong baseline.›Hypothesis testingstatistics: Pick a test statistic, compare it to its distribution under "no effect", read off a p-value, and control error rates across one test or many.›Robust statisticsstatistics: Location and scale estimates (median, MAD, trimmed mean, Huber M-estimator) that stay correct when a minority of the data is garbage.›STL decomposition(seasonal-trend with loess)statistics: Split a series into trend, seasonal and remainder with iterated loess smoothing; the seasonal shape may drift and robust weights keep outliers out of it.›Columnar storagestorage: Store each column contiguously so analytic scans read only the columns they need, compress well and run as tight SIMD loops.›Bitstream serializationgame-networking: A bit writer and reader over a byte buffer that stores each field in exactly the bits its range needs: booleans in 1 bit, bounded integers in ceil(log2(span+1)) bits.›d-ary heapdata-structures: Array heap with d children per node (d = 4 typical): half the binary heap's depth, siblings in one cache line, faster priority queues.›Fast hash functionsdata-structures: Non-cryptographic hashes built from 64×64→128-bit multiplies and xor-shifts; pick by key size, trust level and whether the hash is persisted.›Watermarksdistributed: Event-time progress markers that bound lateness and trigger window resultsHash aggregationstorage: GROUP BY via hash tables with partitioning and spill to diskLSM-treestorage: Buffer writes in memory, flush them as immutable sorted files and merge in the background; turns random writes into sequential I/O.›Hierarchical timing wheelsystems: Timers bucketed by expiry into wheels of slots, coarser wheels for far deadlines: O(1) insert and cancel for millions of timeouts.›Finite differencesnumerics: Replace derivatives with weighted differences of grid values; simple stencils plus a stability condition (CFL) turn PDEs like heat, advection and waves into array loops.›L-BFGSnumerics: Quasi-Newton minimizer that approximates the inverse Hessian from the last m gradient differences via the two-loop recursion; O(m·n) memory and work per step.›Kalman filterrobotics: Optimal recursive estimator for a linear system with Gaussian noise: fuses a motion model with noisy measurements into a state estimate plus its covariance.›Delta encodingcompression: Store differences between consecutive values instead of the values, turning sorted IDs, timestamps and counters into small numbers that pack into few bits.›Bayesian rate estimationstatistics: Estimate a conversion or event rate from few observations with a Beta-Binomial or Gamma-Poisson update: two counters, an honest interval, and P(B beats A) directly.›+ 6 moreConsumer offsetsdistributed: Each consumer group stores one integer per partition, the next position to read, so a restarted consumer resumes where it left off with at-least-once delivery.›Slab allocatorsystems: Pre-carve pages into equal-size slots per size class with an in-place free list: O(1) alloc and free, no external fragmentation, cache-warm reuse.›Explicit Eulernumerics: Step an ODE forward by its current slope, y += h·f(t, y); first-order, one evaluation per step, the baseline every other integrator is measured against.›Thomas tridiagonal solvernumerics: O(n) tridiagonal linear solve used in implicit finite-difference and spline schemesVarint (LEB128)compression: Variable-length integers in 7-bit groups with a continuation bit; small numbers take 1 byte, the wire format of Protobuf, WebAssembly and DWARF.›+ 1 moreFencing tokensdistributed: A number that grows with every lock grant and is checked by the protected resource, so a paused ex-holder's late write is rejected.›Message sequence numbersdistributed: A per-stream counter on every message lets the receiver detect loss, duplicates and reordering, ack cheaply and resume after reconnect with "send from N".›Segmented logdistributed: Split an append-only log into files named by their first offset, write only the newest, and find any record by binary search plus a sparse index.›

How it is built

Architecture overview

A metric anomaly detector turns "this number is too high" from a hand-set threshold into a learned expected band per time series. Every series (a metric name plus labels, such as latency_p99{service="checkout"}) has a baseline made of a level, a trend and a seasonal shape, because most operational metrics follow daily and weekly cycles. Each new point is compared with its forecast; the gap, divided by a robust estimate of how much the series normally wobbles, is the anomaly score. A decision layer turns scores into alerts only when the deviation is large, lasts, and is not one of ten thousand coincidences.

The one idea that makes it work is that the baseline must be fitted on data that may itself contain anomalies, so every stage is built to be robust: medians and median absolute deviations instead of means and standard deviations, a seasonal decomposition that gives outliers low weight, and a persistence requirement before alerting. Hochenbaum et al. (2017) describe exactly this recipe, seasonal decomposition followed by median and MAD, for cloud metrics, and Datadog's anomaly monitors document three algorithms of rising sophistication: a rolling quantile, a robust variant of SARIMA, and a seasonal-trend decomposition. The detector reads series that a Metrics system collects and hands its alerts to Alerting.

Parts:

 collectors ─► metrics store ──► windowing / rollups ──► per-series state
 (scrape/push)  (TSDB)             (aligned buckets)        (level, trend, season, spread)
                                                               │
                      new point ──► forecast ──► residual ─► robust score ──► persistence check
                                                                   │                │
                                                         shift detector ──► multi-series control
                                                                                    │
                                                          grouping/dedup ──► alert + context ──► on-call
                              operator feedback ─► labels ─► retrain / tune thresholds ◄────────────┘

How the parts fit together

Series store and windowing

The detector reads series from the metrics store and keeps its own small state per series. The store holds history in compressed form: Gorilla XOR compression stores timestamps as deltas of deltas and values as the XOR of consecutive float bit patterns, which is why weeks of history for millions of series fit in memory (Pelkonen et al., VLDB 2015). Training and backtesting read long ranges of one or a few series at a time, the access pattern Columnar storage is built for.

Points must be aligned to a fixed step (for example one minute) before modelling, because decomposition and exponential smoothing assume regularly spaced samples. Windowed stream aggregation does this on the live path: group events by event-time window, keep one partial aggregate per window, and emit a window when the watermark passes its end. The contract: the model sees one value per series per step, a missing step is marked missing rather than zero (a gap is not a drop to zero), and late data either revises the window within an allowed lateness or is ignored. For latency metrics the aggregate per window must be mergeable; a percentile cannot be averaged across hosts, so quantile-sketches (no page yet) keep a sketch per window that merges across hosts, and the detector watches the merged percentile.

Baseline model

The baseline answers "what should this value be right now?". Three families cover most needs:

  • Rolling statistics (no seasonality): the median and a robust spread over the last window. Cheap, adapts in minutes, blind to daily cycles. This is the idea of Datadog's "basic" algorithm, a lagging rolling quantile (Datadog anomaly monitor docs).
  • Exponential smoothing (Holt-Winters): keeps a level, a trend and a seasonal profile, each updated by a fraction of the forecast error. It needs O(1) memory per series, so one process can hold millions of series, and a new point updates the state in constant time. The weakness is that a long anomaly leaks into the state: the model learns the outage as normal. The usual fix is to update with a clipped residual (the point capped at the band edge) so a spike barely moves the state.
  • STL decomposition: splits a series into trend, seasonal and remainder with loess smoothing and bisquare robustness weights, so an outlier lands in the remainder rather than bending the seasonal shape. It is a batch method, re-run on a window (for example nightly) and used to project the next period, which keeps it stable through long anomalies at the cost of reacting slowly to intended level shifts. Datadog describes its "robust" algorithm as a seasonal-trend decomposition with exactly this property, and its "agile" algorithm as a robust variant of SARIMA that updates quickly after level shifts at the price of being less robust to long-lasting anomalies (Datadog docs).

arima (no page yet) is the third classical choice, with differencing and autoregressive terms; it fits dynamics that smoothing cannot, but needs order selection and a fit per series, so it suits high-value series rather than a million-series default. Exponential smoothing and STL come first because they have few parameters, fit by recursion, and fail in predictable ways.

Seasonality must be declared or detected: the period is a property of the business (24 hours, 7 days), not something to hunt for in noise. Series shorter than two periods fall back to rolling statistics until they have enough history.

Scoring

The residual is observed minus expected. To compare series of different scale, divide by a spread estimate. The ordinary standard deviation is inflated by the very outliers being sought, so use Robust statistics: the median absolute deviation (MAD) scaled by 1.4826 estimates sigma for normal data and has a 50 % breakdown point, while the standard deviation has none. The score is a robust z: (observed − forecast) / (1.4826 · MAD of recent residuals). A cut around 3 to 4 is a common starting point; the real value is set by the cost of false alarms.

For several signals that matter jointly (CPU, latency, error rate of one service), per-series scores miss the combination. Isolation forest scores a feature vector, one row per time step, by how few random axis-aligned splits isolate it; anomalies are few and different, so they isolate early. With 100 trees of 256 samples (the scikit-learn defaults, as listed on the block page) the model is small and scoring is cheap enough for the live path. The price is interpretability: the score says "unusual", not which metric moved, so keep per-series scores beside it for the explanation.

Shift detection

A step change is not a spike. After a deploy, traffic may settle at a new level; a detector that keeps calling it anomalous is useless, while one that adapts too fast hides a real regression. change-point-detection (no page yet) separates the cases with methods such as CUSUM, which accumulates small deviations until their sum crosses a bound, or PELT, which finds the best segmentation of a series. The policy: a short excursion is an anomaly; a sustained shift raises one "level shift" event and then re-baselines the series. Record deploy times as annotations so a shift can be attributed.

Decision

Raw scores are not alerts. Three filters sit between them:

  1. Persistence. Require the score to stay over the threshold for several consecutive steps. Prometheus alerting rules use the same idea with the for clause: an element must stay active at every evaluation for the whole duration before the alert fires (Prometheus alerting-rules docs).
  2. Error-rate control across series. With 100,000 series tested every minute, even a one-in-a-thousand false-positive rate gives about 100 false alerts per step. Hypothesis testing supplies the frame: convert scores to tail probabilities under the "no anomaly" model and control the false discovery rate (the Benjamini-Hochberg procedure covered on that page) instead of testing each series alone. In practice many systems set the threshold per series from its own history and alert on the count of series that agree.
  3. Grouping. Anomalies on the same service, host or deploy within a window become one alert, grouped by labels, with the top contributing series as context.

For event streams with high-cardinality keys (error messages, URL paths), a Count-min sketch counts each key per window in fixed memory; a jump in a key's estimated count, or a new heavy key, feeds the same scoring. Count-min only overestimates, so thresholds on the estimate err toward false positives, which persistence then filters.

Feedback and evaluation

A detector without feedback decays. Operators mark alerts useful or noise; those labels tune per-series thresholds and choose the algorithm per series. Evaluate offline by backtesting: replay the stream in time order and never score a point with a model that saw its future (Time-series cross-validation is the rolling-origin scheme), and report precision and recall with a tolerance window, since an alert a few minutes late is still a hit. The Numenta Anomaly Benchmark is an open corpus of labelled streams for comparing streaming detectors. Model monitoring applies the same machinery to ML inputs and outputs, and Canary analysis compares against a control group instead of against history.

Data and control flow

A new point arrives:

  1. The sample reaches the store; the windowing stage aligns it to the step and marks gaps.
  2. The detector loads the series state (level, trend, seasonal profile, residual spread), forecasts the step and computes the residual.
  3. It divides by the robust spread to get the score and compares it with the series' threshold.
  4. It updates the state with the clipped residual, so the baseline adapts but not to the anomaly.
  5. If the score stays over the threshold for the required steps, it emits a candidate; the shift detector decides whether it is a spike or a new level.
  6. The decision layer applies error-rate control and grouping, attaches context (series, band, recent deploys) and sends one alert to the alerting system.

A nightly retrain: for each series, STL or a Holt-Winters refit runs on the last several weeks, excluding steps already flagged; the new parameters are backtested against the last week and replace the old ones only if they score no worse.

A feedback loop: an operator marks an alert as noise; the label raises that series' threshold or switches it to a more tolerant algorithm; the next backtest includes the label.

Scaling

In the order the limits appear:

  1. Number of series. Keep per-series state O(1) (smoothing state, a few numbers) in memory, shard series by key hash, and use cheaper models for rarely queried series. Score only series that received a point.
  2. Cold start. New series have no history; use rolling statistics at first, borrow a seasonal profile from a similar series (same metric, other host) and mark the output low confidence.
  3. Training cost. STL and ARIMA refits are batch work: run them nightly, only on series with enough history and recent traffic, and start from the last fit.
  4. False alert volume. Grows with the number of series, not with traffic: control it with persistence, FDR control and grouping before adding detection power.
  5. Storage and read cost. Backtests read long ranges: keep columnar copies of rollups so a backtest reads only the columns it needs.

Failure modes

FailureSymptomCauseFix
Alert storm at the start of the weekmany series flagged on Monday morningweekly seasonality missing or too little historydeclare a weekly period; fall back to rolling statistics until two periods are seen
Baseline learns the outagealert fires, then silence while the problem persistsanomalous points update the stateupdate with clipped residual; use a robust method (STL) for slow-moving series
Missed regression after a deploya slow rise never alertsslow drift absorbed by an adaptive baselinechange-point detection; compare with the previous release; a slow-drift rule
Constant alarms after a level shiftseries stays "anomalous" for daysno re-baselining after an intended changeshift detection with deploy annotations; re-baseline after a confirmed shift
Gaps read as dropsalert when a collector restartsmissing samples treated as zerogap-aware windows; alert on "no data" separately
Noise on low-volume seriesscore jumps on tiny countsvariance of counts is not constantlonger steps; count-aware thresholds
Daylight-saving mismatchwrong band twice a yearseasonal profile fitted in the wrong time zonefit seasonality in the business time zone (Datadog documents this for daily and weekly seasonality)
Look-ahead in evaluationgreat offline scores, poor live resultsbacktest used future data in the fitrolling-origin backtests only
Alert fatigueoperators mute the detectorno grouping, no feedbackgroup by labels, learn from feedback, rank by impact

Real implementations

namewhat it isrepolicencenotes
Datadog anomaly monitors and Watchdogcommercial monitoring with basic, agile and robust algorithms——only what the public docs describe
Prometheusmetrics store and alerting rules; predict_linear for a linear forecast and the for clause for persistenceprometheus/prometheusApache-2.0no learned seasonality built in
AnomalyDetection (Twitter)R package "Anomaly Detection with R" from the Hochenbaum et al. method; archivedtwitter/AnomalyDetectionGPL-3.0
Luminol (LinkedIn)Python anomaly detection and correlation librarylinkedin/luminolApache-2.0
ADTKPython toolkit for rule-based and unsupervised detection in time seriesarundo/adtkMPL-2.0
Merlion (Salesforce)Python framework for time-series intelligence; archivedsalesforce/MerlionBSD-3-Clause
statsmodelsSTL and exponential-smoothing models usable as baselinesstatsmodels/statsmodelsBSD-3-Clauselibrary, not a detector
Numenta Anomaly Benchmarklabelled streams for evaluating streaming detectorsnumenta/NABMITevaluation, not production

Sources

Similar systems

Share the most building blocks with this one.