- An anomaly is a departure from expected behaviour, so every method starts by defining "expected": a fixed limit, a statistical baseline, a seasonal pattern, a forecast, or a learned model of normal data.
- A common approach is to start simple: engineering limits and statistical baselines (control-chart style limits, EWMA) are explainable and can run in SQL or a stream processor. Seasonal decomposition is a natural next step when daily and weekly patterns dominate, and machine learning when many variables interact. This ordering is a judgement, not a rule from a single source.
- Where detection runs is an architecture choice. One common split: the edge for immediate safety limits, a stream processor for low-latency rules on every reading, the database for scheduled checks over recent windows, and the analytics platform for model training and batch scoring over long history.
- Alert fatigue is a well-documented failure mode: the Google SRE book describes people skimming or ignoring pages that arrive too often. Common controls are requiring a condition to persist before alerting, suppressing during known maintenance, grouping related alerts, and sending uncertain anomalies to a review queue rather than a pager.
- Evaluate against labelled events, for example confirmed faults from CMMS work orders, with precision and recall, testing on periods later than the training data. Counting per event rather than per reading, and tracking alerts per site per week, are our suggestions for operational data, not a standard.
What time-series anomaly detection is, and who this is for
Time-series anomaly detection is the automated search for readings, or runs of readings, that do not fit the expected behaviour of a series. In a building portfolio that might be an AHU whose supply-air temperature drifts away from setpoint, a chiller drawing more kW than usual for the same load, a zone CO2 sensor that reports the same value for six hours, or an electricity meter that jumps backwards after a reset.
This explainer is for engineers, data engineers and facilities analysts deciding how to detect such problems across BMS, metering and CMMS data. It covers the methods and the architecture. The SQL implementation, with rolling averages and standard deviations computed by window functions, is in SQL Anomaly Detection Using Rolling Baselines. For the underlying storage, see the time-series database overview.
Kinds of anomaly in building and IoT data
A common way to classify anomalies, widely used in the anomaly detection literature, has the groups below. The grouping is a convention rather than a standard, and the building examples are ours, for illustration.
- Point anomalies (spikes and dips). One reading far outside the usual range, such as a supply-air temperature of 85 degC. This can be a sensor or communication fault rather than a real event.
- Contextual anomalies. A value that is normal at one time and abnormal at another: an AHU running at full speed at 03:00 on a Sunday in an unoccupied office, or heating and cooling valves open at the same time.
- Collective or pattern anomalies. A run of readings that is wrong together: a flatlined sensor, slow drift after a calibration problem, a meter that stops incrementing, or a daily load profile that changes shape.
- Multivariate anomalies. Each value looks normal on its own, but the combination does not: chiller kW normal, but chilled-water delta-T and load low, suggesting fouling or a valve fault.
Separate data quality problems (gaps, duplicates, stuck values, impossible ranges) from process anomalies (the equipment is behaving abnormally). The first should be handled before or during ingestion, as described in IoT Data Quality Checks Before Database Ingestion; otherwise the detector spends its alerts on bad data.
Anomaly detection algorithms: the main families
Methods differ in how they define "expected". The table groups common approaches in rough order of complexity; it is not a ranking, and there is no universal best method: the right choice depends on the signal, the history available, the faults that matter and who acts on the results. The "often used for" and "watch out for" columns are our summary and judgement, while the sourced detail for each family is in the subsections below. Any thresholds mentioned on this page (such as 3-sigma limits or a vendor's default) are illustrations of how a method is configured, not values to copy.
| Method | Expected behaviour is... | Often used for | Watch out for |
|---|---|---|---|
| Fixed thresholds and rate-of-change limits | An engineering limit (high, low, maximum change per minute) | Safety limits, impossible values, stuck sensors | One limit rarely fits all seasons and occupancy states |
| Statistical baselines (control charts, EWMA) | Mean and spread from recent or historical data | Drift and shifts in stable series; explainable | Assumes a fairly stable process; seasonality inflates the spread |
| Seasonal decomposition | Trend plus daily and weekly seasonal pattern; the remainder is scored | Occupancy-driven loads, energy profiles | Needs enough history to learn each season; holidays and schedule changes |
| Forecast residuals | A forecast from a time-series model | Series with trend and seasonality; prediction intervals | Model maintenance; a poor forecast produces false alerts |
| Unsupervised machine learning | Regions where normal training data is dense | Many variables together (multivariate equipment behaviour) | Harder to explain; needs mostly clean training data |
| Supervised machine learning | Patterns learned from labelled faults | Recurring, well-documented fault types | Needs enough labelled examples, which most sites lack |
Thresholds and statistical baselines
Fixed limits are what BMS alarms already do, and they remain a common tool for safety and for physically impossible values. Statistical baselines generalise them: the NIST/SEMATECH e-Handbook describes control charts with a centre line and upper and lower control limits, usually placed at three standard deviations (3-sigma limits). That multiple comes from statistical process control; for noisy, seasonal sensor data the right multiple has to be chosen from your false-alarm tolerance and checked against labelled history. An EWMA (exponentially weighted moving average) chart gives less weight to older data, and NIST notes that, through the choice of weighting factor, it can be made sensitive to small or gradual drift, which a plain limit only catches once a single reading crosses it. For sensors, compute baselines per point and, where behaviour differs, per occupancy state or hour of the week.
Seasonal decomposition and forecast residuals
Building data is often strongly seasonal: daily occupancy, weekly schedules and the annual weather cycle. Decomposition splits a series into a trend-cycle component, one or more seasonal components and a remainder, as set out in Hyndman and Athanasopoulos, Forecasting: Principles and Practice; data observed at least daily can have more than one seasonal period. Anomalies are then judged on the remainder, so a normal Monday-morning peak is not flagged. Built-in functions follow this approach: the Kusto series_decompose_anomalies() function bases detection on series decomposition with a default threshold of 1.5, and Amazon CloudWatch anomaly detection models trends and hourly, daily and weekly patterns, training on up to two weeks of metric data. Forecasting models work similarly: readings outside the forecast's expected range are flagged, as with the ARIMA_PLUS models that BigQuery ML's ML.DETECT_ANOMALIES uses for time series.
Machine learning anomaly detection
A common reason to use machine learning is that the signal is in combinations of variables. The scikit-learn documentation distinguishes outlier detection (training data contains outliers; also called unsupervised anomaly detection) from novelty detection (training data is clean; semi-supervised). Isolation Forest is a common unsupervised choice: it isolates observations with random splits, and points that are isolated quickly score as anomalous. BigQuery ML documents unsupervised options (k-means, autoencoder, PCA) for independent observations rather than time series and recommends supervised models when you already have labelled anomalies. Elastic's machine learning features also model time series data to find anomalous patterns. Treat model output as a score to be thresholded and reviewed, not a verdict, and record the model version with every score.
Where detection runs: edge, stream, database or analytics
The same method can run in different places. The table is our summary of common placement options, not a cited standard; the main factors are the latency you need and the history the method uses.
| Where | Typical tools | Latency | Often used for | Limits |
|---|---|---|---|---|
| Edge (controller or gateway) | BMS alarm limits, gateway rules | Immediate | Safety limits, local interlocks, stuck values | Little history and compute; hard to manage centrally |
| Stream processor | Kafka Streams or other consumers reading the telemetry topic | Seconds | Rules and baselines on every reading across all sites | State must be managed; long-history models are awkward |
| Time-series or relational database | Scheduled SQL over the last hours or days | Minutes | Rolling baselines, persistence checks, joins with asset and CMMS data | Load on the operational database; not every engine has rich window functions |
| Analytics platform | Warehouse or lakehouse ML (for example BigQuery ML), notebooks | Hours | Training on months or years, multivariate models, batch scoring | Batch latency usually too high for urgent operational alarms |
A common split
One split that is often used, described here as an example rather than a rule: keep hard safety limits at the edge. Run simple per-point rules in the stream so that every site gets them without polling the database (Kafka Streams is the processing library that ships with Kafka; see Apache Kafka Explained and Designing an IoT Data Pipeline with Kafka). Run rolling-baseline and persistence checks in the database every few minutes, where readings can be joined with the asset register and open work orders. Train and evaluate seasonal and multivariate models on the analytics platform, then either score in batch there or push the fitted thresholds back to the stream or database. Write all results to one anomaly table (point, start, end, method, score, model version, status) so that the CMMS integration and dashboards read from one place.
Alert fatigue: from anomalies to actions
A detector that fires too often risks being ignored. The Google SRE book puts it plainly: when pages are too frequent, people second-guess, skim or ignore them, and every page should be actionable. For building operations, the equivalent of a page is often an automatically raised work order, which costs a technician visit. Common controls follow; the persistence clause is documented by Prometheus, and the rest are widely used operational practices offered as options, not rules. Any durations involved (how long a condition must persist, how long to suppress) are choices to make per alert from how quickly someone must act and how noisy the signal is.
- Persistence. Require the condition to hold for a period before alerting. Prometheus alerting rules have a
forclause for exactly this, and akeep_firing_forclause to stop flapping alerts resolving and re-firing. - Context suppression. Suppress alerts for assets with an open maintenance work order, during commissioning, or when the BMS reports the equipment as off or in manual override.
- Grouping. One chiller fault can disturb dozens of points; group by asset or plant system and raise one alert.
- Tiering. Page only for safety and service-affecting conditions. Send lower-confidence anomalies to a daily review queue, and raise a CMMS work order only after a person or a confirmed rule says so.
- Symptoms over causes. The Prometheus guidance is to keep alerting simple and alert on symptoms; for buildings, a zone out of comfort range for a sustained period (the length is your choice) often matters more, in our view, than one valve position that looks unusual.
Evaluating a detector
The points below combine sourced definitions (precision, recall, time-ordered splits) with our suggestions for operational telemetry, which are marked as such.
- Labels. Build a set of known events from CMMS work orders with fault codes, BMS alarm logs and commissioning reports, with asset and time window. It will be incomplete, so treat unlabelled detections as "unknown", not automatically false.
- Metrics. Use precision (how many alerts were real) and recall (how many real events were caught), as defined in the scikit-learn evaluation guide. Our suggestion is to count them per event rather than per reading (for example, a fault lasting six hours at one-minute data is one event, not 360 points) and to add operational measures such as alerts per site per week and time from fault onset to alert.
- Time-based splits. Train on earlier periods and test on later ones, including a full seasonal cycle where possible. The scikit-learn cross-validation guide explains that classical techniques such as KFold and ShuffleSplit assume independent samples and give poor estimates of generalisation error on autocorrelated time series, and that a model should be evaluated on "future" observations.
- Exclude known disruption from training. Baselines learned over a shutdown or a sensor fault make that behaviour look normal. Amazon CloudWatch, for example, lets you exclude specified time periods from model training for this reason.
- Review regularly. Occupancy patterns, setpoints and equipment change; re-check thresholds and retrain models on a schedule, and track the alert rate after each change.
Data, retention, security and managed services
- Data needed. Statistical baselines need enough clean history per point to estimate normal behaviour, and seasonal models need several complete cycles of each season they model; how much is enough depends on noise and is best judged against labelled history rather than a fixed rule. Plan retention so raw or rolled-up data covers that window; see Time-Series Retention and Downsampling Design.
- Sizing. Detection output is small compared with readings, but scores per reading are not; store anomaly events, and keep per-reading scores only for a short window if you need them for tuning.
- Security. Anomaly results can reveal occupancy and operating patterns. Apply the same access control as the readings, and if data leaves your environment for a cloud ML service, check where it is processed and stored.
- Managed service lifecycle. Built-in features change. Microsoft stopped new Azure Anomaly Detector resources from 20 September 2023 and announced the service's retirement on 1 October 2026, recommending Microsoft Fabric or the open source project instead (its overview page still carried that notice when checked on 27 October 2026, after the retirement date). Keep the method, thresholds and evaluation data in your own documentation and storage so that a detector can move between platforms.
When not to use machine learning (or automated detection at all)
These are judgement calls rather than sourced rules:
- Clear engineering limits exist. If a fault is defined by a limit (frost protection, high static pressure, CO2 above a set level), a rule is usually simpler, faster and easier to justify than a model.
- Too little history or too few points. A handful of sensors with a few weeks of data is often better served by baselines and a person looking at trends.
- No one to act on results. Detection without an owner and a response process produces unread alerts. Agree who reviews anomalies and how they become work orders before you build.
- Bad data upstream. If gaps, duplicates and stuck values are common, fix ingestion and data quality first.
To build the first detector in SQL, continue with SQL Anomaly Detection Using Rolling Baselines.
Frequently asked questions
What is time series anomaly detection?
The automated search for readings or patterns that depart from the expected behaviour of a series, where "expected" comes from a fixed limit, a statistical baseline, a seasonal pattern, a forecast or a model trained on normal data.
Which anomaly detection algorithm should I start with?
A common starting point is engineering limits plus a statistical baseline per point (a rolling mean and standard deviation, or EWMA), with a persistence condition, and thresholds chosen against labelled history. Seasonal decomposition is worth trying when daily and weekly patterns cause false alerts, and machine learning when faults show up only in combinations of variables. This is a judgement, not a universal rule.
Do I need machine learning for anomaly detection?
Not always. Many building faults can be caught by limits and baselines that are easier to explain and maintain. Machine learning anomaly detection is more likely to pay off for multivariate equipment behaviour and when there is history and staff time to evaluate and maintain models. There is no universal best method; this is a judgement.
Should anomaly detection run in the database or in the stream?
Both can be right. Stream processing gives low latency on every reading; scheduled SQL in the database can use longer windows and join with asset and work-order data; the analytics platform suits training models on long history. Some systems use all three for different checks; which fits depends on the latency you need and the history the method uses.
How do I reduce false alarms?
Require the condition to persist, suppress alerts during maintenance or when equipment is off, group alerts by asset, page only for urgent conditions, and evaluate the detector against confirmed faults so thresholds can be tuned with evidence.
Sources
- NIST/SEMATECH e-Handbook of Statistical Methods: What are Control Charts?
- NIST/SEMATECH e-Handbook of Statistical Methods: EWMA Control Charts
- Hyndman and Athanasopoulos, Forecasting: Principles and Practice (3rd ed.): Time series decomposition
- Microsoft Learn: series_decompose_anomalies() (Kusto)
- Amazon CloudWatch documentation: Using CloudWatch anomaly detection
- BigQuery ML documentation: Anomaly detection overview
- scikit-learn documentation: Novelty and Outlier Detection
- scikit-learn documentation: IsolationForest
- scikit-learn documentation: Metrics and scoring
- scikit-learn documentation: Cross-validation (time series data)
- Elastic documentation: Anomaly detection with machine learning
- Microsoft Learn: What is Anomaly Detector?
- Google SRE book: Monitoring Distributed Systems
- Prometheus documentation: Alerting rules
- Prometheus documentation: Alerting practices
- Apache Kafka 4.4 documentation: Introduction
Checked 27 October 2026.
How we research these articles: our editorial method. Research-based from official documentation; SQL examples are run on a local database where the page says so. CodeWithSQL earns nothing from the vendors mentioned.