mirror of
https://github.com/VictoriaMetrics/VictoriaMetrics.git
synced 2026-08-07 00:06:46 +03:00
Compare commits
9 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c620cb30b8 | ||
|
|
0033834d3c | ||
|
|
ce7b1fba58 | ||
|
|
8855e983b9 | ||
|
|
6b3dc18654 | ||
|
|
e24adb1501 | ||
|
|
0c2dd583c8 | ||
|
|
029540c356 | ||
|
|
4baba77b15 |
16
.github/workflows/build.yml
vendored
16
.github/workflows/build.yml
vendored
@@ -73,11 +73,19 @@ jobs:
|
||||
id: go
|
||||
uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0
|
||||
with:
|
||||
cache-dependency-path: |
|
||||
go.sum
|
||||
Makefile
|
||||
app/**/Makefile
|
||||
cache: false
|
||||
go-version-file: 'go.mod'
|
||||
|
||||
- name: Cache Go build artifacts
|
||||
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
|
||||
with:
|
||||
path: |
|
||||
~/.cache/go-build
|
||||
~/go/pkg/mod
|
||||
key: go-build-${{ matrix.os }}-${{ matrix.arch }}-${{ hashFiles('go.sum', 'Makefile') }}
|
||||
restore-keys: |
|
||||
go-build-${{ matrix.os }}-${{ matrix.arch }}-
|
||||
|
||||
- run: go version
|
||||
|
||||
- name: Build victoria-metrics for ${{ matrix.os }}-${{ matrix.arch }}
|
||||
|
||||
@@ -3,7 +3,7 @@ services:
|
||||
# It scrapes targets defined in --promscrape.config
|
||||
# And forward them to --remoteWrite.url
|
||||
vmagent:
|
||||
image: victoriametrics/vmagent:v1.148.0
|
||||
image: victoriametrics/vmagent:v1.149.0
|
||||
depends_on:
|
||||
- "vmauth"
|
||||
ports:
|
||||
@@ -42,14 +42,14 @@ services:
|
||||
# vmstorage shards. Each shard receives 1/N of all metrics sent to vminserts,
|
||||
# where N is number of vmstorages (2 in this case).
|
||||
vmstorage-1:
|
||||
image: victoriametrics/vmstorage:v1.148.0-cluster
|
||||
image: victoriametrics/vmstorage:v1.149.0-cluster
|
||||
volumes:
|
||||
- strgdata-1:/storage
|
||||
command:
|
||||
- "--storageDataPath=/storage"
|
||||
restart: always
|
||||
vmstorage-2:
|
||||
image: victoriametrics/vmstorage:v1.148.0-cluster
|
||||
image: victoriametrics/vmstorage:v1.149.0-cluster
|
||||
volumes:
|
||||
- strgdata-2:/storage
|
||||
command:
|
||||
@@ -59,7 +59,7 @@ services:
|
||||
# vminsert is ingestion frontend. It receives metrics pushed by vmagent,
|
||||
# pre-process them and distributes across configured vmstorage shards.
|
||||
vminsert-1:
|
||||
image: victoriametrics/vminsert:v1.148.0-cluster
|
||||
image: victoriametrics/vminsert:v1.149.0-cluster
|
||||
depends_on:
|
||||
- "vmstorage-1"
|
||||
- "vmstorage-2"
|
||||
@@ -68,7 +68,7 @@ services:
|
||||
- "--storageNode=vmstorage-2:8400"
|
||||
restart: always
|
||||
vminsert-2:
|
||||
image: victoriametrics/vminsert:v1.148.0-cluster
|
||||
image: victoriametrics/vminsert:v1.149.0-cluster
|
||||
depends_on:
|
||||
- "vmstorage-1"
|
||||
- "vmstorage-2"
|
||||
@@ -80,7 +80,7 @@ services:
|
||||
# vmselect is a query fronted. It serves read queries in MetricsQL or PromQL.
|
||||
# vmselect collects results from configured `--storageNode` shards.
|
||||
vmselect-1:
|
||||
image: victoriametrics/vmselect:v1.148.0-cluster
|
||||
image: victoriametrics/vmselect:v1.149.0-cluster
|
||||
depends_on:
|
||||
- "vmstorage-1"
|
||||
- "vmstorage-2"
|
||||
@@ -90,7 +90,7 @@ services:
|
||||
- "--vmalert.proxyURL=http://vmalert:8880"
|
||||
restart: always
|
||||
vmselect-2:
|
||||
image: victoriametrics/vmselect:v1.148.0-cluster
|
||||
image: victoriametrics/vmselect:v1.149.0-cluster
|
||||
depends_on:
|
||||
- "vmstorage-1"
|
||||
- "vmstorage-2"
|
||||
@@ -105,7 +105,7 @@ services:
|
||||
# read requests from Grafana, vmui, vmalert among vmselects.
|
||||
# It can be used as an authentication proxy.
|
||||
vmauth:
|
||||
image: victoriametrics/vmauth:v1.148.0
|
||||
image: victoriametrics/vmauth:v1.149.0
|
||||
depends_on:
|
||||
- "vmselect-1"
|
||||
- "vmselect-2"
|
||||
@@ -119,7 +119,7 @@ services:
|
||||
|
||||
# vmalert executes alerting and recording rules
|
||||
vmalert:
|
||||
image: victoriametrics/vmalert:v1.148.0
|
||||
image: victoriametrics/vmalert:v1.149.0
|
||||
depends_on:
|
||||
- "vmauth"
|
||||
ports:
|
||||
|
||||
@@ -3,7 +3,7 @@ services:
|
||||
# It scrapes targets defined in --promscrape.config
|
||||
# And forward them to --remoteWrite.url
|
||||
vmagent:
|
||||
image: victoriametrics/vmagent:v1.148.0
|
||||
image: victoriametrics/vmagent:v1.149.0
|
||||
depends_on:
|
||||
- "victoriametrics"
|
||||
ports:
|
||||
@@ -18,7 +18,7 @@ services:
|
||||
# VictoriaMetrics instance, a single process responsible for
|
||||
# storing metrics and serve read requests.
|
||||
victoriametrics:
|
||||
image: victoriametrics/victoria-metrics:v1.148.0
|
||||
image: victoriametrics/victoria-metrics:v1.149.0
|
||||
ports:
|
||||
- 8428:8428
|
||||
- 8089:8089
|
||||
@@ -59,7 +59,7 @@ services:
|
||||
|
||||
# vmalert executes alerting and recording rules
|
||||
vmalert:
|
||||
image: victoriametrics/vmalert:v1.148.0
|
||||
image: victoriametrics/vmalert:v1.149.0
|
||||
depends_on:
|
||||
- "victoriametrics"
|
||||
- "alertmanager"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
services:
|
||||
vmagent:
|
||||
image: victoriametrics/vmagent:v1.148.0
|
||||
image: victoriametrics/vmagent:v1.149.0
|
||||
depends_on:
|
||||
- "victoriametrics"
|
||||
ports:
|
||||
@@ -14,7 +14,7 @@ services:
|
||||
restart: always
|
||||
|
||||
victoriametrics:
|
||||
image: victoriametrics/victoria-metrics:v1.148.0
|
||||
image: victoriametrics/victoria-metrics:v1.149.0
|
||||
ports:
|
||||
- 8428:8428
|
||||
volumes:
|
||||
@@ -40,7 +40,7 @@ services:
|
||||
restart: always
|
||||
|
||||
vmalert:
|
||||
image: victoriametrics/vmalert:v1.148.0
|
||||
image: victoriametrics/vmalert:v1.149.0
|
||||
depends_on:
|
||||
- "victoriametrics"
|
||||
ports:
|
||||
@@ -59,7 +59,7 @@ services:
|
||||
- '--external.alert.source=explore?orgId=1&left=["now-1h","now","VictoriaMetrics",{"expr": },{"mode":"Metrics"},{"ui":[true,true,true,"none"]}]'
|
||||
restart: always
|
||||
vmanomaly:
|
||||
image: victoriametrics/vmanomaly:v1.30.0
|
||||
image: victoriametrics/vmanomaly:v1.30.1
|
||||
depends_on:
|
||||
- "victoriametrics"
|
||||
ports:
|
||||
|
||||
@@ -16,6 +16,27 @@ Please find the changelog for VictoriaMetrics Anomaly Detection below.
|
||||
|
||||
{{% collapse name="2026" open=true %}}
|
||||
|
||||
## v1.30.1
|
||||
Released: 2026-08-06
|
||||
|
||||
- UI: Updated [vmanomaly UI](https://docs.victoriametrics.com/anomaly-detection/ui/) from [v1.8.0](https://docs.victoriametrics.com/anomaly-detection/ui/#v180) to [v1.8.1](https://docs.victoriametrics.com/anomaly-detection/ui/#v181). The update improves UX validation and fixes regressions introduced by new design.
|
||||
|
||||
- IMPROVEMENT: Reduced fit and inference latency for the Z-score, MAD, standard deviation, Seasonal Quantile, and Rolling Quantile online models. Representative service-stage gains range from 1.5-2.6x for fit and 1.7-2.3x for inference, depending on model, storage mode, and data size.
|
||||
|
||||
- IMPROVEMENT: Removed forwarded datasource credentials from in-memory state for completed, failed, canceled, and shutting-down [analysis and autotune tasks](https://docs.victoriametrics.com/anomaly-detection/components/server/#time-series-analysis-and-autotune-api).
|
||||
|
||||
- BUGFIX: Stabilized [Temporal Envelope](https://docs.victoriametrics.com/anomaly-detection/components/models/#temporal-envelope) after fitting across a late level shift. Its level, trend, residual, and supported calendar state now initialize coherently from the recent regime, avoiding stale fitted magnitudes and false seasonal oscillations when periodic inference starts.
|
||||
|
||||
- BUGFIX: Corrected `/api/v1/timeseries/characteristics` seasonality detection for time series whose timestamps are offset from whole sampling intervals. Trend interpolation now preserves the original observation grid, allowing daily and weekly patterns to be detected on shifted grids.
|
||||
|
||||
- BUGFIX: Restored backward-compatible `inference_only` [backtesting](https://docs.victoriametrics.com/anomaly-detection/components/scheduler/#backtesting-scheduler) for configurations that omit `infer_every`. The scheduler derives its inference grid from the query step or reader sampling period and preserves valid single-timestamp range queries.
|
||||
|
||||
- BUGFIX: Aligned periodic inference for exact-capable online models with exact backtesting (used in [UI](https://docs.victoriametrics.com/anomaly-detection/ui/) experiments) by applying the configured `infer_every` as the causal update cadence.
|
||||
|
||||
- BUGFIX: Corrected [self-monitoring](https://docs.victoriametrics.com/anomaly-detection/components/monitoring/#writer-behaviour-metrics) accounting so failed VictoriaMetrics write attempts contribute to `vmanomaly_writer_request_duration_seconds`, including connection retries, and inference counts only unseen *valid* rows in `vmanomaly_model_datapoints_accepted`.
|
||||
|
||||
- BUGFIX: Fixed service-level [`settings.anomaly_score_outside_data_range`](https://docs.victoriametrics.com/anomaly-detection/components/settings/#anomaly-score-outside-data-range) propagation so its configured score applies to every model unless the model defines its own override.
|
||||
|
||||
## v1.30.0
|
||||
Released: 2026-07-23
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ The decision to set the changepoint at `1.0` is made to ensure consistency acros
|
||||
> `anomaly_score` is a metric itself, which preserves all labels found in input data and (optionally) appends [custom labels, specified in writer](https://docs.victoriametrics.com/anomaly-detection/components/writer/#metrics-formatting) - follow the link for detailed output example.
|
||||
|
||||
## How is anomaly score calculated?
|
||||
For most of the [univariate models](https://docs.victoriametrics.com/anomaly-detection/components/models/#univariate-models) that can generate `yhat`, `yhat_lower`, and `yhat_upper` time series in [their output](https://docs.victoriametrics.com/anomaly-detection/components/models/#vmanomaly-output) (such as [Prophet](https://docs.victoriametrics.com/anomaly-detection/components/models/#prophet) or [Z-score](https://docs.victoriametrics.com/anomaly-detection/components/models/#z-score)), the anomaly score is calculated as follows:
|
||||
For most of the [univariate models](https://docs.victoriametrics.com/anomaly-detection/components/models/#univariate-models) that can generate `yhat`, `yhat_lower`, and `yhat_upper` time series in [their output](https://docs.victoriametrics.com/anomaly-detection/components/models/#vmanomaly-output) (such as [Temporal Envelope](https://docs.victoriametrics.com/anomaly-detection/components/models/#temporal-envelope) or [Online Z-score](https://docs.victoriametrics.com/anomaly-detection/components/models/#online-z-score)), the anomaly score is calculated as follows:
|
||||
- If `yhat` (expected series behavior) equals `y` (actual value observed), then the anomaly score is 0.
|
||||
- If `y` (actual value observed) falls within the `[yhat_lower, yhat_upper]` confidence interval, the anomaly score will gradually approach 1, the closer `y` is to the boundary.
|
||||
- If `y` (actual value observed) strictly exceeds the `[yhat_lower, yhat_upper]` interval, the anomaly score will be greater than 1, increasing as the margin between the actual value and the expected range grows.
|
||||
@@ -82,7 +82,7 @@ reader:
|
||||
|
||||
`vmanomaly` supports timezone-aware anomaly detection {{% available_from "v1.18.0" anomaly %}} through a `tz` argument, available both at the [reader level](https://docs.victoriametrics.com/anomaly-detection/components/reader/#vm-reader) and at the [query level](https://docs.victoriametrics.com/anomaly-detection/components/reader/#per-query-parameters).
|
||||
|
||||
For models that depend on seasonality, such as [`ProphetModel`](https://docs.victoriametrics.com/anomaly-detection/components/models/#prophet) and [`OnlineQuantileModel`](https://docs.victoriametrics.com/anomaly-detection/components/models/#online-seasonal-quantile), handling timezone shifts is crucial. Changes like Daylight Saving Time (DST) can disrupt seasonality patterns learned by models, resulting in inaccurate anomaly predictions as the periodic patterns shift with time. Proper timezone configuration ensures that seasonal cycles align with expected intervals, even as DST changes occur.
|
||||
For models that depend on seasonality, such as [`TemporalEnvelopeModel`](https://docs.victoriametrics.com/anomaly-detection/components/models/#temporal-envelope) and [`OnlineQuantileModel`](https://docs.victoriametrics.com/anomaly-detection/components/models/#online-seasonal-quantile), handling timezone shifts is crucial. Changes like Daylight Saving Time (DST) can disrupt seasonality patterns learned by models, resulting in inaccurate anomaly predictions as the periodic patterns shift with time. Proper timezone configuration ensures that seasonal cycles align with expected intervals, even as DST changes occur.
|
||||
|
||||
To enable timezone handling:
|
||||
1. **Reader-level**: Set `tz` in the [`reader`](https://docs.victoriametrics.com/anomaly-detection/components/reader/#vm-reader) section to a specific timezone (e.g., `Europe/Berlin`) to apply this setting to all queries.
|
||||
@@ -100,9 +100,9 @@ reader:
|
||||
tz: 'Europe/London' # per-query override
|
||||
models:
|
||||
seasonal_model:
|
||||
class: 'prophet'
|
||||
class: 'temporal_envelope'
|
||||
queries: ['your_query']
|
||||
# other model params ...
|
||||
seasonalities: ['hod_smooth', 'dow_smooth']
|
||||
```
|
||||
|
||||
## Output produced by vmanomaly
|
||||
@@ -124,9 +124,8 @@ Selecting the best model for `vmanomaly` depends on the data's nature and the [t
|
||||
|
||||
- Use [Online MAD](https://docs.victoriametrics.com/anomaly-detection/components/models/#online-mad) for simple, mostly stationary data with no-to-slow trend, when robustness to outliers is important.
|
||||
- Use [Online Z-score](https://docs.victoriametrics.com/anomaly-detection/components/models/#online-z-score) for simple, light-tailed data where standard-deviation units are meaningful.
|
||||
- Use [Temporal Envelope](https://docs.victoriametrics.com/anomaly-detection/components/models/#temporal-envelope) {{% available_from "v1.30.0" anomaly %}} for complex data with trends, calendar patterns, holidays, or persistent shifts. It is the preferred *online* alternative to Prophet (which will be deprecated in the future releases).
|
||||
- Use [Temporal Envelope](https://docs.victoriametrics.com/anomaly-detection/components/models/#temporal-envelope) {{% available_from "v1.30.0" anomaly %}} for complex data with trends, calendar patterns, holidays, or persistent shifts. It is the preferred online migration target for existing Prophet configurations.
|
||||
- Use multivariate Temporal Envelope when normal relationships between aligned metrics matter. This should replace [Isolation Forest](https://docs.victoriametrics.com/anomaly-detection/components/models/#isolation-forest-multivariate) used in previous versions of `vmanomaly`, which will be deprecated in future releases.
|
||||
- Use [Prophet](https://docs.victoriametrics.com/anomaly-detection/components/models/#prophet) when Prophet-specific decomposition outputs, or offline batch behavior are required. Consider using Temporal Envelope instead, as it is more efficient and provides better results in most cases.
|
||||
|
||||
There is also an option to auto-tune the most important parameters of a selected model class {{% available_from "v1.12.0" anomaly %}}. {{% available_from "v1.30.0" anomaly %}} The asynchronous autotune API can first profile a bounded sample through `/api/v1/timeseries/characteristics`, then tune a shared concrete configuration through `/api/v1/autotune/tasks`. See the [autotune workflow](https://docs.victoriametrics.com/anomaly-detection/components/models/#shared-asynchronous-autotune-workflow).
|
||||
|
||||
@@ -254,7 +253,7 @@ Configuration above will produce N intervals of full length (`fit_window`=14d +
|
||||
|
||||
## Forecasting
|
||||
|
||||
`vmanomaly` can generate future forecasts using [Temporal Envelope](https://docs.victoriametrics.com/anomaly-detection/components/models/#temporal-envelope) {{% available_from "v1.30.0" anomaly %}} or [ProphetModel](https://docs.victoriametrics.com/anomaly-detection/components/models/#prophet) {{% available_from "v1.25.3" anomaly %}}. This is helpful for capacity planning, resource allocation, or trend analysis when the underlying data is complex and exceeds what inline MetricsQL queries, including [predict_linear](https://docs.victoriametrics.com/victoriametrics/metricsql/#predict_linear), can handle.
|
||||
`vmanomaly` can generate future forecasts with [Temporal Envelope](https://docs.victoriametrics.com/anomaly-detection/components/models/#temporal-envelope) {{% available_from "v1.30.0" anomaly %}}, the preferred online forecasting model. [ProphetModel](https://docs.victoriametrics.com/anomaly-detection/components/models/#prophet) {{% available_from "v1.25.3" anomaly %}} also supports forecasting for existing offline configurations. Forecasts help with capacity planning, resource allocation, or trend analysis when the underlying data is complex and exceeds what inline MetricsQL queries, including [predict_linear](https://docs.victoriametrics.com/victoriametrics/metricsql/#predict_linear), can handle.
|
||||
|
||||
> However, please note that this mode should be used with care, as the model will produce `yhat_{h}` (and probably `yhat_lower_{h}`, and `yhat_upper_{h}`) time series **for each timeseries returned by input queries and for each forecasting horizon specified in `forecast_at` argument, which can lead to a significant increase in the number of active timeseries in VictoriaMetrics TSDB**.
|
||||
|
||||
@@ -432,7 +431,7 @@ services:
|
||||
# ...
|
||||
vmanomaly:
|
||||
container_name: vmanomaly
|
||||
image: victoriametrics/vmanomaly:v1.30.0
|
||||
image: victoriametrics/vmanomaly:v1.30.1
|
||||
# ...
|
||||
restart: always
|
||||
volumes:
|
||||
@@ -554,7 +553,8 @@ reader:
|
||||
expr: 'sum(ALERTS{alertstate=~'(pending|firing)'}) by (alertstate)'
|
||||
max_points_per_query: 5000 # query-level override
|
||||
models:
|
||||
prophet:
|
||||
temporal_envelope:
|
||||
class: temporal_envelope
|
||||
# other model args
|
||||
queries: [
|
||||
'sum_alerts',
|
||||
@@ -575,7 +575,8 @@ reader:
|
||||
sum_alerts:
|
||||
expr: 'sum(ALERTS{alertstate=~'(pending|firing)'}) by (alertstate)'
|
||||
models:
|
||||
prophet:
|
||||
temporal_envelope:
|
||||
class: temporal_envelope
|
||||
# other model args
|
||||
queries: [
|
||||
'sum_alerts',
|
||||
@@ -594,7 +595,8 @@ reader:
|
||||
sum_alerts_firing:
|
||||
expr: 'sum(ALERTS{alertstate='firing'}) by ()'
|
||||
models:
|
||||
prophet:
|
||||
temporal_envelope:
|
||||
class: temporal_envelope
|
||||
# other model args
|
||||
queries: [
|
||||
'sum_alerts_pending',
|
||||
@@ -652,7 +654,7 @@ options:
|
||||
Here’s an example of using the config splitter to divide configurations based on the `extra_filters` argument from the reader section:
|
||||
|
||||
```sh
|
||||
docker pull victoriametrics/vmanomaly:v1.30.0 && docker image tag victoriametrics/vmanomaly:v1.30.0 vmanomaly
|
||||
docker pull victoriametrics/vmanomaly:v1.30.1 && docker image tag victoriametrics/vmanomaly:v1.30.1 vmanomaly
|
||||
```
|
||||
|
||||
```sh
|
||||
|
||||
@@ -45,7 +45,7 @@ There are 2 types of compatibility to consider when migrating in stateful mode:
|
||||
|
||||
| Group start | Group end | Compatibility | Notes |
|
||||
|---------|--------- |------------|-------|
|
||||
| [v1.29.1](https://docs.victoriametrics.com/anomaly-detection/changelog/#v1291) | [v1.30.0](https://docs.victoriametrics.com/anomaly-detection/changelog/#v1300) | Fully Compatible | v1.30.0 adds new [Temporal Envelope](https://docs.victoriametrics.com/anomaly-detection/components/models/#temporal-envelope) model state without changing the compatibility of existing model and data artifacts. |
|
||||
| [v1.29.1](https://docs.victoriametrics.com/anomaly-detection/changelog/#v1291) | [v1.30.1](https://docs.victoriametrics.com/anomaly-detection/changelog/#v1301) | Fully Compatible | v1.30.0 adds new [Temporal Envelope](https://docs.victoriametrics.com/anomaly-detection/components/models/#temporal-envelope) model state without changing the compatibility of existing model and data artifacts. v1.30.1 remains compatible with v1.30.0 state and its compatible predecessors. |
|
||||
| [v1.28.7](https://docs.victoriametrics.com/anomaly-detection/changelog/#v1287) | [v1.29.0](https://docs.victoriametrics.com/anomaly-detection/changelog/#v1290) | Partially compatible* | Dumped models of class [prophet](https://docs.victoriametrics.com/anomaly-detection/components/models/#prophet) and [seasonal quantile](https://docs.victoriametrics.com/anomaly-detection/components/models/#online-seasonal-quantile) have problems with loading to [v1.29.0](https://docs.victoriametrics.com/anomaly-detection/changelog/#v1290) due to dropped `pytz` library. **Upgrading directly from v1.28.7 to [v1.29.1](https://docs.victoriametrics.com/anomaly-detection/changelog/#v1291) with a fix is suggested** |
|
||||
| [v1.26.0](https://docs.victoriametrics.com/anomaly-detection/changelog/#v1262) | [v1.28.7](https://docs.victoriametrics.com/anomaly-detection/changelog/#v1287) | Fully Compatible | [v1.28.0](https://docs.victoriametrics.com/anomaly-detection/changelog/#v1280) introduced [rolling](https://docs.victoriametrics.com/anomaly-detection/components/models/#rolling-models) model class drop in favor of [online](https://docs.victoriametrics.com/anomaly-detection/components/models/#online-models) models (`rolling_quantile` and `std` models), however, it does not impact compatibility, as artifacts were not produced by default for rolling models. Also, offline `mad` and `zscore` models are redirecting to their respective online counterparts since [v1.28.4](https://docs.victoriametrics.com/anomaly-detection/changelog/#v1284). |
|
||||
| [v1.25.3](https://docs.victoriametrics.com/anomaly-detection/changelog/#v1253) | [v1.26.0](https://docs.victoriametrics.com/anomaly-detection/changelog/#v1270) | Partially Compatible* | [v1.25.3](https://docs.victoriametrics.com/anomaly-detection/changelog/#v1253) introduced `forecast_at` argument for base [univariate](https://docs.victoriametrics.com/anomaly-detection/components/models/#univariate-models) and `Prophet` [models](https://docs.victoriametrics.com/anomaly-detection/components/models/#prophet), however, itself remains backward-reversible from newer states like [v1.26.2](https://docs.victoriametrics.com/anomaly-detection/changelog/#v1262), [v1.27.0](https://docs.victoriametrics.com/anomaly-detection/changelog/#v1270). (All models except `isolation_forest_multivariate` class will be dropped) |
|
||||
@@ -71,7 +71,7 @@ In stateless mode, the migration process is almost straightforward as there are
|
||||
|
||||
**Breaking Changes**
|
||||
|
||||
- [v1.12.0](https://docs.victoriametrics.com/anomaly-detection/changelog/#v1120) **ARIMA** model is removed from [built-in models](https://docs.victoriametrics.com/anomaly-detection/components/models/#built-in-models); Action: replace ARIMA by [Prophet](https://docs.victoriametrics.com/anomaly-detection/components/models/#prophet) or alternative seasonal models in `model(s)` section of your configuration files.
|
||||
- [v1.12.0](https://docs.victoriametrics.com/anomaly-detection/changelog/#v1120) **ARIMA** model is removed from [built-in models](https://docs.victoriametrics.com/anomaly-detection/components/models/#built-in-models). Action: for vmanomaly v1.30.0 and newer, replace ARIMA with [Temporal Envelope](https://docs.victoriametrics.com/anomaly-detection/components/models/#temporal-envelope) {{% available_from "v1.30.0" anomaly %}}; for older releases, use another supported seasonal model in the `models` section of the configuration.
|
||||
|
||||
- [v1.9.0](https://docs.victoriametrics.com/anomaly-detection/changelog/#v190) The `sampling_period` parameter is now mandatory in `VmReader`. This change aims to clarify and standardize the frequency of input/output in `vmanomaly`, thereby reducing uncertainty and aligning with user expectations; Action: Add the `sampling_period` parameter to your `VmReader` configuration, e.g.:
|
||||
|
||||
|
||||
@@ -126,13 +126,18 @@ groups:
|
||||
> docker pull quay.io/victoriametrics/vmanomaly:vX.Y.Z
|
||||
> ```
|
||||
|
||||
> [!NOTE] ARM64 startup on affected Apple Silicon virtualization
|
||||
> On some `linux/arm64` environments running through virtualization on Apple M4/M5 hosts, `vmanomaly` may exit with `SIGILL` (exit code `132`) before startup. This is caused by the virtualized host advertising an SVE2 capability that traps when used by OpenSSL 4.x; it does not affect all ARM64 systems.
|
||||
>
|
||||
> On affected hosts, add `-e OPENSSL_armcap=0` to `docker run`, or add `- OPENSSL_armcap=0` under the service's Docker Compose `environment`, matching the list syntax used below. This disables ARM cryptographic acceleration, so apply it only as a temporary workaround on affected hosts.
|
||||
|
||||
|
||||
Below are the steps to get `vmanomaly` up and running inside a Docker container:
|
||||
|
||||
1. Pull Docker image:
|
||||
|
||||
```sh
|
||||
docker pull victoriametrics/vmanomaly:v1.30.0
|
||||
docker pull victoriametrics/vmanomaly:v1.30.1
|
||||
```
|
||||
|
||||
2. Create the license file with your license key.
|
||||
@@ -152,7 +157,7 @@ docker run -it \
|
||||
-v ./license:/license \
|
||||
-v ./config.yaml:/config.yaml \
|
||||
-p 8490:8490 \
|
||||
victoriametrics/vmanomaly:v1.30.0 \
|
||||
victoriametrics/vmanomaly:v1.30.1 \
|
||||
/config.yaml \
|
||||
--licenseFile=/license \
|
||||
--loggerLevel=INFO \
|
||||
@@ -169,7 +174,7 @@ docker run -it \
|
||||
-e VMANOMALY_DATA_DUMPS_DIR=/tmp/vmanomaly/data \
|
||||
-e VMANOMALY_MODEL_DUMPS_DIR=/tmp/vmanomaly/models \
|
||||
-p 8490:8490 \
|
||||
victoriametrics/vmanomaly:v1.30.0 \
|
||||
victoriametrics/vmanomaly:v1.30.1 \
|
||||
/config.yaml \
|
||||
--licenseFile=/license \
|
||||
--loggerLevel=INFO \
|
||||
@@ -182,7 +187,7 @@ services:
|
||||
# ...
|
||||
vmanomaly:
|
||||
container_name: vmanomaly
|
||||
image: victoriametrics/vmanomaly:v1.30.0
|
||||
image: victoriametrics/vmanomaly:v1.30.1
|
||||
# ...
|
||||
restart: always
|
||||
volumes:
|
||||
|
||||
@@ -193,7 +193,7 @@ The best applications of this mode are:
|
||||
|
||||
### What you can do with Copilot
|
||||
|
||||
- **Ask questions** about any model (e.g. [Temporal Envelope](https://docs.victoriametrics.com/anomaly-detection/components/models/#temporal-envelope), [Prophet](https://docs.victoriametrics.com/anomaly-detection/components/models/#prophet), or [Z-score](https://docs.victoriametrics.com/anomaly-detection/components/models/#online-z-score) - parameters, trade-offs, when to use each)
|
||||
- **Ask questions** about any model (e.g. [Temporal Envelope](https://docs.victoriametrics.com/anomaly-detection/components/models/#temporal-envelope), [Online Seasonal Quantile](https://docs.victoriametrics.com/anomaly-detection/components/models/#online-seasonal-quantile), or [Online Z-score](https://docs.victoriametrics.com/anomaly-detection/components/models/#online-z-score) - parameters, trade-offs, when to use each)
|
||||
- **Improve detection quality** - describe what's wrong ("too many false positives", "missing spikes") and Copilot reads the config, searches the docs, and proposes a validated configuration change to fix the issue.
|
||||
- **Get config suggestions inline** - suggestions appear as interactive cards with an explanation and a YAML diff; click **Apply** to write the change directly to your current settings, or **Decline** to keep the conversation going.
|
||||
- {{% available_from "v1.30.0" anomaly %}} **Profile and tune the real query** - with [mcp-vmanomaly](#mcp-tools-server) connected, Copilot can inspect bounded time-series characteristics, recommend an online model, start an asynchronous autotune task, and apply its validated query and model suggestions.
|
||||
@@ -316,7 +316,7 @@ docker run -it --rm \
|
||||
-e VMANOMALY_MCP_SERVER_URL=http://mcp-vmanomaly:8081/mcp \
|
||||
-p 8080:8080 \
|
||||
-p 8490:8490 \
|
||||
victoriametrics/vmanomaly:v1.30.0 \
|
||||
victoriametrics/vmanomaly:v1.30.1 \
|
||||
vmanomaly_config.yaml
|
||||
```
|
||||
|
||||
@@ -569,7 +569,7 @@ Set up the time range and resolution (step) for data visualization and anomaly d
|
||||
|
||||

|
||||
|
||||
Pay attention to trends, seasonality, noise, outliers, and other patterns in the data, which can influence the choice of anomaly detection model and its hyperparameters (e.g. use seasonal models for seasonal data - like `Prophet`, robust models for noisy de-seasonalized data - like `MAD`, etc.).
|
||||
Pay attention to trends, seasonality, noise, outliers, and other patterns in the data, which can influence the choice of anomaly detection model and its hyperparameters. Use [Temporal Envelope](https://docs.victoriametrics.com/anomaly-detection/components/models/#temporal-envelope) for complex data with trend or calendar patterns, and [Online MAD](https://docs.victoriametrics.com/anomaly-detection/components/models/#online-mad) for simple, mostly stationary data where robustness to outliers matters.
|
||||
|
||||

|
||||
|
||||
@@ -645,6 +645,19 @@ If the **results** look good and the **model configuration should be deployed in
|
||||
|
||||
{{% collapse name="Release history" %}}
|
||||
|
||||
### v1.8.1
|
||||
Released: 2026-08-06
|
||||
|
||||
vmanomaly version: [v1.30.1](https://docs.victoriametrics.com/anomaly-detection/changelog/#v1301)
|
||||
|
||||
- IMPROVEMENT: Model settings are validated and normalized when applied. Invalid drafts remain open with actionable feedback, and advanced-setting summaries open the corresponding editor directly.
|
||||
|
||||
- BUGFIX: Server-query counts load when the query drawer opens, and numeric model fields preserve valid scalar and range values while reporting parsing errors on blur.
|
||||
|
||||
- BUGFIX: The anomaly visualization empty state now follows the active theme instead of using light-theme colors in dark mode.
|
||||
|
||||
- BUGFIX: Tenant selection now follows the datasource URL resolved by the server, avoiding an incorrect switch to tenant `0` when it is unavailable.
|
||||
|
||||
### v1.8.0
|
||||
Released: 2026-07-23
|
||||
|
||||
|
||||
@@ -54,11 +54,11 @@ schedulers:
|
||||
fit_window: "3d" # how much historical data to use for fit stage
|
||||
start_from: "00:00" # align the annual fit schedule to midnight in the configured timezone
|
||||
tz: "Europe/Kyiv" # timezone to use for start_from
|
||||
periodic_offline_1w:
|
||||
periodic_online_weekly:
|
||||
class: 'periodic'
|
||||
infer_every: "15m"
|
||||
scatter_infer_jobs: true
|
||||
fit_every: "24h"
|
||||
fit_every: "365d" # online state continues adapting between infrequent full re-fits
|
||||
fit_window: "14d"
|
||||
# if no start_from is specified, jobs will start immediately after service starts
|
||||
|
||||
@@ -75,18 +75,16 @@ models:
|
||||
min_dev_from_expected: 0.0 # turned off. if |y - yhat| < min_dev_from_expected, anomaly score will be 0
|
||||
detection_direction: 'above_expected' # detect anomalies only when y > yhat, "peaks"
|
||||
clip_predictions: True # clip predictions to expected data range, i.e. [0, inf] for this query `host_network_receive_errors
|
||||
prophet_weekly: # we can set up alias for model
|
||||
class: 'prophet'
|
||||
envelope_weekly: # we can set up alias for model
|
||||
class: 'temporal_envelope'
|
||||
provide_series: ['anomaly_score', 'y', 'yhat', 'yhat_lower', 'yhat_upper']
|
||||
queries: ['cpu_seconds_total']
|
||||
schedulers: ['periodic_offline_1w'] # will be attached to 1-week scheduler, re-fit every 24h and infer every 15m
|
||||
schedulers: ['periodic_online_weekly'] # fit on two weekly cycles, then update online every 15m
|
||||
min_dev_from_expected: [0.01, 0.01] # minimum deviation from expected value to be even considered as anomaly
|
||||
anomaly_score_outside_data_range: 1.5 # override default anomaly score outside expected data range
|
||||
detection_direction: 'above_expected'
|
||||
clip_predictions: True # clip predictions to expected data range, i.e. [0, inf] for this query `cpu_seconds_total`
|
||||
args: # model-specific arguments
|
||||
interval_width: 0.98
|
||||
yearly_seasonality: False # disable yearly seasonality, since we have only 7 days of data
|
||||
seasonalities: ['hod_smooth', 'dow_smooth']
|
||||
|
||||
# where to read data from
|
||||
# https://docs.victoriametrics.com/anomaly-detection/components/reader/#vm-reader
|
||||
@@ -113,7 +111,7 @@ reader:
|
||||
# https://docs.victoriametrics.com/anomaly-detection/components/writer/
|
||||
writer:
|
||||
datasource_url: "http://victoriametrics:8428/"
|
||||
# tenant_id: "0:0" # for VictoriaMetrics cluster, can support "multitenant"
|
||||
tenant_id: "0:0" # for VictoriaMetrics cluster, can support "multitenant"
|
||||
# https://docs.victoriametrics.com/anomaly-detection/components/writer/#metrics-formatting
|
||||
metric_format:
|
||||
__name__: $VAR
|
||||
@@ -204,6 +202,7 @@ models:
|
||||
|
||||
writer:
|
||||
datasource_url: "http://victoriametrics:8428/"
|
||||
tenant_id: "0:0"
|
||||
|
||||
monitoring:
|
||||
push:
|
||||
|
||||
@@ -27,16 +27,13 @@ This section covers the `Models` component of VictoriaMetrics Anomaly Detection
|
||||
```yaml
|
||||
models:
|
||||
model_univariate_1:
|
||||
class: 'zscore' # or 'model.zscore.ZscoreModel' until v1.13.0
|
||||
class: 'zscore_online'
|
||||
z_threshold: 2.5
|
||||
queries: ['query_alias2'] # referencing queries defined in `reader` section
|
||||
model_multivariate_1:
|
||||
class: 'isolation_forest_multivariate' # or model.isolation_forest.IsolationForestMultivariateModel until v1.13.0
|
||||
contamination: 'auto'
|
||||
args:
|
||||
n_estimators: 100
|
||||
# i.e. to assure reproducibility of produced results each time model is fit on the same input
|
||||
random_state: 42
|
||||
class: 'temporal_envelope_multivariate'
|
||||
seasonalities: ['hod_smooth', 'dow_smooth']
|
||||
provide_series: ['anomaly_score']
|
||||
# if there is no explicit `queries` arg, then the model will be run on ALL queries found in reader section
|
||||
# ...
|
||||
```
|
||||
@@ -334,9 +331,10 @@ reader:
|
||||
+ sum(rate(node_network_transmit_bytes_total[5m])) by (host)
|
||||
|
||||
models:
|
||||
iforest: # alias for the model
|
||||
class: isolation_forest_multivariate
|
||||
contamination: 0.01
|
||||
envelope: # alias for the model
|
||||
class: temporal_envelope_multivariate
|
||||
seasonalities: [hod_smooth, dow_smooth]
|
||||
provide_series: [anomaly_score]
|
||||
# the multivariate model can be trained on 2+ timeseries returned by 1+ queries
|
||||
queries: [cpu, ram, network]
|
||||
# train a distinct multivariate model for each unique value found in the `host` label
|
||||
@@ -548,7 +546,7 @@ If during an inference, you got a series having **new labelset** (not present in
|
||||
|
||||
**Implications:** Univariate models are a go-to default, when your queries returns **changing** amount of **individual** time series of **different** magnitude, [trend](https://victoriametrics.com/blog/victoriametrics-anomaly-detection-handbook-chapter-1/#trend) or [seasonality](https://victoriametrics.com/blog/victoriametrics-anomaly-detection-handbook-chapter-1/#seasonality), so you won't be mixing incompatible data with different behavior within a single fit model (context isolation).
|
||||
|
||||
**Examples:** [Prophet](#prophet), [Holt-Winters](#holt-winters)
|
||||
**Examples:** [Temporal Envelope](#temporal-envelope), [Online MAD](#online-mad), [Online Z-score](#online-z-score), [Online Seasonal Quantile](#online-seasonal-quantile)
|
||||
|
||||

|
||||
|
||||
@@ -565,11 +563,11 @@ If during an inference, you got a **different amount of series** or some series
|
||||
|
||||
**Implications:** Multivariate models are a go-to default, when your queries returns **fixed** amount of **individual** time series (say, some aggregations), to be used for adding cross-series (and cross-query) context, useful for catching [collective anomalies](https://victoriametrics.com/blog/victoriametrics-anomaly-detection-handbook-chapter-2/#collective-anomalies) or [novelties](https://victoriametrics.com/blog/victoriametrics-anomaly-detection-handbook-chapter-2/#novelties) (expanded to multi-input scenario). For example, you may set it up for anomaly detection of CPU usage in different modes (`idle`, `user`, `system`, etc.) and use its cross-dependencies to detect **unseen (in fit data)** behavior.
|
||||
|
||||
**Examples:** [Temporal Envelope](#temporal-envelope), [Isolation Forest](#isolation-forest-multivariate)
|
||||
**Recommended:** [Temporal Envelope](#temporal-envelope). Existing [Isolation Forest](#isolation-forest-multivariate) configurations can migrate to its multivariate form.
|
||||
|
||||

|
||||
|
||||
The following configuration applies both models to the same aligned input series. Start with Temporal Envelope when temporal profiles and online adaptation matter; use Isolation Forest as an offline alternative when feature-space outliers are the primary concern.
|
||||
The following configuration applies a multivariate Temporal Envelope model to the same aligned input series:
|
||||
|
||||
```yaml
|
||||
models:
|
||||
@@ -582,16 +580,6 @@ models:
|
||||
seasonalities: [hod_smooth, dow_smooth]
|
||||
provide_series: [anomaly_score]
|
||||
|
||||
service_dependency_isolation_forest:
|
||||
class: isolation_forest_multivariate
|
||||
queries: [request_rate, error_rate, latency]
|
||||
groupby: [cluster]
|
||||
contamination: 0.01
|
||||
seasonal_features: [hod, dow]
|
||||
args:
|
||||
n_estimators: 100
|
||||
random_state: 42
|
||||
provide_series: [anomaly_score]
|
||||
```
|
||||
|
||||
|
||||
@@ -634,6 +622,9 @@ Each of the ([built-in](#built-in-models) or [custom](#custom-model-guide)) onli
|
||||
|
||||
Every other model that isn't [online](#online-models). Offline models are completely re-trained during `fit` call and aren't updated during consecutive `infer` calls.
|
||||
|
||||
> [!NOTE]
|
||||
> Built-in offline model classes are planned for deprecation in a future release in favor of online counterparts. For complex temporal data, prefer [Temporal Envelope](#temporal-envelope), which supports incremental adaptation, forecasting, and both univariate and multivariate operation.
|
||||
|
||||
|
||||
## Built-in Models
|
||||
|
||||
@@ -649,14 +640,14 @@ Built-in models support 2 groups of arguments:
|
||||
**Models**:
|
||||
- [AutoTuned](#autotuned) - designed to take the cognitive load off the user, allowing any of built-in models below to be re-tuned for best hyperparameters on data seen during each `fit` phase of the algorithm. Tradeoff is between increased computational time and optimized results / simpler maintenance.
|
||||
- [Temporal Envelope](#temporal-envelope) - the preferred **online model for complex operational data** with trends, changepoints, multiple calendar patterns, holidays, capable of [forecasting](https://docs.victoriametrics.com/anomaly-detection/faq/#forecasting). Its multivariate form also learns cross-series relationships.
|
||||
- [Prophet](#prophet) - an offline forecasting alternative when Prophet-specific decomposition outputs are required. Favor `Temporal Envelope` for online adaptation and multivariate support.
|
||||
- [Online Z-score](#online-z-score) - useful for initial testing and for simpler data ([de-trended](https://victoriametrics.com/blog/victoriametrics-anomaly-detection-handbook-chapter-1/#trend) data without strict [seasonality](https://victoriametrics.com/blog/victoriametrics-anomaly-detection-handbook-chapter-1/#seasonality) and with anomalies of similar magnitude as your "normal" data)
|
||||
- [MAD](#online-mad) - similarly to [Z-score](#online-z-score), is effective for **identifying outliers in relatively consistent data**. Useful for detecting sudden, stark deviations from the median, being less prone to outlier's magnitude than z-score.
|
||||
- [Rolling Quantile](#rolling-quantile) - best for **data with evolving patterns**, as it adapts to changes over a rolling window.
|
||||
- [Online Seasonal Quantile](#online-seasonal-quantile) - best used on **[de-trended](https://victoriametrics.com/blog/victoriametrics-anomaly-detection-handbook-chapter-1/#trend) data with strong (possibly multiple) [seasonalities](https://victoriametrics.com/blog/victoriametrics-anomaly-detection-handbook-chapter-1/#seasonality)**. Can act as a (slightly less powerful) [online](#online-models) replacement to [`ProphetModel`](#prophet).
|
||||
- [Seasonal Trend Decomposition](#seasonal-trend-decomposition) - similarly to Holt-Winters, is best for **data with pronounced [seasonal](https://victoriametrics.com/blog/victoriametrics-anomaly-detection-handbook-chapter-1/#seasonality) and [trend](https://victoriametrics.com/blog/victoriametrics-anomaly-detection-handbook-chapter-1/#trend) components**
|
||||
- [Isolation forest (Multivariate)](#isolation-forest-multivariate) - an offline alternative for **metrics data interaction** (several queries/metrics -> single anomaly score) and high-dimensional feature-space outliers. Prefer multivariate Temporal Envelope when temporal profiles and *online* adaptation matter.
|
||||
- [Holt-Winters](#holt-winters) - well-suited for **data with moderate complexity**, exhibiting distinct [trends](https://victoriametrics.com/blog/victoriametrics-anomaly-detection-handbook-chapter-1/#trend) and/or [single seasonal pattern](https://victoriametrics.com/blog/victoriametrics-anomaly-detection-handbook-chapter-1/#seasonality).
|
||||
- [Prophet](#prophet) - an offline model retained for existing deployments. Migrate forecasting and seasonal anomaly-detection configurations to [Temporal Envelope](#temporal-envelope), unless Prophet-specific decomposition output must be preserved.
|
||||
- [Isolation forest (Multivariate)](#isolation-forest-multivariate) - an offline model retained for existing univariate and multivariate deployments. Migrate to the corresponding [Temporal Envelope](#temporal-envelope) form for online adaptation and temporal or cross-series context.
|
||||
- [Holt-Winters](#holt-winters) - an offline model retained for existing trend and single-seasonality configurations. Migrate these configurations to [Temporal Envelope](#temporal-envelope).
|
||||
- [Custom model](#custom-model-guide) - benefit from your own models and expertise to better support your **unique use case**.
|
||||
|
||||
|
||||
@@ -785,6 +776,8 @@ The requested anomaly percentage is treated as an alert-volume constraint rather
|
||||
|
||||
{{% available_from "v1.30.0" anomaly %}} Temporal Envelope is the preferred online model for complex operational and business metrics. It learns an evolving expected range from robust trend, calendar and holiday patterns, persistent level shifts, uncertainty, and optional future forecasts. The model adapts during inference while limiting the lasting influence of short-lived spikes.
|
||||
|
||||
{{% available_from "v1.30.1" anomaly %}} When the fit window ends in a recently established level, the model initializes its adaptive state from that recent regime while preserving supported calendar structure. This improves the first periodic predictions after a level shift and reduces false seasonal oscillation without requiring additional configuration.
|
||||
|
||||
> `TemporalEnvelopeModel` is [univariate](#univariate-models) and [online](#online-models). `TemporalEnvelopeMultivariateModel` also learns normal cross-series relationships as a [multivariate](#multivariate-models) model.
|
||||
|
||||
Use it for:
|
||||
@@ -793,7 +786,7 @@ Use it for:
|
||||
- deployments, traffic migrations, and capacity changes that create persistent shifts, including short-horizon forecasts through `forecast_at`;
|
||||
- aligned related metrics where each channel keeps its own temporal pattern while their joint behavior contributes to one anomaly score.
|
||||
|
||||
For simple profiles without strong trend or seasonality, prefer [Online MAD](#online-mad) or [Online Z-score](#online-z-score). [Prophet](#prophet) and [Isolation Forest](#isolation-forest-multivariate) remain offline alternatives when their distinct capabilities are required or validation favors them.
|
||||
For simple profiles without strong trend or seasonality, prefer [Online MAD](#online-mad) or [Online Z-score](#online-z-score). Existing [Prophet](#prophet) and [Isolation Forest](#isolation-forest-multivariate) configurations can be migrated to the corresponding univariate or multivariate Temporal Envelope form.
|
||||
|
||||
<div class="model-details">
|
||||
|
||||
@@ -873,11 +866,224 @@ For independent per-series detection, use `temporal_envelope`. Use `temporal_env
|
||||
|
||||
</div>
|
||||
|
||||
### Online MAD
|
||||
|
||||
> `OnlineMADModel` is a [univariate](#univariate-models), [online](#online-models) model.
|
||||
|
||||
The MAD model is a robust method for anomaly detection that is *less sensitive* to outliers in data compared to standard deviation-based models. It considers a point as an anomaly if the absolute deviation from the median is significantly large. This is the online approximate version, based on [t-digests](https://www.sciencedirect.com/science/article/pii/S2665963820300403) for online quantile estimation{{% available_from "v1.15.0" anomaly %}}.
|
||||
|
||||
<div class="model-details">
|
||||
|
||||
{{% collapse name="Model-specific arguments" %}}
|
||||
|
||||
- `class` (string) - model class name `"model.online.OnlineMADModel"` (or `mad_online` with class alias support{{% available_from "v1.13.0" anomaly %}})
|
||||
- `threshold` (float, optional) - The threshold multiplier for the MAD to determine anomalies. Defaults to `2.5`. Higher values will identify fewer points as anomalies.
|
||||
- `min_n_samples_seen` (int, optional) - the minimum number of samples to be seen (`n_samples_seen_` property) before computing the anomaly score. Otherwise, the **anomaly score will be 0**, as there is not enough data to trust the model's predictions. Defaults to 16.
|
||||
- `history_strength` (float, optional) - {{% available_from "v1.30.0" anomaly %}} strength of the initial history learned by `fit`. Values above `1` preserve fitted quantiles initially but reduce the leverage of subsequent updates. Defaults to `1`.
|
||||
- `compression` (int, optional) - the compression parameter for underlying [t-digest](https://www.sciencedirect.com/science/article/pii/S2665963820300403). Higher values mean higher accuracy but higher memory usage. By default 100.
|
||||
|
||||
{{% /collapse %}}
|
||||
|
||||
{{% collapse name="Configuration example" %}}
|
||||
|
||||
|
||||
```yaml
|
||||
models:
|
||||
your_desired_alias_for_a_model:
|
||||
class: "mad_online" # or 'model.online.OnlineMADModel'
|
||||
threshold: 2.5
|
||||
min_n_samples_seen: 128 # i.e. calculate it as full seasonality / data freq
|
||||
history_strength: 2 # retain fitted history as a stronger prior
|
||||
compression: 100 # higher values mean higher accuracy but higher memory usage
|
||||
provide_series: ['anomaly_score', 'yhat'] # common arg example
|
||||
# Common arguments for built-in model, if not set, default to
|
||||
# See https://docs.victoriametrics.com/anomaly-detection/components/models/#common-args
|
||||
#
|
||||
# provide_series: ['anomaly_score', 'yhat', 'yhat_lower', 'yhat_upper']
|
||||
# schedulers: [all scheduler aliases defined in `scheduler` section]
|
||||
# queries: [all query aliases defined in `reader.queries` section]
|
||||
# detection_direction: 'both' # meaning both drops and spikes will be captured
|
||||
# min_dev_from_expected: [0.0, 0.0] # meaning, no minimal threshold is applied to prevent smaller anomalies
|
||||
# scale: [1.0, 1.0] # if needed, prediction intervals' width can be increased (>1) or narrowed (<1)
|
||||
# clip_predictions: False # if data_range for respective `queries` is set in reader, `yhat.*` columns will be clipped
|
||||
# anomaly_score_outside_data_range: 1.01 # auto anomaly score (1.01) if `y` (real value) is outside of data_range, if set
|
||||
```
|
||||
|
||||
{{% /collapse %}}
|
||||
|
||||
</div>
|
||||
|
||||
Resulting metrics of the model are described [here](#vmanomaly-output).
|
||||
|
||||
|
||||
### Online Seasonal Quantile
|
||||
|
||||
> `OnlineQuantileModel` is a [univariate](#univariate-models), [online](#online-models) model.
|
||||
|
||||
Online (seasonal) quantile utilizes a set of approximate distributions, based on [t-digests](https://www.sciencedirect.com/science/article/pii/S2665963820300403) for online quantile estimation {{% available_from "v1.15.0" anomaly %}}.
|
||||
|
||||
Best used on **[de-trended](https://victoriametrics.com/blog/victoriametrics-anomaly-detection-handbook-chapter-1/#trend) data with strong (potentially multiple) [seasonalities](https://victoriametrics.com/blog/victoriametrics-anomaly-detection-handbook-chapter-1/#seasonality)**. Can act as a (slightly less flexible) replacement to [`ProphetModel`](#prophet).
|
||||
|
||||
It uses the `quantiles` triplet to calculate `yhat_lower`, `yhat`, and `yhat_upper` [output](#vmanomaly-output), respectively, for each of the `min_subseason` sub-intervals contained in `seasonal_interval`. For example, with '4d' + '2h' seasonality patterns (multiple), it will hold and update 24*4 / 2 = 48 consecutive estimates (each 2 hours long).
|
||||
|
||||
<div class="model-details">
|
||||
|
||||
{{% collapse name="Model-specific arguments" %}}
|
||||
|
||||
- `class` (string) - model class name `"model.online.OnlineQuantileModel"` (or `quantile_online` with class alias support{{% available_from "v1.13.0" anomaly %}})
|
||||
- `quantiles` (list[float], optional) - The quantiles to estimate. `yhat_lower`, `yhat`, `yhat_upper` are the quantile order. By default (0.01, 0.5, 0.99).
|
||||
- `iqr_threshold` (float, optional) - {{% available_from "v1.25.0" anomaly %}} The [interquartile range (IQR)](https://en.wikipedia.org/wiki/Interquartile_range) multiplier to increase the width of the prediction intervals. Defaults to 0 (no adjustment) for backward compatibility. If set > 0, the model will add IQR * `iqr_threshold` to `yhat_lower` and `yhat_upper` (respecting `min_subseason` seasonal buckets). This is useful for data with high variance or outliers, as it helps to avoid false positives in anomaly detection. Best used with **robust** `quantiles` set to (0.25, 0.5, 0.75) or similar.
|
||||
- `seasonal_interval` (string, optional) - the interval for the seasonal adjustment. If not set, the model will equal to a simple online quantile model. By default not set.
|
||||
- `min_subseason` (str, optional) - the minimum interval to estimate quantiles for. By default not set. Note that the minimum interval should be a multiple of the seasonal interval, i.e. if seasonal_interval='2h', then min_subseason='15m' is valid, but '37m' is not.
|
||||
- `use_transform` (bool, optional) - whether to internally apply a `log1p(abs(x)) * sign(x)` transformation to the data to stabilize internal quantile estimation. Does not affect the scale of produced output (i.e. `yhat`) By default False.
|
||||
- `global_smoothing` (float, optional) - the smoothing parameter for the global quantiles. i.e. the output is a weighted average of the global and seasonal quantiles (if `seasonal_interval` and `min_subseason` args are set). Should be from `[0, 1]` interval, where 0 means no smoothing and 1 means using only global quantile values.
|
||||
- `scale` (float, optional) - Is used to adjust the margins between `yhat` and [`yhat_lower`, `yhat_upper`]. New margin = `|yhat_* - yhat_lower| * scale`. Defaults to 1 (no scaling is applied). See `scale`[common arg](https://docs.victoriametrics.com/anomaly-detection/components/models/#scale) section for detailed instructions and 2-sided option.
|
||||
- `season_starts_from` (str, optional) - the start date for the seasonal adjustment, as a reference point to start counting the intervals. By default '1970-01-01'.
|
||||
- `min_n_samples_seen` (int, optional) - the minimum number of samples to be seen (`n_samples_seen_` property) before computing the anomaly score. Otherwise, the **anomaly score will be 0**, as there is not enough data to trust the model's predictions. Defaults to 16.
|
||||
- `history_strength` (float, optional) - {{% available_from "v1.30.0" anomaly %}} strength of the initial history learned by `fit`. Values above `1` preserve fitted quantiles initially but reduce the leverage of subsequent updates. Defaults to `1`.
|
||||
- `compression` (int, optional) - the compression parameter for the underlying [t-digests](https://www.sciencedirect.com/science/article/pii/S2665963820300403). Higher values mean higher accuracy but higher memory usage. By default 100.
|
||||
|
||||
{{% /collapse %}}
|
||||
|
||||
{{% collapse name="Configuration example" %}}
|
||||
|
||||
Suppose we have a data with strong intra-day (hourly) and intra-week (daily) seasonality, data granularity is '5m' with up to 5% expected outliers present in data. Then you can apply similar config:
|
||||
|
||||
```yaml
|
||||
models:
|
||||
your_desired_alias_for_a_model:
|
||||
class: "quantile_online" # or 'model.online.OnlineQuantileModel'
|
||||
quantiles: [0.25, 0.5, 0.75] # lowered to exclude anomalous edges, can be compensated by `scale` param > 1 and `iqr_threshold` > 0
|
||||
iqr_threshold: 2.5 # to increase prediction intervals' width to avoid false positives while still keeping the model robust
|
||||
seasonal_interval: '7d' # longest seasonality (week, day) = week, starting from `season_starts_from`
|
||||
min_subseason: '1h' # smallest seasonality (week, day, hour) = hour, will have its own quantile estimates
|
||||
min_n_samples_seen: 288 # 1440 / 5 - at least 1 full day, ideal = 1440 / 5 * 7 - one full week (seasonal_interval)
|
||||
history_strength: 2 # retain fitted history as a stronger prior
|
||||
scale: 1.1 # to compensate lowered quantile boundaries with wider intervals
|
||||
season_starts_from: '2024-01-01' # interval calculation starting point, especially for uncommon seasonalities like '36h' or '12d'
|
||||
compression: 100 # higher values mean higher accuracy but higher memory usage
|
||||
provide_series: ['anomaly_score', 'yhat'] # common arg example
|
||||
# Common arguments for built-in model, if not set, default to
|
||||
# See https://docs.victoriametrics.com/anomaly-detection/components/models/#common-args
|
||||
#
|
||||
# provide_series: ['anomaly_score', 'yhat', 'yhat_lower', 'yhat_upper']
|
||||
# schedulers: [all scheduler aliases defined in `scheduler` section]
|
||||
# queries: [all query aliases defined in `reader.queries` section]
|
||||
# detection_direction: 'both' # meaning both drops and spikes will be captured
|
||||
# min_dev_from_expected: [0.0, 0.0] # meaning, no minimal threshold is applied to prevent smaller anomalies
|
||||
# scale: [1.0, 1.0] # if needed, prediction intervals' width can be increased (>1) or narrowed (<1)
|
||||
# clip_predictions: False # if data_range for respective `queries` is set in reader, `yhat.*` columns will be clipped
|
||||
# anomaly_score_outside_data_range: 1.01 # auto anomaly score (1.01) if `y` (real value) is outside of data_range, if set
|
||||
```
|
||||
|
||||
{{% /collapse %}}
|
||||
|
||||
</div>
|
||||
|
||||
Resulting metrics of the model are described [here](#vmanomaly-output).
|
||||
|
||||
|
||||
### Online Z-score
|
||||
|
||||
> `OnlineZscoreModel` is a [univariate](#univariate-models), [online](#online-models) model.
|
||||
|
||||
Online version of existing [Z-score](#z-score) implementation with the same exact behavior and implications {{% available_from "v1.15.0" anomaly %}}.
|
||||
|
||||
<div class="model-details">
|
||||
|
||||
{{% collapse name="Model-specific arguments" %}}
|
||||
|
||||
- `class` (string) - model class name `"model.online.OnlineZscoreModel"` (or `zscore_online`with class alias support{{% available_from "v1.13.0" anomaly %}})
|
||||
- `z_threshold` (float, optional) - [standard score](https://en.wikipedia.org/wiki/Standard_score) for calculation boundaries and anomaly score. Defaults to `2.5`.
|
||||
- `min_n_samples_seen` (int, optional) - the minimum number of samples to be seen (`n_samples_seen_` property) before computing the anomaly score. Otherwise, the **anomaly score will be 0**, as there is not enough data to trust the model's predictions. Defaults to 16.
|
||||
- `history_strength` (float, optional) - {{% available_from "v1.30.0" anomaly %}} strength of the initial history learned by `fit`. Values above `1` keep fitted mean and variance unchanged initially but reduce the leverage of subsequent updates. Defaults to `1`.
|
||||
|
||||
{{% /collapse %}}
|
||||
|
||||
{{% collapse name="Configuration example" %}}
|
||||
|
||||
```yaml
|
||||
models:
|
||||
your_desired_alias_for_a_model:
|
||||
class: "zscore_online" # or 'model.online.OnlineZscoreModel'
|
||||
z_threshold: 3.5
|
||||
min_n_samples_seen: 128 # i.e. calculate it as full seasonality / data freq
|
||||
history_strength: 2 # retain fitted history as a stronger prior
|
||||
provide_series: ['anomaly_score', 'yhat'] # common arg example
|
||||
# Common arguments for built-in model, if not set, default to
|
||||
# See https://docs.victoriametrics.com/anomaly-detection/components/models/#common-args
|
||||
#
|
||||
# provide_series: ['anomaly_score', 'yhat', 'yhat_lower', 'yhat_upper']
|
||||
# schedulers: [all scheduler aliases defined in `scheduler` section]
|
||||
# queries: [all query aliases defined in `reader.queries` section]
|
||||
# detection_direction: 'both' # meaning both drops and spikes will be captured
|
||||
# min_dev_from_expected: [0.0, 0.0] # meaning, no minimal threshold is applied to prevent smaller anomalies
|
||||
# scale: [1.0, 1.0] # if needed, prediction intervals' width can be increased (>1) or narrowed (<1)
|
||||
# clip_predictions: False # if data_range for respective `queries` is set in reader, `yhat.*` columns will be clipped
|
||||
# anomaly_score_outside_data_range: 1.01 # auto anomaly score (1.01) if `y` (real value) is outside of data_range, if set
|
||||
```
|
||||
|
||||
{{% /collapse %}}
|
||||
|
||||
</div>
|
||||
|
||||
Resulting metrics of the model are described [here](#vmanomaly-output).
|
||||
|
||||
|
||||
### [Rolling Quantile](https://en.wikipedia.org/wiki/Quantile)
|
||||
|
||||
> `RollingQuantileModel` **is** {{% available_from "v1.28.0" anomaly %}} a [univariate](#univariate-models), [online](#online-models) model. It **was** {{% deprecated_from "v1.28.0" anomaly %}} a [univariate](#univariate-models), [rolling](#rolling-models), [offline](#offline-models) model.
|
||||
|
||||
This model is best used on **data with short evolving patterns** (i.e. 10-100 datapoints of particular frequency), as it adapts to changes over a rolling window.
|
||||
|
||||
<div class="model-details">
|
||||
|
||||
{{% collapse name="Model-specific arguments" %}}
|
||||
|
||||
- `class` (string) - model class name `"model.rolling_quantile.RollingQuantileModel"` (or `rolling_quantile` with class alias support {{% available_from "v1.13.0" anomaly %}})
|
||||
- `quantile` (float) - quantile value, from 0.5 to 1.0. This constraint is implied by 2-sided confidence interval.
|
||||
- `window_steps` (integer) - size of the moving window. (see 'sampling_period')
|
||||
- `iqr_threshold` (float, optional) - {{% available_from "v1.25.0" anomaly %}} The [interquartile range (IQR)](https://en.wikipedia.org/wiki/Interquartile_range) multiplier to increase the width of the prediction intervals. Defaults to 0 (no adjustment) for backward compatibility. If set > 0, the model will add half IQR * `iqr_threshold` to `yhat_lower` and `yhat_upper`. This is useful for data with high variance or outliers, as it helps to avoid false positives in anomaly detection.
|
||||
|
||||
{{% /collapse %}}
|
||||
|
||||
{{% collapse name="Configuration example" %}}
|
||||
|
||||
```yaml
|
||||
models:
|
||||
your_desired_alias_for_a_model:
|
||||
class: "rolling_quantile"
|
||||
quantile: 0.9
|
||||
window_steps: 96
|
||||
iqr_threshold: 1
|
||||
# Common arguments for built-in model, if not set, default to
|
||||
# See https://docs.victoriametrics.com/anomaly-detection/components/models/#common-args
|
||||
#
|
||||
# provide_series: ['anomaly_score', 'yhat', 'yhat_lower', 'yhat_upper']
|
||||
# schedulers: [all scheduler aliases defined in `scheduler` section]
|
||||
# queries: [all query aliases defined in `reader.queries` section]
|
||||
# detection_direction: 'both' # meaning both drops and spikes will be captured
|
||||
# min_dev_from_expected: [0.0, 0.0] # meaning, no minimal threshold is applied to prevent smaller anomalies
|
||||
# scale: [1.0, 1.0] # if needed, prediction intervals' width can be increased (>1) or narrowed (<1)
|
||||
# clip_predictions: False # if data_range for respective `queries` is set in reader, `yhat.*` columns will be clipped
|
||||
# anomaly_score_outside_data_range: 1.01 # auto anomaly score (1.01) if `y` (real value) is outside of data_range, if set
|
||||
```
|
||||
|
||||
{{% /collapse %}}
|
||||
|
||||
</div>
|
||||
|
||||
Resulting metrics of the model are described [here](#vmanomaly-output).
|
||||
|
||||
|
||||
### [Prophet](https://facebook.github.io/prophet/)
|
||||
`vmanomaly` uses the Facebook Prophet implementation for time series forecasting, with detailed usage provided in the [Prophet library documentation](https://facebook.github.io/prophet/docs/quick_start#python-api). All original Prophet parameters are supported and can be directly passed to the model via `args` argument.
|
||||
|
||||
> `ProphetModel` is a [univariate](#univariate-models), [offline](#offline-models) model.
|
||||
|
||||
> [!NOTE]
|
||||
> Prophet is planned for deprecation in a future release. For new forecasting and anomaly-detection deployments, prefer the online [Temporal Envelope](#temporal-envelope) model unless Prophet-specific decomposition output is required.
|
||||
|
||||
> {{% available_from "v1.25.3" anomaly %}} Producing forecasts for future timestamps is now supported. To enable this, set the `forecast_at` argument to a list of relative future offsets (e.g., `['1h', '1d']`). The model will then generate forecasts for these future timestamps, which can be useful for planning and resource allocation. Output series are affected by [provide_series](#provide-series) argument, which need to include at least `yhat` for point-wise forecasts (and `yhat_lower` or/and `yhat_upper` for respective confidence intervals). See the example below for more details.
|
||||
|
||||
<div class="model-details">
|
||||
@@ -993,271 +1199,15 @@ Depending on chosen `seasonality` parameter FB Prophet can return additional met
|
||||
|
||||
Resulting metrics of the model are described [here](#vmanomaly-output)
|
||||
|
||||
### Online Z-score
|
||||
|
||||
> `OnlineZscoreModel` is a [univariate](#univariate-models), [online](#online-models) model.
|
||||
|
||||
Online version of existing [Z-score](#z-score) implementation with the same exact behavior and implications {{% available_from "v1.15.0" anomaly %}}.
|
||||
|
||||
<div class="model-details">
|
||||
|
||||
{{% collapse name="Model-specific arguments" %}}
|
||||
|
||||
- `class` (string) - model class name `"model.online.OnlineZscoreModel"` (or `zscore_online`with class alias support{{% available_from "v1.13.0" anomaly %}})
|
||||
- `z_threshold` (float, optional) - [standard score](https://en.wikipedia.org/wiki/Standard_score) for calculation boundaries and anomaly score. Defaults to `2.5`.
|
||||
- `min_n_samples_seen` (int, optional) - the minimum number of samples to be seen (`n_samples_seen_` property) before computing the anomaly score. Otherwise, the **anomaly score will be 0**, as there is not enough data to trust the model's predictions. Defaults to 16.
|
||||
- `history_strength` (float, optional) - {{% available_from "v1.30.0" anomaly %}} strength of the initial history learned by `fit`. Values above `1` keep fitted mean and variance unchanged initially but reduce the leverage of subsequent updates. Defaults to `1`.
|
||||
|
||||
{{% /collapse %}}
|
||||
|
||||
{{% collapse name="Configuration example" %}}
|
||||
|
||||
```yaml
|
||||
models:
|
||||
your_desired_alias_for_a_model:
|
||||
class: "zscore_online" # or 'model.online.OnlineZscoreModel'
|
||||
z_threshold: 3.5
|
||||
min_n_samples_seen: 128 # i.e. calculate it as full seasonality / data freq
|
||||
history_strength: 2 # retain fitted history as a stronger prior
|
||||
provide_series: ['anomaly_score', 'yhat'] # common arg example
|
||||
# Common arguments for built-in model, if not set, default to
|
||||
# See https://docs.victoriametrics.com/anomaly-detection/components/models/#common-args
|
||||
#
|
||||
# provide_series: ['anomaly_score', 'yhat', 'yhat_lower', 'yhat_upper']
|
||||
# schedulers: [all scheduler aliases defined in `scheduler` section]
|
||||
# queries: [all query aliases defined in `reader.queries` section]
|
||||
# detection_direction: 'both' # meaning both drops and spikes will be captured
|
||||
# min_dev_from_expected: [0.0, 0.0] # meaning, no minimal threshold is applied to prevent smaller anomalies
|
||||
# scale: [1.0, 1.0] # if needed, prediction intervals' width can be increased (>1) or narrowed (<1)
|
||||
# clip_predictions: False # if data_range for respective `queries` is set in reader, `yhat.*` columns will be clipped
|
||||
# anomaly_score_outside_data_range: 1.01 # auto anomaly score (1.01) if `y` (real value) is outside of data_range, if set
|
||||
```
|
||||
|
||||
{{% /collapse %}}
|
||||
|
||||
</div>
|
||||
|
||||
Resulting metrics of the model are described [here](#vmanomaly-output).
|
||||
|
||||
|
||||
### Online MAD
|
||||
|
||||
> `OnlineMADModel` is a [univariate](#univariate-models), [online](#online-models) model.
|
||||
|
||||
The MAD model is a robust method for anomaly detection that is *less sensitive* to outliers in data compared to standard deviation-based models. It considers a point as an anomaly if the absolute deviation from the median is significantly large. This is the online approximate version, based on [t-digests](https://www.sciencedirect.com/science/article/pii/S2665963820300403) for online quantile estimation{{% available_from "v1.15.0" anomaly %}}.
|
||||
|
||||
<div class="model-details">
|
||||
|
||||
{{% collapse name="Model-specific arguments" %}}
|
||||
|
||||
- `class` (string) - model class name `"model.online.OnlineMADModel"` (or `mad_online` with class alias support{{% available_from "v1.13.0" anomaly %}})
|
||||
- `threshold` (float, optional) - The threshold multiplier for the MAD to determine anomalies. Defaults to `2.5`. Higher values will identify fewer points as anomalies.
|
||||
- `min_n_samples_seen` (int, optional) - the minimum number of samples to be seen (`n_samples_seen_` property) before computing the anomaly score. Otherwise, the **anomaly score will be 0**, as there is not enough data to trust the model's predictions. Defaults to 16.
|
||||
- `history_strength` (float, optional) - {{% available_from "v1.30.0" anomaly %}} strength of the initial history learned by `fit`. Values above `1` preserve fitted quantiles initially but reduce the leverage of subsequent updates. Defaults to `1`.
|
||||
- `compression` (int, optional) - the compression parameter for underlying [t-digest](https://www.sciencedirect.com/science/article/pii/S2665963820300403). Higher values mean higher accuracy but higher memory usage. By default 100.
|
||||
|
||||
{{% /collapse %}}
|
||||
|
||||
{{% collapse name="Configuration example" %}}
|
||||
|
||||
|
||||
```yaml
|
||||
models:
|
||||
your_desired_alias_for_a_model:
|
||||
class: "mad_online" # or 'model.online.OnlineMADModel'
|
||||
threshold: 2.5
|
||||
min_n_samples_seen: 128 # i.e. calculate it as full seasonality / data freq
|
||||
history_strength: 2 # retain fitted history as a stronger prior
|
||||
compression: 100 # higher values mean higher accuracy but higher memory usage
|
||||
provide_series: ['anomaly_score', 'yhat'] # common arg example
|
||||
# Common arguments for built-in model, if not set, default to
|
||||
# See https://docs.victoriametrics.com/anomaly-detection/components/models/#common-args
|
||||
#
|
||||
# provide_series: ['anomaly_score', 'yhat', 'yhat_lower', 'yhat_upper']
|
||||
# schedulers: [all scheduler aliases defined in `scheduler` section]
|
||||
# queries: [all query aliases defined in `reader.queries` section]
|
||||
# detection_direction: 'both' # meaning both drops and spikes will be captured
|
||||
# min_dev_from_expected: [0.0, 0.0] # meaning, no minimal threshold is applied to prevent smaller anomalies
|
||||
# scale: [1.0, 1.0] # if needed, prediction intervals' width can be increased (>1) or narrowed (<1)
|
||||
# clip_predictions: False # if data_range for respective `queries` is set in reader, `yhat.*` columns will be clipped
|
||||
# anomaly_score_outside_data_range: 1.01 # auto anomaly score (1.01) if `y` (real value) is outside of data_range, if set
|
||||
```
|
||||
|
||||
{{% /collapse %}}
|
||||
|
||||
</div>
|
||||
|
||||
Resulting metrics of the model are described [here](#vmanomaly-output).
|
||||
|
||||
|
||||
### [Rolling Quantile](https://en.wikipedia.org/wiki/Quantile)
|
||||
|
||||
> `RollingQuantileModel` **is** {{% available_from "v1.28.0" anomaly %}} a [univariate](#univariate-models), [online](#online-models) model. It **was** {{% deprecated_from "v1.28.0" anomaly %}} a [univariate](#univariate-models), [rolling](#rolling-models), [offline](#offline-models) model.
|
||||
|
||||
This model is best used on **data with short evolving patterns** (i.e. 10-100 datapoints of particular frequency), as it adapts to changes over a rolling window.
|
||||
|
||||
<div class="model-details">
|
||||
|
||||
{{% collapse name="Model-specific arguments" %}}
|
||||
|
||||
- `class` (string) - model class name `"model.rolling_quantile.RollingQuantileModel"` (or `rolling_quantile` with class alias support {{% available_from "v1.13.0" anomaly %}})
|
||||
- `quantile` (float) - quantile value, from 0.5 to 1.0. This constraint is implied by 2-sided confidence interval.
|
||||
- `window_steps` (integer) - size of the moving window. (see 'sampling_period')
|
||||
- `iqr_threshold` (float, optional) - {{% available_from "v1.25.0" anomaly %}} The [interquartile range (IQR)](https://en.wikipedia.org/wiki/Interquartile_range) multiplier to increase the width of the prediction intervals. Defaults to 0 (no adjustment) for backward compatibility. If set > 0, the model will add half IQR * `iqr_threshold` to `yhat_lower` and `yhat_upper`. This is useful for data with high variance or outliers, as it helps to avoid false positives in anomaly detection.
|
||||
|
||||
{{% /collapse %}}
|
||||
|
||||
{{% collapse name="Configuration example" %}}
|
||||
|
||||
```yaml
|
||||
models:
|
||||
your_desired_alias_for_a_model:
|
||||
class: "rolling_quantile"
|
||||
quantile: 0.9
|
||||
window_steps: 96
|
||||
iqr_threshold: 1
|
||||
# Common arguments for built-in model, if not set, default to
|
||||
# See https://docs.victoriametrics.com/anomaly-detection/components/models/#common-args
|
||||
#
|
||||
# provide_series: ['anomaly_score', 'yhat', 'yhat_lower', 'yhat_upper']
|
||||
# schedulers: [all scheduler aliases defined in `scheduler` section]
|
||||
# queries: [all query aliases defined in `reader.queries` section]
|
||||
# detection_direction: 'both' # meaning both drops and spikes will be captured
|
||||
# min_dev_from_expected: [0.0, 0.0] # meaning, no minimal threshold is applied to prevent smaller anomalies
|
||||
# scale: [1.0, 1.0] # if needed, prediction intervals' width can be increased (>1) or narrowed (<1)
|
||||
# clip_predictions: False # if data_range for respective `queries` is set in reader, `yhat.*` columns will be clipped
|
||||
# anomaly_score_outside_data_range: 1.01 # auto anomaly score (1.01) if `y` (real value) is outside of data_range, if set
|
||||
```
|
||||
|
||||
{{% /collapse %}}
|
||||
|
||||
</div>
|
||||
|
||||
Resulting metrics of the model are described [here](#vmanomaly-output).
|
||||
|
||||
|
||||
### Online Seasonal Quantile
|
||||
|
||||
> `OnlineQuantileModel` is a [univariate](#univariate-models), [online](#online-models) model.
|
||||
|
||||
Online (seasonal) quantile utilizes a set of approximate distributions, based on [t-digests](https://www.sciencedirect.com/science/article/pii/S2665963820300403) for online quantile estimation {{% available_from "v1.15.0" anomaly %}}.
|
||||
|
||||
Best used on **[de-trended](https://victoriametrics.com/blog/victoriametrics-anomaly-detection-handbook-chapter-1/#trend) data with strong (potentially multiple) [seasonalities](https://victoriametrics.com/blog/victoriametrics-anomaly-detection-handbook-chapter-1/#seasonality)**. Can act as a (slightly less flexible) replacement to [`ProphetModel`](#prophet).
|
||||
|
||||
It uses the `quantiles` triplet to calculate `yhat_lower`, `yhat`, and `yhat_upper` [output](#vmanomaly-output), respectively, for each of the `min_subseasons` sub-intervals contained in `seasonal_interval`. For example, with '4d' + '2h' seasonality patterns (multiple), it will hold and update 24*4 / 2 = 48 consecutive estimates (each 2 hours long).
|
||||
|
||||
<div class="model-details">
|
||||
|
||||
{{% collapse name="Model-specific arguments" %}}
|
||||
|
||||
- `class` (string) - model class name `"model.online.OnlineQuantileModel"` (or `quantile_online` with class alias support{{% available_from "v1.13.0" anomaly %}})
|
||||
- `quantiles` (list[float], optional) - The quantiles to estimate. `yhat_lower`, `yhat`, `yhat_upper` are the quantile order. By default (0.01, 0.5, 0.99).
|
||||
- `iqr_threshold` (float, optional) - {{% available_from "v1.25.0" anomaly %}} The [interquartile range (IQR)](https://en.wikipedia.org/wiki/Interquartile_range) multiplier to increase the width of the prediction intervals. Defaults to 0 (no adjustment) for backward compatibility. If set > 0, the model will add IQR * `iqr_threshold` to `yhat_lower` and `yhat_upper` (respecting `min_subseason` seasonal buckets). This is useful for data with high variance or outliers, as it helps to avoid false positives in anomaly detection. Best used with **robust** `quantiles` set to (0.25, 0.5, 0.75) or similar.
|
||||
- `seasonal_interval` (string, optional) - the interval for the seasonal adjustment. If not set, the model will equal to a simple online quantile model. By default not set.
|
||||
- `min_subseason` (str, optional) - the minimum interval to estimate quantiles for. By default not set. Note that the minimum interval should be a multiple of the seasonal interval, i.e. if seasonal_interval='2h', then min_subseason='15m' is valid, but '37m' is not.
|
||||
- `use_transform` (bool, optional) - whether to internally apply a `log1p(abs(x)) * sign(x)` transformation to the data to stabilize internal quantile estimation. Does not affect the scale of produced output (i.e. `yhat`) By default False.
|
||||
- `global_smoothing` (float, optional) - the smoothing parameter for the global quantiles. i.e. the output is a weighted average of the global and seasonal quantiles (if `seasonal_interval` and `min_subseason` args are set). Should be from `[0, 1]` interval, where 0 means no smoothing and 1 means using only global quantile values.
|
||||
- `scale` (float, optional) - Is used to adjust the margins between `yhat` and [`yhat_lower`, `yhat_upper`]. New margin = `|yhat_* - yhat_lower| * scale`. Defaults to 1 (no scaling is applied). See `scale`[common arg](https://docs.victoriametrics.com/anomaly-detection/components/models/#scale) section for detailed instructions and 2-sided option.
|
||||
- `season_starts_from` (str, optional) - the start date for the seasonal adjustment, as a reference point to start counting the intervals. By default '1970-01-01'.
|
||||
- `min_n_samples_seen` (int, optional) - the minimum number of samples to be seen (`n_samples_seen_` property) before computing the anomaly score. Otherwise, the **anomaly score will be 0**, as there is not enough data to trust the model's predictions. Defaults to 16.
|
||||
- `history_strength` (float, optional) - {{% available_from "v1.30.0" anomaly %}} strength of the initial history learned by `fit`. Values above `1` preserve fitted quantiles initially but reduce the leverage of subsequent updates. Defaults to `1`.
|
||||
- `compression` (int, optional) - the compression parameter for the underlying [t-digests](https://www.sciencedirect.com/science/article/pii/S2665963820300403). Higher values mean higher accuracy but higher memory usage. By default 100.
|
||||
|
||||
{{% /collapse %}}
|
||||
|
||||
{{% collapse name="Configuration example" %}}
|
||||
|
||||
Suppose we have a data with strong intra-day (hourly) and intra-week (daily) seasonality, data granularity is '5m' with up to 5% expected outliers present in data. Then you can apply similar config:
|
||||
|
||||
```yaml
|
||||
models:
|
||||
your_desired_alias_for_a_model:
|
||||
class: "quantile_online" # or 'model.online.OnlineQuantileModel'
|
||||
quantiles: [0.25, 0.5, 0.75] # lowered to exclude anomalous edges, can be compensated by `scale` param > 1 and `iqr_threshold` > 0
|
||||
iqr_threshold: 2.5 # to increase prediction intervals' width to avoid false positives while still keeping the model robust
|
||||
seasonal_interval: '7d' # longest seasonality (week, day) = week, starting from `season_starts_from`
|
||||
min_subseason: '1h' # smallest seasonality (week, day, hour) = hour, will have its own quantile estimates
|
||||
min_n_samples_seen: 288 # 1440 / 5 - at least 1 full day, ideal = 1440 / 5 * 7 - one full week (seasonal_interval)
|
||||
history_strength: 2 # retain fitted history as a stronger prior
|
||||
scale: 1.1 # to compensate lowered quantile boundaries with wider intervals
|
||||
season_starts_from: '2024-01-01' # interval calculation starting point, especially for uncommon seasonalities like '36h' or '12d'
|
||||
compression: 100 # higher values mean higher accuracy but higher memory usage
|
||||
provide_series: ['anomaly_score', 'yhat'] # common arg example
|
||||
# Common arguments for built-in model, if not set, default to
|
||||
# See https://docs.victoriametrics.com/anomaly-detection/components/models/#common-args
|
||||
#
|
||||
# provide_series: ['anomaly_score', 'yhat', 'yhat_lower', 'yhat_upper']
|
||||
# schedulers: [all scheduler aliases defined in `scheduler` section]
|
||||
# queries: [all query aliases defined in `reader.queries` section]
|
||||
# detection_direction: 'both' # meaning both drops and spikes will be captured
|
||||
# min_dev_from_expected: [0.0, 0.0] # meaning, no minimal threshold is applied to prevent smaller anomalies
|
||||
# scale: [1.0, 1.0] # if needed, prediction intervals' width can be increased (>1) or narrowed (<1)
|
||||
# clip_predictions: False # if data_range for respective `queries` is set in reader, `yhat.*` columns will be clipped
|
||||
# anomaly_score_outside_data_range: 1.01 # auto anomaly score (1.01) if `y` (real value) is outside of data_range, if set
|
||||
```
|
||||
|
||||
{{% /collapse %}}
|
||||
|
||||
</div>
|
||||
|
||||
Resulting metrics of the model are described [here](#vmanomaly-output).
|
||||
|
||||
|
||||
### [Seasonal Trend Decomposition](https://en.wikipedia.org/wiki/Seasonal_adjustment)
|
||||
|
||||
> `StdModel` **is** {{% available_from "v1.28.0" anomaly %}} a [univariate](#univariate-models), [online](#online-models) model. It **was** {{% deprecated_from "v1.28.0" anomaly %}} a [univariate](#univariate-models), [rolling](#rolling-models), [offline](#offline-models) model.
|
||||
|
||||
Here we use Seasonal Decompose implementation from `statsmodels` [library](https://www.statsmodels.org/dev/generated/statsmodels.tsa.seasonal.seasonal_decompose). Parameters from this library can be passed to the model. Some parameters are specifically predefined in `vmanomaly` and can't be changed by user (`model`='additive', `two_sided`=False).
|
||||
|
||||
<div class="model-details">
|
||||
|
||||
{{% collapse name="Model-specific arguments" %}}
|
||||
|
||||
- `class` (string) - model class name `"model.std.StdModel"` (or `std` with class alias support{{% available_from "v1.13.0" anomaly %}})
|
||||
- `period` (integer) - Number of datapoints in one season.
|
||||
- `z_threshold` (float, optional) - [standard score](https://en.wikipedia.org/wiki/Standard_score) for calculating boundaries to define anomaly score. Defaults to `2.5`.
|
||||
|
||||
{{% /collapse %}}
|
||||
|
||||
{{% collapse name="Configuration example" %}}
|
||||
|
||||
|
||||
```yaml
|
||||
models:
|
||||
your_desired_alias_for_a_model:
|
||||
class: "std" # or 'model.std.StdModel' starting from v1.13.0
|
||||
period: 2
|
||||
# Common arguments for built-in model, if not set, default to
|
||||
# See https://docs.victoriametrics.com/anomaly-detection/components/models/#common-args
|
||||
#
|
||||
# provide_series: ['anomaly_score', 'yhat', 'yhat_lower', 'yhat_upper']
|
||||
# schedulers: [all scheduler aliases defined in `scheduler` section]
|
||||
# queries: [all query aliases defined in `reader.queries` section]
|
||||
# detection_direction: 'both' # meaning both drops and spikes will be captured
|
||||
# min_dev_from_expected: [0.0, 0.0] # meaning, no minimal threshold is applied to prevent smaller anomalies
|
||||
# scale: [1.0, 1.0] # if needed, prediction intervals' width can be increased (>1) or narrowed (<1)
|
||||
# clip_predictions: False # if data_range for respective `queries` is set in reader, `yhat.*` columns will be clipped
|
||||
# anomaly_score_outside_data_range: 1.01 # auto anomaly score (1.01) if `y` (real value) is outside of data_range, if set
|
||||
```
|
||||
|
||||
{{% /collapse %}}
|
||||
|
||||
</div>
|
||||
|
||||
Resulting metrics of the model are described [here](#vmanomaly-output).
|
||||
|
||||
**Additional output metrics produced by Seasonal Trend Decomposition model**
|
||||
- `resid` - The residual component of the data series.
|
||||
- `trend` - The trend component of the data series.
|
||||
- `seasonal` - The seasonal component of the data series.
|
||||
|
||||
|
||||
### [Isolation forest](https://en.wikipedia.org/wiki/Isolation_forest) (Multivariate)
|
||||
|
||||
> `IsolationForestModel` is a [univariate](#univariate-models), [offline](#offline-models) model.
|
||||
|
||||
> `IsolationForestMultivariateModel` is a [multivariate](#multivariate-models), [offline](#offline-models) model.
|
||||
|
||||
> [!NOTE]
|
||||
> Both univariate `isolation_forest` and multivariate `isolation_forest_multivariate` are planned for deprecation in a future release. For new deployments, use the corresponding univariate or multivariate online [Temporal Envelope](#temporal-envelope) model.
|
||||
|
||||
Detects anomalies using binary trees. The algorithm has a linear time complexity and a low memory requirement, which works well with high-volume data. It can be used on both univariate and multivariate data, but it is more effective in multivariate case.
|
||||
|
||||
**Important**: Be aware of [the curse of dimensionality](https://en.wikipedia.org/wiki/Curse_of_dimensionality). Don't use single multivariate model if you expect your queries to return many time series of less datapoints that the number of metrics. In such case it is hard for a model to learn meaningful dependencies from too sparse data hypercube.
|
||||
@@ -1319,6 +1269,9 @@ Resulting metrics of the model are described [here](#vmanomaly-output).
|
||||
|
||||
> `HoltWinters` is a [univariate](#univariate-models), [offline](#offline-models) model.
|
||||
|
||||
> [!NOTE]
|
||||
> Holt-Winters is planned for deprecation in a future release. For new deployments, prefer the online [Temporal Envelope](#temporal-envelope) model.
|
||||
|
||||
Here we use Holt-Winters Exponential Smoothing implementation from `statsmodels` [library](https://www.statsmodels.org/dev/generated/statsmodels.tsa.holtwinters.ExponentialSmoothing). All parameters from this library can be passed to the model.
|
||||
|
||||
<div class="model-details">
|
||||
@@ -1378,6 +1331,55 @@ models:
|
||||
|
||||
Resulting metrics of the model are described [here](#vmanomaly-output).
|
||||
|
||||
### [Seasonal Trend Decomposition](https://en.wikipedia.org/wiki/Seasonal_adjustment)
|
||||
|
||||
> `StdModel` **is** {{% available_from "v1.28.0" anomaly %}} a [univariate](#univariate-models), [online](#online-models) model. It **was** {{% deprecated_from "v1.28.0" anomaly %}} a [univariate](#univariate-models), [rolling](#rolling-models), [offline](#offline-models) model.
|
||||
|
||||
Here we use Seasonal Decompose implementation from `statsmodels` [library](https://www.statsmodels.org/dev/generated/statsmodels.tsa.seasonal.seasonal_decompose). Parameters from this library can be passed to the model. Some parameters are specifically predefined in `vmanomaly` and can't be changed by user (`model`='additive', `two_sided`=False).
|
||||
|
||||
<div class="model-details">
|
||||
|
||||
{{% collapse name="Model-specific arguments" %}}
|
||||
|
||||
- `class` (string) - model class name `"model.std.StdModel"` (or `std` with class alias support{{% available_from "v1.13.0" anomaly %}})
|
||||
- `period` (integer) - Number of datapoints in one season.
|
||||
- `z_threshold` (float, optional) - [standard score](https://en.wikipedia.org/wiki/Standard_score) for calculating boundaries to define anomaly score. Defaults to `2.5`.
|
||||
|
||||
{{% /collapse %}}
|
||||
|
||||
{{% collapse name="Configuration example" %}}
|
||||
|
||||
|
||||
```yaml
|
||||
models:
|
||||
your_desired_alias_for_a_model:
|
||||
class: "std" # or 'model.std.StdModel' starting from v1.13.0
|
||||
period: 2
|
||||
# Common arguments for built-in model, if not set, default to
|
||||
# See https://docs.victoriametrics.com/anomaly-detection/components/models/#common-args
|
||||
#
|
||||
# provide_series: ['anomaly_score', 'yhat', 'yhat_lower', 'yhat_upper']
|
||||
# schedulers: [all scheduler aliases defined in `scheduler` section]
|
||||
# queries: [all query aliases defined in `reader.queries` section]
|
||||
# detection_direction: 'both' # meaning both drops and spikes will be captured
|
||||
# min_dev_from_expected: [0.0, 0.0] # meaning, no minimal threshold is applied to prevent smaller anomalies
|
||||
# scale: [1.0, 1.0] # if needed, prediction intervals' width can be increased (>1) or narrowed (<1)
|
||||
# clip_predictions: False # if data_range for respective `queries` is set in reader, `yhat.*` columns will be clipped
|
||||
# anomaly_score_outside_data_range: 1.01 # auto anomaly score (1.01) if `y` (real value) is outside of data_range, if set
|
||||
```
|
||||
|
||||
{{% /collapse %}}
|
||||
|
||||
</div>
|
||||
|
||||
Resulting metrics of the model are described [here](#vmanomaly-output).
|
||||
|
||||
**Additional output metrics produced by Seasonal Trend Decomposition model**
|
||||
- `resid` - The residual component of the data series.
|
||||
- `trend` - The trend component of the data series.
|
||||
- `seasonal` - The seasonal component of the data series.
|
||||
|
||||
|
||||
## vmanomaly output
|
||||
|
||||
`vmanomaly` generates model-dependent output series. Their metric names can be configured in the writer section.
|
||||
@@ -1559,7 +1561,7 @@ See the [component configuration reference](https://docs.victoriametrics.com/ano
|
||||
Pull the `vmanomaly` image:
|
||||
|
||||
```sh
|
||||
docker pull victoriametrics/vmanomaly:v1.30.0
|
||||
docker pull victoriametrics/vmanomaly:v1.30.1
|
||||
```
|
||||
|
||||
Mount the module at `/vmanomaly/src/model/custom.py`, which matches the configured import path `model.custom.CustomModel`. Validate the complete configuration with `--dryRun` before starting the long-running service.
|
||||
@@ -1569,7 +1571,7 @@ docker run --rm \
|
||||
-v "$PWD/license:/license:ro" \
|
||||
-v "$PWD/custom_model.py:/vmanomaly/src/model/custom.py:ro" \
|
||||
-v "$PWD/config.yaml:/config.yaml:ro" \
|
||||
victoriametrics/vmanomaly:v1.30.0 \
|
||||
victoriametrics/vmanomaly:v1.30.1 \
|
||||
/config.yaml \
|
||||
--licenseFile=/license \
|
||||
--dryRun
|
||||
|
||||
@@ -588,7 +588,7 @@ Label names [description](#labelnames)
|
||||
|
||||
`Counter`
|
||||
</td>
|
||||
<td>The number of valid datapoints accepted by `model_alias`, excluding NaN and Inf values, during `fit`, `infer`, or combined `fit_infer` execution for the `query_key` query.</td>
|
||||
<td>The number of valid datapoints accepted by `model_alias`, excluding NaN and Inf values, during `fit`, `infer`, or combined `fit_infer` execution for the `query_key` query. During inference, only previously unseen valid rows are counted {{% available_from "v1.30.1" anomaly %}}.</td>
|
||||
<td>
|
||||
|
||||
`stage`, `query_key`, `model_alias`, `scheduler_alias`, `preset`
|
||||
@@ -687,7 +687,7 @@ Label names [description](#labelnames)
|
||||
|
||||
`Histogram` (was `Summary`{{% deprecated_from "v1.17.0" anomaly %}})
|
||||
</td>
|
||||
<td>The total time (in seconds) taken by write requests to VictoriaMetrics `url` for the `query_key` query within the specified scheduler `scheduler_alias`, in the `vmanomaly` service running in `preset` mode.
|
||||
<td>The total time (in seconds) taken by write requests to VictoriaMetrics `url` for the `query_key` query within the specified scheduler `scheduler_alias`, in the `vmanomaly` service running in `preset` mode. Successful and handled failed attempts, including connection retries, are observed {{% available_from "v1.30.1" anomaly %}}.
|
||||
</td>
|
||||
<td>
|
||||
|
||||
|
||||
@@ -87,7 +87,7 @@ There is change {{% available_from "v1.13.0" anomaly %}} of [`queries`](https://
|
||||
|
||||
- `max_points_per_query`{{% available_from "v1.17.0" anomaly %}} (int): Optional arg, overrides how `search.maxPointsPerTimeseries` flag{{% available_from "v1.14.1" anomaly %}} impacts `vmanomaly` on splitting long `fit_window` [queries](https://docs.victoriametrics.com/anomaly-detection/components/reader/#vm-reader) into smaller sub-intervals. This helps users avoid hitting the `search.maxQueryDuration` limit for individual queries by distributing initial query across multiple subquery requests with minimal overhead. Set less than `search.maxPointsPerTimeseries` if hitting `maxQueryDuration` limits. If set on a query-level, it overrides the global `max_points_per_query` (reader-level).
|
||||
|
||||
- `tz`{{% available_from "v1.18.0" anomaly %}} (string): this optional argument enables timezone specification per query, overriding the reader’s default `tz`. This setting helps to account for local timezone shifts, such as [DST](https://en.wikipedia.org/wiki/Daylight_saving_time), in models that are sensitive to seasonal variations (e.g., [`ProphetModel`](https://docs.victoriametrics.com/anomaly-detection/components/models/#prophet) or [`OnlineQuantileModel`](https://docs.victoriametrics.com/anomaly-detection/components/models/#online-seasonal-quantile)).
|
||||
- `tz`{{% available_from "v1.18.0" anomaly %}} (string): this optional argument enables timezone specification per query, overriding the reader’s default `tz`. This setting helps to account for local timezone shifts, such as [DST](https://en.wikipedia.org/wiki/Daylight_saving_time), in models that are sensitive to seasonal variations (e.g., [`TemporalEnvelopeModel`](https://docs.victoriametrics.com/anomaly-detection/components/models/#temporal-envelope) or [`OnlineQuantileModel`](https://docs.victoriametrics.com/anomaly-detection/components/models/#online-seasonal-quantile)).
|
||||
|
||||
- `tenant_id` {{% available_from "v1.19.0" anomaly %}} (string): this optional argument enables tenant-level separation for queries (e.g. `query1` to get the data from tenant "0:0", `query2` - from tenant "1:0"). It works as follows:
|
||||
- if *not set, inherits* reader-level `tenant_id`
|
||||
@@ -441,7 +441,7 @@ Optional arg{{% available_from "v1.17.0" anomaly %}} overrides how `search.maxPo
|
||||
`UTC`
|
||||
</td>
|
||||
<td>
|
||||
Optional argument {{% available_from "v1.18.0" anomaly %}} specifies the [IANA](https://nodatime.org/TimeZones) timezone to account for local shifts, like [DST](https://en.wikipedia.org/wiki/Daylight_saving_time), in models sensitive to seasonal patterns (e.g., [`TemporalEnvelopeModel`](https://docs.victoriametrics.com/anomaly-detection/components/models/#temporal-envelope), [`ProphetModel`](https://docs.victoriametrics.com/anomaly-detection/components/models/#prophet), or [`OnlineQuantileModel`](https://docs.victoriametrics.com/anomaly-detection/components/models/#online-seasonal-quantile)). Defaults to `UTC` if not set and can be overridden on a [per-query basis](#per-query-parameters).
|
||||
Optional argument {{% available_from "v1.18.0" anomaly %}} specifies the [IANA](https://nodatime.org/TimeZones) timezone to account for local shifts, like [DST](https://en.wikipedia.org/wiki/Daylight_saving_time), in models sensitive to seasonal patterns (e.g., [`TemporalEnvelopeModel`](https://docs.victoriametrics.com/anomaly-detection/components/models/#temporal-envelope) or [`OnlineQuantileModel`](https://docs.victoriametrics.com/anomaly-detection/components/models/#online-seasonal-quantile)). Defaults to `UTC` if not set and can be overridden on a [per-query basis](#per-query-parameters).
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
@@ -825,7 +825,7 @@ Frequency of the points returned. Will be converted to `/select/stats_query_rang
|
||||
`America/New_York`
|
||||
</td>
|
||||
<td>
|
||||
(Optional) Specifies the [IANA](https://nodatime.org/TimeZones) timezone to account for local shifts, like [DST](https://en.wikipedia.org/wiki/Daylight_saving_time), in models sensitive to seasonal patterns (e.g., [`ProphetModel`](https://docs.victoriametrics.com/anomaly-detection/components/models/#prophet) or [`OnlineQuantileModel`](https://docs.victoriametrics.com/anomaly-detection/components/models/#online-seasonal-quantile)). Defaults to `UTC` if not set and can be overridden on a [per-query basis](#per-query-parameters).
|
||||
(Optional) Specifies the [IANA](https://nodatime.org/TimeZones) timezone to account for local shifts, like [DST](https://en.wikipedia.org/wiki/Daylight_saving_time), in models sensitive to seasonal patterns (e.g., [`TemporalEnvelopeModel`](https://docs.victoriametrics.com/anomaly-detection/components/models/#temporal-envelope) or [`OnlineQuantileModel`](https://docs.victoriametrics.com/anomaly-detection/components/models/#online-seasonal-quantile)). Defaults to `UTC` if not set and can be overridden on a [per-query basis](#per-query-parameters).
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
||||
@@ -74,6 +74,8 @@ options={`"scheduler.periodic.PeriodicScheduler"`, `"scheduler.oneoff.OneoffSche
|
||||
|
||||
> {{% available_from "v1.30.0" anomaly %}} If a periodic scheduler worker exits unexpectedly, the service attempts bounded restarts with exponential backoff instead of shutting down unrelated schedulers. Monitor [`vmanomaly_scheduler_alive`](https://docs.victoriametrics.com/anomaly-detection/components/monitoring/#startup-metrics) and `vmanomaly_scheduler_restarts_total` to alert on persistent failures.
|
||||
|
||||
> {{% available_from "v1.30.1" anomaly %}} For exact-capable [online models](https://docs.victoriametrics.com/anomaly-detection/components/models/#online-models), `infer_every` is also the causal model-update cadence. If a delayed periodic job fetches several observations at once, they are processed on the same chronological grid used by exact backtesting rather than as one behaviorally different batch.
|
||||
|
||||
### Parameters
|
||||
|
||||
For periodic scheduler parameters are defined as differences in times, expressed in difference units, e.g. days, hours, minutes, seconds. Time granularity is defined by the last characters of a string. Examples: `"50s"` (seconds), `"4m"` (minutes), `"3h"` (hours), `"2d"` (days), `"1w"` (weeks).
|
||||
@@ -440,7 +442,7 @@ In **Inference only** mode {{% available_from "v1.22.1" anomaly %}}, the schedul
|
||||
- `fit_window`: Duration of historical data used for each training run (e.g. `P7D`, `PT1H`).
|
||||
- `fit_every`: Interval between consecutive training/inference cycles.
|
||||
- {{% available_from "v1.28.0" anomaly %}} `exact`: If set to `true`, BacktestingScheduler will execute inference for online models in small chronological batches equal to `infer_every` to mimic the production scheduler. (default: `false`)
|
||||
- {{% available_from "v1.28.0" anomaly %}} `infer_every`: Optional inference cadence for exact mode, defining how often the scheduler should call infer between two fits, otherwise defaults to `fit_every` when unset.
|
||||
- {{% available_from "v1.28.0" anomaly %}} `infer_every`: Optional inference grid and, in exact mode, model-call cadence between two fits. {{% available_from "v1.30.1" anomaly %}} In `inference_only` mode, an omitted value is derived from the effective query step or reader sampling period and capped by `fit_every`; it falls back to `fit_every` only when neither reader value is available.
|
||||
- `n_jobs`: Number of parallel jobs for backtesting (default: `1`).
|
||||
|
||||
#### Example
|
||||
|
||||
@@ -74,5 +74,7 @@ Rest API endpoints (e.g. `/metrics`) can be accessed at `<vmanomaly-host>:8490/v
|
||||
- `GET /api/v1/autotune/tasks/{task_id}` returns progress and the concrete suggested `modelConfig` when complete.
|
||||
- `DELETE /api/v1/autotune/tasks/{task_id}` cancels pending work cooperatively.
|
||||
|
||||
{{% available_from "v1.30.1" anomaly %}} Seasonality analysis preserves the original timestamp grid when samples are offset from whole step boundaries. This avoids missing daily or weekly patterns solely because timestamps are shifted within the configured sampling interval.
|
||||
|
||||
> [!TIP]
|
||||
> For a complete request and recommended workflow, see [Shared asynchronous autotune workflow](https://docs.victoriametrics.com/anomaly-detection/components/models/#shared-asynchronous-autotune-workflow). OpenAPI schemas for the running version are available at `/docs` endpoint of a running `vmanomaly` instance.
|
||||
|
||||
@@ -42,7 +42,7 @@ schedulers:
|
||||
# other schedulers
|
||||
|
||||
models:
|
||||
zscore_online_override:
|
||||
zscore_online_inherited:
|
||||
class: zscore_online
|
||||
z_threshold: 3.5
|
||||
clip_predictions: True
|
||||
@@ -73,6 +73,7 @@ reader:
|
||||
writer:
|
||||
class: "vm"
|
||||
datasource_url: http://localhost:8428
|
||||
tenant_id: "0"
|
||||
metric_format:
|
||||
__name__: "$VAR"
|
||||
for: "$QUERY_KEY"
|
||||
@@ -249,12 +250,11 @@ models:
|
||||
class: zscore_online
|
||||
z_threshold: 3.5
|
||||
schedulers: ['periodic_1d']
|
||||
prophet:
|
||||
class: prophet
|
||||
temporal_envelope:
|
||||
class: temporal_envelope
|
||||
schedulers: ['periodic_1d']
|
||||
queries: ['q1', 'q2']
|
||||
args:
|
||||
interval_width: 0.98
|
||||
seasonalities: ['hod_smooth', 'dow_smooth']
|
||||
reader:
|
||||
class: vm
|
||||
datasource_url: 'https://play.victoriametrics.com'
|
||||
@@ -268,7 +268,7 @@ reader:
|
||||
# other components like writer, monitoring, etc.
|
||||
```
|
||||
|
||||
if the service is restarted in less than 1 hour after the last training (now < next scheduled fit time), it will restore the state of the `zscore_online` and `prophet` models if their signature (class, hyperparameters, schedulers, etc.) has not changed. It will load the trained model instances or their training data from disk and continue producing [anomaly scores](https://docs.victoriametrics.com/anomaly-detection/faq/#what-is-anomaly-score) without retraining. If there are changes or new queries added to the configuration, the service will add these to scheduled jobs for fit and infer. That's what is changed and what is restored in a config below:
|
||||
if the service is restarted in less than 1 hour after the last training (now < next scheduled fit time), it will restore the state of the `zscore_online` and `temporal_envelope` models if their signature (class, hyperparameters, schedulers, etc.) has not changed. It will load the trained model instances or their training data from disk and continue producing [anomaly scores](https://docs.victoriametrics.com/anomaly-detection/faq/#what-is-anomaly-score) without retraining. If there are changes or new queries added to the configuration, the service will add these to scheduled jobs for fit and infer. That's what is changed and what is restored in a config below:
|
||||
|
||||
```yaml
|
||||
settings:
|
||||
@@ -285,12 +285,11 @@ models:
|
||||
class: zscore_online # unchanged, still the same model class
|
||||
z_threshold: 3.0 # changed, needs retraining!
|
||||
schedulers: ['periodic_1d'] # unchanged, still attached to the same scheduler
|
||||
prophet: # can be partially reused, because its class and schedulers are unchanged but queries have changed
|
||||
class: prophet # unchanged, still the same model class
|
||||
temporal_envelope: # can be partially reused, because its class and schedulers are unchanged but queries have changed
|
||||
class: temporal_envelope # unchanged, still the same model class
|
||||
schedulers: ['periodic_1d'] # unchanged, still attached to the same scheduler
|
||||
queries: ['q1', 'q3'] # changed, added new query 'q3', drops 'q2', so (prophet, q2) should be trained from scratch
|
||||
args:
|
||||
interval_width: 0.98 # unchanged, still the same argument
|
||||
queries: ['q1', 'q3'] # changed, added new query 'q3', drops 'q2', so (temporal_envelope, q2) should be trained from scratch
|
||||
seasonalities: ['hod_smooth', 'dow_smooth'] # unchanged
|
||||
reader: # can be partially reused, because its class and datasource URL are unchanged, but queries have changed
|
||||
class: vm # unchanged, still the same reader class
|
||||
datasource_url: 'https://play.victoriametrics.com' # unchanged, still the same datasource URL
|
||||
@@ -301,13 +300,13 @@ reader: # can be partially reused, because its class and datasource URL are unc
|
||||
q2:
|
||||
expr: 'some_metricsql_query_2' # will be removed, no longer used by any model
|
||||
q3:
|
||||
expr: 'some_metricsql_query_3' # new query, added to the reader, and used by the `prophet` model
|
||||
expr: 'some_metricsql_query_3' # new query, added to the reader, and used by the `temporal_envelope` model
|
||||
sampling_period: 30s # unchanged, still the same sampling period
|
||||
# other components like writer, monitoring, etc. remain unchanged
|
||||
```
|
||||
This means that the service upon restart:
|
||||
1. Won't restore the state of `zscore_online` model, because its `z_threshold` argument **has changed**, retraining from scratch is needed on the last `fit_window` = 24 hours of data for `q1`, `q2` and `q3` (as model's `queries` arg is not set so it defaults to all queries found in the reader).
|
||||
2. Will **partially** restore the state of `prophet` model, because its class and schedulers are unchanged, but **only instances trained on timeseries returned by `q1` query**. New fit/infer jobs will be set for new query `q3`. The old query `q2` artifacts will be dropped upon restart - all respective models and data for (`prophet`, `q2`) combination will be removed from the database file and from the disk.
|
||||
2. Will **partially** restore the state of `temporal_envelope` model, because its class and schedulers are unchanged, but **only instances trained on timeseries returned by `q1` query**. New fit/infer jobs will be set for new query `q3`. The old query `q2` artifacts will be dropped upon restart - all respective models and data for (`temporal_envelope`, `q2`) combination will be removed from the database file and from the disk.
|
||||
|
||||
{{% /collapse %}}
|
||||
|
||||
@@ -371,7 +370,7 @@ models:
|
||||
queries: ['q1']
|
||||
# other model args
|
||||
m2: # model instances will be likely dropped during retention checks due to high churn rate
|
||||
class: prophet
|
||||
class: temporal_envelope
|
||||
schedulers: ['s1']
|
||||
queries: ['q2']
|
||||
# other model args
|
||||
@@ -406,7 +405,7 @@ settings:
|
||||
restore_state: True # enables state restoration
|
||||
logger_levels:
|
||||
reader.vm: DEBUG # affects only VmReader logs
|
||||
model: WARNING # applies to all components with 'model' prefix, such as 'model.zscore_online', 'model.prophet', etc.
|
||||
model: WARNING # applies to all components with 'model' prefix, such as 'model.zscore_online', 'model.online.temporal_envelope', etc.
|
||||
# once commented out in hot-reload mode, will use the default logger level set by --loggerLevel command line argument
|
||||
# monitoring.push: critical
|
||||
```
|
||||
|
||||
@@ -10,9 +10,9 @@ sitemap:
|
||||
|
||||
- To use *vmanomaly*, part of the enterprise package, a license key is required. Obtain your key [here](https://victoriametrics.com/products/enterprise/trial/) for this tutorial or for enterprise use.
|
||||
- In the tutorial, we'll be using the following VictoriaMetrics components:
|
||||
- [VictoriaMetrics Single-Node](https://docs.victoriametrics.com/victoriametrics/single-server-victoriametrics/) (v1.148.0)
|
||||
- [vmalert](https://docs.victoriametrics.com/victoriametrics/vmalert/) (v1.148.0)
|
||||
- [vmagent](https://docs.victoriametrics.com/victoriametrics/vmagent/) (v1.148.0)
|
||||
- [VictoriaMetrics Single-Node](https://docs.victoriametrics.com/victoriametrics/single-server-victoriametrics/) (v1.149.0)
|
||||
- [vmalert](https://docs.victoriametrics.com/victoriametrics/vmalert/) (v1.149.0)
|
||||
- [vmagent](https://docs.victoriametrics.com/victoriametrics/vmagent/) (v1.149.0)
|
||||
- [Grafana](https://grafana.com/) (v12.2.0)
|
||||
- [Docker](https://docs.docker.com/get-docker/) and [Docker Compose](https://docs.docker.com/compose/)
|
||||
- [Node exporter](https://github.com/prometheus/node_exporter#node-exporter) (v1.9.1) and [Alertmanager](https://prometheus.io/docs/alerting/latest/alertmanager/) (v0.28.1)
|
||||
@@ -323,7 +323,7 @@ Let's wrap it all up together into the `docker-compose.yml` file.
|
||||
services:
|
||||
vmagent:
|
||||
container_name: vmagent
|
||||
image: victoriametrics/vmagent:v1.148.0
|
||||
image: victoriametrics/vmagent:v1.149.0
|
||||
depends_on:
|
||||
- "victoriametrics"
|
||||
ports:
|
||||
@@ -340,7 +340,7 @@ services:
|
||||
|
||||
victoriametrics:
|
||||
container_name: victoriametrics
|
||||
image: victoriametrics/victoria-metrics:v1.148.0
|
||||
image: victoriametrics/victoria-metrics:v1.149.0
|
||||
ports:
|
||||
- 8428:8428
|
||||
volumes:
|
||||
@@ -373,7 +373,7 @@ services:
|
||||
|
||||
vmalert:
|
||||
container_name: vmalert
|
||||
image: victoriametrics/vmalert:v1.148.0
|
||||
image: victoriametrics/vmalert:v1.149.0
|
||||
depends_on:
|
||||
- "victoriametrics"
|
||||
ports:
|
||||
@@ -395,7 +395,7 @@ services:
|
||||
restart: always
|
||||
vmanomaly:
|
||||
container_name: vmanomaly
|
||||
image: victoriametrics/vmanomaly:v1.30.0
|
||||
image: victoriametrics/vmanomaly:v1.30.1
|
||||
depends_on:
|
||||
- "victoriametrics"
|
||||
ports:
|
||||
|
||||
@@ -240,23 +240,23 @@ vmagent will write data into VictoriaMetrics single-node and cluster (with tenan
|
||||
# compose.yaml
|
||||
services:
|
||||
vmsingle:
|
||||
image: victoriametrics/victoria-metrics:v1.148.0
|
||||
image: victoriametrics/victoria-metrics:v1.149.0
|
||||
|
||||
vmstorage:
|
||||
image: victoriametrics/vmstorage:v1.148.0-cluster
|
||||
image: victoriametrics/vmstorage:v1.149.0-cluster
|
||||
|
||||
vminsert:
|
||||
image: victoriametrics/vminsert:v1.148.0-cluster
|
||||
image: victoriametrics/vminsert:v1.149.0-cluster
|
||||
command:
|
||||
- -storageNode=vmstorage:8400
|
||||
|
||||
vmselect:
|
||||
image: victoriametrics/vmselect:v1.148.0-cluster
|
||||
image: victoriametrics/vmselect:v1.149.0-cluster
|
||||
command:
|
||||
- -storageNode=vmstorage:8401
|
||||
|
||||
vmagent:
|
||||
image: victoriametrics/vmagent:v1.148.0
|
||||
image: victoriametrics/vmagent:v1.149.0
|
||||
volumes:
|
||||
- ./scrape.yaml:/etc/vmagent/config.yaml
|
||||
command:
|
||||
@@ -308,7 +308,7 @@ Now add the vmauth service to `compose.yaml`:
|
||||
# compose.yaml
|
||||
services:
|
||||
vmauth:
|
||||
image: docker.io/victoriametrics/vmauth:v1.148.0
|
||||
image: docker.io/victoriametrics/vmauth:v1.149.0
|
||||
ports:
|
||||
- 8427:8427
|
||||
volumes:
|
||||
|
||||
@@ -155,15 +155,15 @@ These services will store and query the metrics scraped by vmagent.
|
||||
# compose.yaml
|
||||
services:
|
||||
vmstorage:
|
||||
image: victoriametrics/vmstorage:v1.148.0-cluster
|
||||
image: victoriametrics/vmstorage:v1.149.0-cluster
|
||||
|
||||
vminsert:
|
||||
image: victoriametrics/vminsert:v1.148.0-cluster
|
||||
image: victoriametrics/vminsert:v1.149.0-cluster
|
||||
command:
|
||||
- -storageNode=vmstorage:8400
|
||||
|
||||
vmselect:
|
||||
image: victoriametrics/vmselect:v1.148.0-cluster
|
||||
image: victoriametrics/vmselect:v1.149.0-cluster
|
||||
command:
|
||||
- -storageNode=vmstorage:8401
|
||||
ports:
|
||||
@@ -196,7 +196,7 @@ Add the vmauth service to `compose.yaml`:
|
||||
# compose.yaml
|
||||
services:
|
||||
vmauth:
|
||||
image: victoriametrics/vmauth:v1.148.0-enterprise
|
||||
image: victoriametrics/vmauth:v1.149.0-enterprise
|
||||
ports:
|
||||
- 8427:8427
|
||||
volumes:
|
||||
@@ -251,7 +251,7 @@ Add the vmagent service to `compose.yaml` with OAuth2 configuration:
|
||||
# compose.yaml
|
||||
services:
|
||||
vmagent:
|
||||
image: victoriametrics/vmagent:v1.148.0
|
||||
image: victoriametrics/vmagent:v1.149.0
|
||||
volumes:
|
||||
- ./scrape.yaml:/etc/vmagent/config.yaml
|
||||
command:
|
||||
|
||||
@@ -107,7 +107,7 @@ The final piece is the Docker Compose file. This ties all the services together
|
||||
# compose.yml
|
||||
services:
|
||||
victoriametrics:
|
||||
image: victoriametrics/victoria-metrics:v1.148.0
|
||||
image: victoriametrics/victoria-metrics:v1.149.0
|
||||
command:
|
||||
- "--storageDataPath=/victoria-metrics-data"
|
||||
- "--selfScrapeInterval=10s"
|
||||
@@ -128,7 +128,7 @@ services:
|
||||
- ./alertmanager.yml:/etc/alertmanager/alertmanager.yml:ro
|
||||
|
||||
vmalert:
|
||||
image: victoriametrics/vmalert:v1.148.0
|
||||
image: victoriametrics/vmalert:v1.149.0
|
||||
depends_on:
|
||||
- victoriametrics
|
||||
- alertmanager
|
||||
|
||||
@@ -27,5 +27,5 @@ to [the latest available releases](https://docs.victoriametrics.com/victoriametr
|
||||
|
||||
## Currently supported LTS release lines
|
||||
|
||||
- v1.148.x - the latest one is [v1.148.0 LTS release](https://github.com/VictoriaMetrics/VictoriaMetrics/releases/tag/v1.148.0)
|
||||
- v1.136.x - the latest one is [v1.136.14 LTS release](https://github.com/VictoriaMetrics/VictoriaMetrics/releases/tag/v1.136.14)
|
||||
- v1.148.x - the latest one is [v1.148.1 LTS release](https://github.com/VictoriaMetrics/VictoriaMetrics/releases/tag/v1.148.1)
|
||||
- v1.136.x - the latest one is [v1.136.15 LTS release](https://github.com/VictoriaMetrics/VictoriaMetrics/releases/tag/v1.136.15)
|
||||
|
||||
@@ -53,8 +53,8 @@ and unpack it. It contains a single `victoria-metrics-prod` binary.
|
||||
For example, on Linux with `amd64` architecture:
|
||||
|
||||
```sh
|
||||
wget https://github.com/VictoriaMetrics/VictoriaMetrics/releases/download/v1.148.0/victoria-metrics-linux-amd64-v1.148.0.tar.gz
|
||||
tar xzf victoria-metrics-linux-amd64-v1.148.0.tar.gz
|
||||
wget https://github.com/VictoriaMetrics/VictoriaMetrics/releases/download/v1.149.0/victoria-metrics-linux-amd64-v1.149.0.tar.gz
|
||||
tar xzf victoria-metrics-linux-amd64-v1.149.0.tar.gz
|
||||
```
|
||||
|
||||
The binary is self-contained and requires no installation - it is ready to run as is.
|
||||
@@ -229,9 +229,9 @@ Download the newest available [VictoriaMetrics release](https://docs.victoriamet
|
||||
from [DockerHub](https://hub.docker.com/r/victoriametrics/victoria-metrics) or [Quay](https://quay.io/repository/victoriametrics/victoria-metrics?tab=tags):
|
||||
|
||||
```sh
|
||||
docker pull victoriametrics/victoria-metrics:v1.148.0
|
||||
docker pull victoriametrics/victoria-metrics:v1.149.0
|
||||
docker run -it --rm -v `pwd`/victoria-metrics-data:/victoria-metrics-data -p 8428:8428 \
|
||||
victoriametrics/victoria-metrics:v1.148.0 --selfScrapeInterval=5s -storageDataPath=victoria-metrics-data
|
||||
victoriametrics/victoria-metrics:v1.149.0 --selfScrapeInterval=5s -storageDataPath=victoria-metrics-data
|
||||
```
|
||||
|
||||
_For Enterprise images, see [this link](https://docs.victoriametrics.com/victoriametrics/enterprise/#docker-images)._
|
||||
|
||||
@@ -25,10 +25,11 @@ The sandbox cluster installation runs under the constant load generated by
|
||||
See also [LTS releases](https://docs.victoriametrics.com/victoriametrics/lts-releases/).
|
||||
|
||||
## tip
|
||||
* BUGFIX: [vmsingle](https://docs.victoriametrics.com/victoriametrics/single-server-victoriametrics/), `vmselect` in [VictoriaMetrics cluster](https://docs.victoriametrics.com/victoriametrics/cluster-victoriametrics/) and [vmctl](https://docs.victoriametrics.com/victoriametrics/vmctl/): properly parse small fractional Unix timestamps in timestamp args such as `start` and `end` in `/api/v1/query_range` and `--vm-native-filter-time-start` and `--vm-native-filter-time-end` in `vmctl`. Previously, fractional Unix timestamps with the integer part below `9223372` were interpreted with the wrong unit, for example `12.0` was parsed as `12000` seconds instead of `12` seconds. See [#11324](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/11324).
|
||||
|
||||
## [v1.149.0](https://github.com/VictoriaMetrics/VictoriaMetrics/releases/tag/v1.149.0)
|
||||
|
||||
Release candidate
|
||||
Released at 2026-08-05
|
||||
|
||||
**Update Note 1:** `vminsert` in [VictoriaMetrics cluster](https://docs.victoriametrics.com/victoriametrics/cluster-victoriametrics/): the default value of `-disableRerouting` flag has changed from `true` to `false`, enabling [slowness-based re-routing](https://docs.victoriametrics.com/victoriametrics/cluster-victoriametrics/#slowness-based-re-routing) by default. Slowness re-routing is automatically disabled when `-replicationFactor` is greater than 1. If you rely on the old behavior, pass `-disableRerouting` command-line flag to `vminsert`. See [#11287](https://github.com/VictoriaMetrics/VictoriaMetrics/pull/11287).
|
||||
|
||||
@@ -53,6 +54,25 @@ Release candidate
|
||||
* BUGFIX: [stream aggregation](https://docs.victoriametrics.com/victoriametrics/stream-aggregation/): fix incorrect [sum_samples_total](https://docs.victoriametrics.com/victoriametrics/stream-aggregation/configuration/#sum_samples_total) results when `enable_windows: true` is set. See [#11261](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/11261). Thanks to @beyond-infra for contribution.
|
||||
* BUGFIX: [vmsingle](https://docs.victoriametrics.com/victoriametrics/single-server-victoriametrics/), `vmselect` in [VictoriaMetrics cluster](https://docs.victoriametrics.com/victoriametrics/cluster-victoriametrics/) and [vmctl](https://docs.victoriametrics.com/victoriametrics/vmctl/): accept scientific notation with sub-second precision (e.g. `1.784144612388E9`) for timestamp args such as `start` and `end` in `/api/v1/query_range` and `--vm-native-filter-time-start` and `--vm-native-filter-time-end` in `vmctl`. Previously, values with this pattern were rejected, which is incompatible with Prometheus. See [#11268](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/11268). Thanks to @STiFLeR7 for contribution.
|
||||
|
||||
## [v1.148.1](https://github.com/VictoriaMetrics/VictoriaMetrics/releases/tag/v1.148.1)
|
||||
|
||||
Released at 2026-07-31
|
||||
|
||||
**v1.148.x is a line of [LTS releases](https://docs.victoriametrics.com/victoriametrics/lts-releases/). It contains important up-to-date bugfixes for [VictoriaMetrics enterprise](https://docs.victoriametrics.com/victoriametrics/enterprise/).
|
||||
All these fixes are also included in [the latest community release](https://github.com/VictoriaMetrics/VictoriaMetrics/releases/latest).
|
||||
The v1.148.x line will be supported for at least 12 months since [v1.148.0](https://docs.victoriametrics.com/victoriametrics/changelog/#v11480) release**
|
||||
|
||||
**Update Note 1:** [vmsingle](https://docs.victoriametrics.com/victoriametrics/single-server-victoriametrics/) and `vmselect` in [VictoriaMetrics cluster](https://docs.victoriametrics.com/victoriametrics/cluster-victoriametrics/): the `/api/v1/admin/tsdb/delete_series`, `/tags/delSeries` endpoints now require `POST` method. Previously, it also accepted `GET` requests. If you use `GET` requests for this endpoint, update your scripts or tooling to use `POST` instead. See [#5552](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/5552).
|
||||
|
||||
* SECURITY: [vmsingle](https://docs.victoriametrics.com/victoriametrics/single-server-victoriametrics/) and `vmselect` in [VictoriaMetrics cluster](https://docs.victoriametrics.com/victoriametrics/cluster-victoriametrics/): restrict `/api/v1/admin/tsdb/delete_series`, `/tags/delSeries` endpoints to `POST` method only to prevent some [SSRF](https://en.wikipedia.org/wiki/Server-side_request_forgery)-based data deletion attacks. See [#5552](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/5552).
|
||||
|
||||
* BUGFIX: [MetricsQL](https://docs.victoriametrics.com/victoriametrics/metricsql/): properly drop data points filtered out by an inner [comparison operation](https://prometheus.io/docs/prometheus/latest/querying/operators/#comparison-binary-operators) when its result is used on the right side of another comparison. Previously, queries like `foo != (bar > 100)` could return unexpected results because filtered-out data points are represented internally as `NaN`, and `value != NaN` evaluates to `true`. Comparisons against explicitly present `NaN` values keep the previous behavior. See [#10018](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/10018). Thanks to @zasdaym for contribution.
|
||||
* BUGFIX: [vmagent](https://docs.victoriametrics.com/victoriametrics/vmagent/) and [vmsingle](https://docs.victoriametrics.com/victoriametrics/single-server-victoriametrics/): ignore HTTP proxy environment variables when scraping targets over Unix domain sockets. See [#11318](https://github.com/VictoriaMetrics/VictoriaMetrics/pull/11318). Thanks to @lwmacct for contribution.
|
||||
* BUGFIX: [vmalert](https://docs.victoriametrics.com/victoriametrics/vmalert/): fixed the display of rule state badges on the `Groups` page in the web UI. See [#11160](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/11160).
|
||||
* BUGFIX: [vmbackupmanager](https://docs.victoriametrics.com/victoriametrics/vmbackupmanager/): previously, `vmbackupmanager` was crashing on startup when it failed to restore backup state from remote storage, causing a crash loop. Now it logs the error and continues running, retrying the state restore before each scheduled backup. Added `vm_backup_errors_total{type="restoreState"}` metric to track backup state restore failures. See [#11217](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/11217).
|
||||
* BUGFIX: [stream aggregation](https://docs.victoriametrics.com/victoriametrics/stream-aggregation/): fix incorrect [sum_samples_total](https://docs.victoriametrics.com/victoriametrics/stream-aggregation/configuration/#sum_samples_total) results when `enable_windows: true` is set. See [#11261](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/11261). Thanks to @beyond-infra for contribution.
|
||||
* BUGFIX: [vmsingle](https://docs.victoriametrics.com/victoriametrics/single-server-victoriametrics/), `vmselect` in [VictoriaMetrics cluster](https://docs.victoriametrics.com/victoriametrics/cluster-victoriametrics/) and [vmctl](https://docs.victoriametrics.com/victoriametrics/vmctl/): accept scientific notation with sub-second precision (e.g. `1.784144612388E9`) for timestamp args such as `start` and `end` in `/api/v1/query_range` and `--vm-native-filter-time-start` and `--vm-native-filter-time-end` in `vmctl`. Previously, values with this pattern were rejected, which is incompatible with Prometheus. See [#11268](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/11268). Thanks to @STiFLeR7 for contribution.
|
||||
|
||||
## [v1.148.0](https://github.com/VictoriaMetrics/VictoriaMetrics/releases/tag/v1.148.0)
|
||||
|
||||
Released at 2026-07-20
|
||||
@@ -375,6 +395,20 @@ It enables back `Discovered targets` debug UI by default.
|
||||
* BUGFIX: `vmstorage` in [VictoriaMetrics cluster](https://docs.victoriametrics.com/victoriametrics/cluster-victoriametrics/): properly apply `extra_filters[]` filter when querying `vm_account_id` or `vm_project_id` labels via [multitenant](https://docs.victoriametrics.com/victoriametrics/cluster-victoriametrics/#multitenancy) request for `/api/v1/label/…/values` API. Before, `extra_filters` was ignored. See [#10503](https://github.com/VictoriaMetrics/VictoriaMetrics/pull/10503).
|
||||
* BUGFIX: [vmsingle](https://docs.victoriametrics.com/victoriametrics/single-server-victoriametrics/) and `vmselect` in [VictoriaMetrics cluster](https://docs.victoriametrics.com/victoriametrics/cluster-victoriametrics/): revert the use of rollup result cache for [instant queries](https://docs.victoriametrics.com/keyConcepts.html#instant-query) that contain [`rate`](https://docs.victoriametrics.com/MetricsQL.html#rate) function with a lookbehind window larger than `-search.minWindowForInstantRollupOptimization`. The cache usage was removed since [v1.132.0](https://github.com/VictoriaMetrics/VictoriaMetrics/releases/tag/v1.132.0). See [#10098](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/10098#issuecomment-3895011084) for more details.
|
||||
|
||||
## [v1.136.15](https://github.com/VictoriaMetrics/VictoriaMetrics/releases/tag/v1.136.15)
|
||||
|
||||
Released at 2026-07-31
|
||||
|
||||
**v1.136.x is a line of [LTS releases](https://docs.victoriametrics.com/victoriametrics/lts-releases/). It contains important up-to-date bugfixes for [VictoriaMetrics enterprise](https://docs.victoriametrics.com/victoriametrics/enterprise/).
|
||||
All these fixes are also included in [the latest community release](https://github.com/VictoriaMetrics/VictoriaMetrics/releases/latest).
|
||||
The v1.136.x line will be supported for at least 12 months since [v1.136.0](https://docs.victoriametrics.com/victoriametrics/changelog/#v11360) release**
|
||||
|
||||
**Update Note 1:** [vmsingle](https://docs.victoriametrics.com/victoriametrics/single-server-victoriametrics/) and `vmselect` in [VictoriaMetrics cluster](https://docs.victoriametrics.com/victoriametrics/cluster-victoriametrics/): the `/api/v1/admin/tsdb/delete_series`, `/tags/delSeries` endpoints now require `POST` method. Previously, it also accepted `GET` requests. If you use `GET` requests for this endpoint, update your scripts or tooling to use `POST` instead. See [#5552](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/5552).
|
||||
|
||||
* SECURITY: [vmsingle](https://docs.victoriametrics.com/victoriametrics/single-server-victoriametrics/) and `vmselect` in [VictoriaMetrics cluster](https://docs.victoriametrics.com/victoriametrics/cluster-victoriametrics/): restrict `/api/v1/admin/tsdb/delete_series`, `/tags/delSeries` endpoints to `POST` method only to prevent some [SSRF](https://en.wikipedia.org/wiki/Server-side_request_forgery)-based data deletion attacks. See [#5552](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/5552).
|
||||
|
||||
* BUGFIX: [vmbackupmanager](https://docs.victoriametrics.com/victoriametrics/vmbackupmanager/): previously, `vmbackupmanager` was crashing on startup when it failed to restore backup state from remote storage, causing a crash loop. Now it logs the error and continues running, retrying the state restore before each scheduled backup. Added `vm_backup_errors_total{type="restoreState"}` metric to track backup state restore failures. See [#11217](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/11217).
|
||||
|
||||
## [v1.136.14](https://github.com/VictoriaMetrics/VictoriaMetrics/releases/tag/v1.136.14)
|
||||
|
||||
Released at 2026-07-17
|
||||
|
||||
@@ -121,7 +121,7 @@ It is allowed to run Enterprise components in [cases listed here](https://docs.v
|
||||
Binary releases of Enterprise components are available at [the releases page for VictoriaMetrics](https://github.com/VictoriaMetrics/VictoriaMetrics/releases/latest),
|
||||
[the releases page for VictoriaLogs](https://github.com/VictoriaMetrics/VictoriaLogs/releases/latest)
|
||||
and [the releases page for VictoriaTraces](https://github.com/VictoriaMetrics/VictoriaTraces/releases/latest).
|
||||
Enterprise binaries and packages have `enterprise` suffix in their names. For example, `victoria-metrics-linux-amd64-v1.148.0-enterprise.tar.gz`.
|
||||
Enterprise binaries and packages have `enterprise` suffix in their names. For example, `victoria-metrics-linux-amd64-v1.149.0-enterprise.tar.gz`.
|
||||
|
||||
In order to run binary release of Enterprise component, please download the `*-enterprise.tar.gz` archive for your OS and architecture
|
||||
from the corresponding releases page and unpack it. Then run the unpacked binary.
|
||||
@@ -139,8 +139,8 @@ For example, the following command runs VictoriaMetrics Enterprise binary with t
|
||||
obtained at [this page](https://victoriametrics.com/products/enterprise/trial/):
|
||||
|
||||
```sh
|
||||
wget https://github.com/VictoriaMetrics/VictoriaMetrics/releases/download/v1.148.0/victoria-metrics-linux-amd64-v1.148.0-enterprise.tar.gz
|
||||
tar -xzf victoria-metrics-linux-amd64-v1.148.0-enterprise.tar.gz
|
||||
wget https://github.com/VictoriaMetrics/VictoriaMetrics/releases/download/v1.149.0/victoria-metrics-linux-amd64-v1.149.0-enterprise.tar.gz
|
||||
tar -xzf victoria-metrics-linux-amd64-v1.149.0-enterprise.tar.gz
|
||||
./victoria-metrics-prod -license=BASE64_ENCODED_LICENSE_KEY
|
||||
```
|
||||
|
||||
@@ -155,7 +155,7 @@ Alternatively, VictoriaMetrics Enterprise license can be stored in the file and
|
||||
It is allowed to run Enterprise components in [cases listed here](https://docs.victoriametrics.com/victoriametrics/enterprise/#valid-cases-for-victoriametrics-enterprise).
|
||||
|
||||
Docker images for Enterprise components are available at [VictoriaMetrics Docker Hub](https://hub.docker.com/u/victoriametrics) and [VictoriaMetrics Quay](https://quay.io/organization/victoriametrics).
|
||||
Enterprise docker images have `enterprise` suffix in their names. For example, `victoriametrics/victoria-metrics:v1.148.0-enterprise`.
|
||||
Enterprise docker images have `enterprise` suffix in their names. For example, `victoriametrics/victoria-metrics:v1.149.0-enterprise`.
|
||||
|
||||
In order to run Docker image of VictoriaMetrics Enterprise component, it is required to provide the license key via the command-line
|
||||
flag as described in the [binary-releases](https://docs.victoriametrics.com/victoriametrics/enterprise/#binary-releases) section.
|
||||
@@ -165,13 +165,13 @@ Enterprise license key can be obtained at [this page](https://victoriametrics.co
|
||||
For example, the following command runs VictoriaMetrics Enterprise Docker image with the specified license key:
|
||||
|
||||
```sh
|
||||
docker run --name=victoria-metrics victoriametrics/victoria-metrics:v1.148.0-enterprise -license=BASE64_ENCODED_LICENSE_KEY
|
||||
docker run --name=victoria-metrics victoriametrics/victoria-metrics:v1.149.0-enterprise -license=BASE64_ENCODED_LICENSE_KEY
|
||||
```
|
||||
|
||||
Alternatively, the license code can be stored in the file and then referred via `-licenseFile` command-line flag:
|
||||
|
||||
```sh
|
||||
docker run --name=victoria-metrics -v /vm-license:/vm-license victoriametrics/victoria-metrics:v1.148.0-enterprise -licenseFile=/path/to/vm-license
|
||||
docker run --name=victoria-metrics -v /vm-license:/vm-license victoriametrics/victoria-metrics:v1.149.0-enterprise -licenseFile=/path/to/vm-license
|
||||
```
|
||||
|
||||
Example docker-compose configuration:
|
||||
@@ -181,7 +181,7 @@ version: "3.5"
|
||||
services:
|
||||
victoriametrics:
|
||||
container_name: victoriametrics
|
||||
image: victoriametrics/victoria-metrics:v1.148.0
|
||||
image: victoriametrics/victoria-metrics:v1.149.0
|
||||
ports:
|
||||
- 8428:8428
|
||||
volumes:
|
||||
@@ -213,7 +213,7 @@ is used to provide the license key in plain-text:
|
||||
```yaml
|
||||
server:
|
||||
image:
|
||||
tag: v1.148.0-enterprise
|
||||
tag: v1.149.0-enterprise
|
||||
|
||||
license:
|
||||
key: {BASE64_ENCODED_LICENSE_KEY}
|
||||
@@ -224,7 +224,7 @@ In order to provide the license key via existing secret, the following values fi
|
||||
```yaml
|
||||
server:
|
||||
image:
|
||||
tag: v1.148.0-enterprise
|
||||
tag: v1.149.0-enterprise
|
||||
|
||||
license:
|
||||
secret:
|
||||
@@ -274,7 +274,7 @@ spec:
|
||||
license:
|
||||
key: {BASE64_ENCODED_LICENSE_KEY}
|
||||
image:
|
||||
tag: v1.148.0-enterprise
|
||||
tag: v1.149.0-enterprise
|
||||
```
|
||||
|
||||
In order to provide the license key via an existing secret, the following custom resource is used:
|
||||
@@ -291,7 +291,7 @@ spec:
|
||||
name: vm-license
|
||||
key: license
|
||||
image:
|
||||
tag: v1.148.0-enterprise
|
||||
tag: v1.149.0-enterprise
|
||||
```
|
||||
|
||||
Example secret with license key:
|
||||
@@ -342,7 +342,7 @@ Builds are available for amd64 and arm64 architectures.
|
||||
|
||||
Example archive:
|
||||
|
||||
`victoria-metrics-linux-amd64-v1.148.0-enterprise.tar.gz`
|
||||
`victoria-metrics-linux-amd64-v1.149.0-enterprise.tar.gz`
|
||||
|
||||
Includes:
|
||||
|
||||
@@ -351,7 +351,7 @@ Includes:
|
||||
|
||||
Example Docker image:
|
||||
|
||||
`victoriametrics/victoria-metrics:v1.148.0-enterprise-fips` – uses the FIPS-compatible binary and based on `scratch` image.
|
||||
`victoriametrics/victoria-metrics:v1.149.0-enterprise-fips` – uses the FIPS-compatible binary and based on `scratch` image.
|
||||
|
||||
## What Happens to Licensed Components When a License Expires
|
||||
|
||||
|
||||
@@ -35,8 +35,8 @@ scrape_configs:
|
||||
After you created the `scrape.yaml` file, download and unpack [single-node VictoriaMetrics](https://docs.victoriametrics.com/victoriametrics/single-server-victoriametrics/) to the same directory:
|
||||
|
||||
```sh
|
||||
wget https://github.com/VictoriaMetrics/VictoriaMetrics/releases/download/v1.148.0/victoria-metrics-linux-amd64-v1.148.0.tar.gz
|
||||
tar xzf victoria-metrics-linux-amd64-v1.148.0.tar.gz
|
||||
wget https://github.com/VictoriaMetrics/VictoriaMetrics/releases/download/v1.149.0/victoria-metrics-linux-amd64-v1.149.0.tar.gz
|
||||
tar xzf victoria-metrics-linux-amd64-v1.149.0.tar.gz
|
||||
```
|
||||
|
||||
Then start VictoriaMetrics and instruct it to scrape targets defined in `scrape.yaml` and save scraped metrics
|
||||
@@ -150,8 +150,8 @@ Then start [single-node VictoriaMetrics](https://docs.victoriametrics.com/victor
|
||||
|
||||
```yaml
|
||||
# Download and unpack single-node VictoriaMetrics
|
||||
wget https://github.com/VictoriaMetrics/VictoriaMetrics/releases/download/v1.148.0/victoria-metrics-linux-amd64-v1.148.0.tar.gz
|
||||
tar xzf victoria-metrics-linux-amd64-v1.148.0.tar.gz
|
||||
wget https://github.com/VictoriaMetrics/VictoriaMetrics/releases/download/v1.149.0/victoria-metrics-linux-amd64-v1.149.0.tar.gz
|
||||
tar xzf victoria-metrics-linux-amd64-v1.149.0.tar.gz
|
||||
|
||||
# Run single-node VictoriaMetrics with the given scrape.yaml
|
||||
./victoria-metrics-prod -promscrape.config=scrape.yaml
|
||||
|
||||
@@ -640,7 +640,7 @@ See the docs at https://docs.victoriametrics.com/victoriametrics/
|
||||
-vmalert.proxyURL string
|
||||
Optional URL for proxying requests to vmalert. For example, if -vmalert.proxyURL=http://vmalert:8880 , then alerting API requests such as /api/v1/rules from Grafana will be proxied to http://vmalert:8880/api/v1/rules . See https://docs.victoriametrics.com/victoriametrics/single-server-victoriametrics/#vmalert
|
||||
-vmselectAddr string
|
||||
TCP address to accept connections from vmselect services
|
||||
TCP address to listen for incoming connections from vmselect. When set, the node will be able to accept cluster-native vmselect RPC requests as if it were vmstorage. The tenant ID assigned to this node's data is controlled by -accountID and -projectID flags. See https://docs.victoriametrics.com/victoriametrics/single-server-victoriametrics/#multi-tenancy
|
||||
-vmui.customDashboardsPath string
|
||||
Optional path to vmui dashboards. See https://github.com/VictoriaMetrics/VictoriaMetrics/tree/master/app/vmui/packages/vmui/public/dashboards
|
||||
-vmui.defaultTimezone string
|
||||
|
||||
@@ -468,7 +468,7 @@ See the docs at https://docs.victoriametrics.com/victoriametrics/vmagent/ .
|
||||
-remoteWrite.maxRowsPerBlock int
|
||||
The maximum number of samples to send in each block to remote storage. Higher number may improve performance at the cost of the increased memory usage. See also -remoteWrite.maxBlockSize (default 10000)
|
||||
-remoteWrite.mdx.enable array
|
||||
Whether to only retain metrics from VictoriaMetrics services before sending them to the corresponding -remoteWrite.url. Please see https://docs.victoriametrics.com/victoriametrics/vmagent/#monitoring-data-exchange
|
||||
Whether to only retain metrics from VictoriaMetrics services before sending them to the corresponding -remoteWrite.url. Can be combined with -remoteWrite.obfuscateLabels to hide sensitive label values in the forwarded metrics. Please see https://docs.victoriametrics.com/victoriametrics/vmagent/#monitoring-data-exchange
|
||||
Supports array of values separated by comma or specified via multiple flags.
|
||||
Empty values are set to false.
|
||||
-remoteWrite.oauth2.clientID array
|
||||
@@ -495,6 +495,10 @@ See the docs at https://docs.victoriametrics.com/victoriametrics/vmagent/ .
|
||||
Optional OAuth2 tokenURL to use for the corresponding -remoteWrite.url
|
||||
Supports an array of values separated by comma or specified via multiple flags.
|
||||
Each array item can contain comma inside single-quoted or double-quoted string, {}, [] and () braces.
|
||||
-remoteWrite.obfuscateLabels ^^
|
||||
List of label names whose values will be obfuscated before being sent to the corresponding -remoteWrite.url. Multiple label names should be separated by ^^, e.g. "job^^instance,ip". Can be combined with -remoteWrite.mdx.enable to hide sensitive label values in VictoriaMetrics self-monitoring metrics. Please see https://docs.victoriametrics.com/victoriametrics/vmagent/#obfuscating-label-values
|
||||
Supports an `array` of values separated by comma or specified via multiple flags.
|
||||
Each array item can contain comma inside single-quoted or double-quoted string, {}, [] and () braces.
|
||||
-remoteWrite.proxyURL array
|
||||
Optional proxy URL for writing data to the corresponding -remoteWrite.url. Supported proxies: http, https, socks5. Example: -remoteWrite.proxyURL=socks5://proxy:1234
|
||||
Supports an array of values separated by comma or specified via multiple flags.
|
||||
|
||||
@@ -404,7 +404,7 @@ See the docs at https://docs.victoriametrics.com/victoriametrics/vmalert/ .
|
||||
Optional TLS server name to use for connections to -remoteWrite.url. By default, the server name from -remoteWrite.url is used
|
||||
-remoteWrite.url string
|
||||
Optional URL to persist alerts state and recording rules results in form of timeseries. It must support either VictoriaMetrics remote write protocol or Prometheus remote_write protocol. Supports address in the form of IP address with a port (e.g., http://127.0.0.1:8428) or DNS SRV record. For example, if -remoteWrite.url=http://127.0.0.1:8428 is specified, then the alerts state will be written to http://127.0.0.1:8428/api/v1/write . See also -remoteWrite.disablePathAppend, '-remoteWrite.showURL'.
|
||||
-replay.continueWithExecutionErr bool
|
||||
-replay.continueWithExecutionErr
|
||||
Whether to continue replaying other rules if a rule execution fails with a 422 response code, which can happen due to an expression syntax error or a resource limit being hit.
|
||||
-replay.disableProgressBar
|
||||
Whether to disable rendering progress bars during the replay. Progress bar rendering might be verbose or break the logs parsing, so it is recommended to be disabled when not used in interactive mode.
|
||||
|
||||
@@ -34,9 +34,9 @@ vmctl command-line tool is available as:
|
||||
|
||||
Download and unpack vmctl:
|
||||
```sh
|
||||
wget https://github.com/VictoriaMetrics/VictoriaMetrics/releases/download/v1.148.0/vmutils-darwin-arm64-v1.148.0.tar.gz
|
||||
wget https://github.com/VictoriaMetrics/VictoriaMetrics/releases/download/v1.149.0/vmutils-darwin-arm64-v1.149.0.tar.gz
|
||||
|
||||
tar xzf vmutils-darwin-arm64-v1.148.0.tar.gz
|
||||
tar xzf vmutils-darwin-arm64-v1.149.0.tar.gz
|
||||
```
|
||||
|
||||
Once binary is unpacked, see the full list of supported modes by running the following command:
|
||||
|
||||
@@ -31,7 +31,7 @@ See the docs at https://docs.victoriametrics.com/victoriametrics/cluster-victori
|
||||
-denyQueryTracing
|
||||
Whether to disable the ability to trace queries. See https://docs.victoriametrics.com/victoriametrics/single-server-victoriametrics/#query-tracing
|
||||
-disableRerouting
|
||||
Whether to disable re-routing when some of vmstorage nodes accept incoming data at slower speed compared to other storage nodes. Disabled re-routing limits the ingestion rate by the slowest vmstorage node. On the other side, disabled re-routing minimizes the number of active time series in the cluster during rolling restarts and during spikes in series churn rate. See also -disableReroutingOnUnavailable and -dropSamplesOnOverload (default true)
|
||||
Whether to disable re-routing when some of vmstorage nodes accept incoming data at slower speed compared to other storage nodes. Disabled re-routing limits the ingestion rate by the slowest vmstorage node. On the other side, disabled re-routing minimizes the number of active time series in the cluster during rolling restarts and during spikes in series churn rate. See also -disableReroutingOnUnavailable and -dropSamplesOnOverload
|
||||
-disableReroutingOnUnavailable
|
||||
Whether to disable re-routing when some of vmstorage nodes are unavailable. Disabled re-routing stops ingestion when some storage nodes are unavailable. On the other side, disabled re-routing minimizes the number of active time series in the cluster during rolling restarts and during spikes in series churn rate. See also -disableRerouting
|
||||
-dropSamplesOnOverload
|
||||
|
||||
@@ -132,7 +132,7 @@ See the docs at https://docs.victoriametrics.com/victoriametrics/cluster-victori
|
||||
-loggerWarnsPerSecondLimit int
|
||||
Per-second limit on the number of WARN messages. If more than the given number of warns are emitted per second, then the remaining warns are suppressed. Zero values disable the rate limit
|
||||
-maxConcurrentInserts int
|
||||
The maximum number of concurrent insert requests. Set higher value when clients send data over slow networks. Default value depends on the number of available CPU cores. It should work fine in most cases since it minimizes resource usage. See also -insert.maxQueueDuration (default 24)
|
||||
The maximum number of concurrent insert requests. Set higher value when clients send data over slow networks. Default value depends on the number of available CPU cores. It should work fine in most cases since it minimizes resource usage. See also -insert.maxQueueDuration (default 20)
|
||||
-memory.allowedBytes size
|
||||
Allowed size of system memory VictoriaMetrics caches may occupy. This option overrides -memory.allowedPercent if set to a non-zero value. Too low a value may increase the cache miss rate usually resulting in higher CPU and disk IO usage. Too high a value may evict too much data from the OS page cache resulting in higher disk IO usage. The process may behave unexpectedly if this flag is set too small (e.g., 1 byte).
|
||||
Supports the following optional suffixes for size values: KB, MB, GB, TB, KiB, MiB, GiB, TiB (default 0)
|
||||
|
||||
@@ -148,11 +148,11 @@ func TryParseUnixTimestamp(s string) (int64, bool) {
|
||||
if !ok {
|
||||
return 0, false
|
||||
}
|
||||
n, ok := tryParseScientificNumberForUnixTimestamp(s[:expIdx], decimalExp)
|
||||
n, ok := tryParseScientificUnixTimestamp(s[:expIdx], decimalExp)
|
||||
if !ok {
|
||||
return 0, false
|
||||
}
|
||||
return getUnixTimestampNanoseconds(n), true
|
||||
return n, true
|
||||
}
|
||||
|
||||
dotIdx := strings.IndexByte(s, '.')
|
||||
@@ -168,22 +168,11 @@ func TryParseUnixTimestamp(s string) (int64, bool) {
|
||||
// The timestamp is fractional.
|
||||
intStr := s[:dotIdx]
|
||||
fracStr := s[dotIdx+1:]
|
||||
n, ok := tryParseFractionalNumberForUnixTimestamp(intStr, fracStr)
|
||||
n, ok := tryParseFractionalUnixTimestamp(intStr, fracStr)
|
||||
if !ok {
|
||||
return 0, false
|
||||
}
|
||||
|
||||
// Adjust the n to multiples of thousands, since this is expected by getUnixTimestampNanoseconds.
|
||||
decimalExp := len(fracStr)
|
||||
for decimalExp%3 != 0 {
|
||||
if n >= 0 && n > math.MaxInt64/10 || n < 0 && n < math.MinInt64/10 {
|
||||
return 0, false
|
||||
}
|
||||
n *= 10
|
||||
decimalExp++
|
||||
}
|
||||
|
||||
return getUnixTimestampNanoseconds(n), true
|
||||
return n, true
|
||||
}
|
||||
|
||||
func getExpIndex(s string) int {
|
||||
@@ -196,49 +185,52 @@ func getExpIndex(s string) int {
|
||||
return -1
|
||||
}
|
||||
|
||||
func tryParseScientificNumberForUnixTimestamp(s string, decimalExp int64) (int64, bool) {
|
||||
func tryParseScientificUnixTimestamp(s string, decimalExp int64) (int64, bool) {
|
||||
if decimalExp < 0 {
|
||||
// Negative exponents on a fractional mantissa are intentionally not
|
||||
// supported. See https://github.com/VictoriaMetrics/VictoriaMetrics/issues/11268
|
||||
return 0, false
|
||||
}
|
||||
dotIdx := strings.IndexByte(s, '.')
|
||||
if dotIdx < 0 {
|
||||
n, ok := tryParseInt64(s)
|
||||
if !ok {
|
||||
return 0, false
|
||||
}
|
||||
return multiplyByDecimalExp(n, decimalExp)
|
||||
}
|
||||
|
||||
if decimalExp < 0 {
|
||||
// Negative exponents on a fractional mantissa are intentionally not
|
||||
// supported. See https://github.com/VictoriaMetrics/VictoriaMetrics/issues/11268
|
||||
return 0, false
|
||||
n, ok = multiplyByDecimalExp(n, decimalExp)
|
||||
if !ok {
|
||||
return 0, false
|
||||
}
|
||||
return getUnixTimestampNanoseconds(n), true
|
||||
}
|
||||
|
||||
intStr := s[:dotIdx]
|
||||
fracStr := s[dotIdx+1:]
|
||||
n, ok := tryParseFractionalNumberForUnixTimestamp(intStr, fracStr)
|
||||
if !ok {
|
||||
return 0, false
|
||||
}
|
||||
if decimalExp >= int64(len(fracStr)) {
|
||||
// The exponent shifts the decimal point past every fractional digit,
|
||||
// so the value is an integer number of seconds (or coarser).
|
||||
// The exponent shifts the decimal point past every fractional digit.
|
||||
n, ok := tryParseDecimalMantissaAsInt(intStr, fracStr)
|
||||
if !ok {
|
||||
return 0, false
|
||||
}
|
||||
decimalExp -= int64(len(fracStr))
|
||||
return multiplyByDecimalExp(n, decimalExp)
|
||||
n, ok = multiplyByDecimalExp(n, decimalExp)
|
||||
if !ok {
|
||||
return 0, false
|
||||
}
|
||||
return getUnixTimestampNanoseconds(n), true
|
||||
}
|
||||
|
||||
// The exponent leaves fractional digits, e.g. 1.784144612388E9 == 1784144612.388
|
||||
// Pad n as plain fractional timestamps do.
|
||||
fracDigits := int64(len(fracStr)) - decimalExp
|
||||
for fracDigits%3 != 0 {
|
||||
if n >= 0 && n > math.MaxInt64/10 || n < 0 && n < math.MinInt64/10 {
|
||||
return 0, false
|
||||
}
|
||||
n *= 10
|
||||
fracDigits++
|
||||
if decimalExp >= int64(len(decimalMultipliers)) {
|
||||
return 0, false
|
||||
}
|
||||
return n, true
|
||||
decimalExpInt := int(decimalExp)
|
||||
intStr = s[:dotIdx] + fracStr[:decimalExpInt]
|
||||
fracStr = fracStr[decimalExpInt:]
|
||||
return tryParseFractionalUnixTimestamp(intStr, fracStr)
|
||||
}
|
||||
|
||||
func tryParseFractionalNumberForUnixTimestamp(intStr, fracStr string) (int64, bool) {
|
||||
func tryParseDecimalMantissaAsInt(intStr, fracStr string) (int64, bool) {
|
||||
n, ok := tryParseInt64(intStr)
|
||||
if !ok {
|
||||
return 0, false
|
||||
@@ -270,6 +262,53 @@ func tryParseFractionalNumberForUnixTimestamp(intStr, fracStr string) (int64, bo
|
||||
return num, true
|
||||
}
|
||||
|
||||
func tryParseFractionalUnixTimestamp(intStr, fracStr string) (int64, bool) {
|
||||
n, ok := tryParseInt64(intStr)
|
||||
if !ok {
|
||||
return 0, false
|
||||
}
|
||||
isNegative := n < 0 || n == 0 && strings.HasPrefix(intStr, "-")
|
||||
|
||||
multiplier, maxFracDigits := getUnixTimestampMultiplier(n)
|
||||
// Truncate the fractional digits to valid length according to the unit precision.
|
||||
if len(fracStr) > maxFracDigits {
|
||||
// 1.123456789XXX is invalid.
|
||||
tail := fracStr[maxFracDigits:]
|
||||
for i := 0; i < len(tail); i++ {
|
||||
if tail[i] < '0' || tail[i] > '9' {
|
||||
return 0, false
|
||||
}
|
||||
}
|
||||
fracStr = fracStr[:maxFracDigits]
|
||||
}
|
||||
if len(fracStr) == 0 {
|
||||
return n * multiplier, true
|
||||
}
|
||||
|
||||
frac, ok := tryParseInt64(fracStr)
|
||||
if !ok {
|
||||
return 0, false
|
||||
}
|
||||
decimalExp := len(fracStr)
|
||||
if decimalExp >= len(decimalMultipliers) {
|
||||
return 0, false
|
||||
}
|
||||
n *= multiplier
|
||||
scale := decimalMultipliers[decimalExp]
|
||||
frac *= multiplier / scale
|
||||
|
||||
if isNegative {
|
||||
if n < math.MinInt64+frac {
|
||||
return 0, false
|
||||
}
|
||||
return n - frac, true
|
||||
}
|
||||
if n > math.MaxInt64-frac {
|
||||
return 0, false
|
||||
}
|
||||
return n + frac, true
|
||||
}
|
||||
|
||||
func multiplyByDecimalExp(n int64, decimalExp int64) (int64, bool) {
|
||||
if decimalExp < 0 {
|
||||
return 0, false
|
||||
@@ -302,20 +341,25 @@ const (
|
||||
)
|
||||
|
||||
func getUnixTimestampNanoseconds(n int64) int64 {
|
||||
multiplier, _ := getUnixTimestampMultiplier(n)
|
||||
return n * multiplier
|
||||
}
|
||||
|
||||
func getUnixTimestampMultiplier(n int64) (int64, int) {
|
||||
if n <= maxValidSecond && n >= minValidSecond {
|
||||
// The timestamp is in seconds.
|
||||
return n * 1e9
|
||||
return 1e9, 9
|
||||
}
|
||||
if n <= maxValidMilli && n >= minValidMilli {
|
||||
// The timestamp is in milliseconds.
|
||||
return n * 1e6
|
||||
return 1e6, 6
|
||||
}
|
||||
if n <= maxValidMicro && n >= minValidMicro {
|
||||
// The timestamp is in microseconds.
|
||||
return n * 1e3
|
||||
return 1e3, 3
|
||||
}
|
||||
// The timestamp is in nanoseconds
|
||||
return n
|
||||
return 1, 0
|
||||
}
|
||||
|
||||
func tryParseInt64(s string) (int64, bool) {
|
||||
|
||||
@@ -24,62 +24,83 @@ func TestTryParseUnixTimestamp_Success(t *testing.T) {
|
||||
f("0", 0)
|
||||
|
||||
// nanoseconds
|
||||
f("-1234567890123456789", -1234567890123456789)
|
||||
f("1234567890123456789", 1234567890123456789)
|
||||
f("1234567890123456.789", 1234567890123456789)
|
||||
f("-1234567890123456789", -1234567890_123_456_789)
|
||||
f("1234567890123456789", 1234567890_123_456_789)
|
||||
f("1234567890123456.789", 1234567890_123_456_789)
|
||||
f("12345678901234567.891", 12345678_901_234_567)
|
||||
f("12345678901234567.89", 12345678_901_234_567)
|
||||
f("12345678901234567.8", 12345678_901_234_567)
|
||||
|
||||
// microseconds
|
||||
f("-1234567890123456", -1234567890123456000)
|
||||
f("1234567890123456", 1234567890123456000)
|
||||
f("1234567890123456.789", 1234567890123456789)
|
||||
f("-1234567890123456", -1234567890_123_456_000)
|
||||
f("1234567890123456", 1234567890_123_456_000)
|
||||
f("1234567890123456.789", 1234567890_123_456_789)
|
||||
f("12345678901234.5000", 12345678_901_234_500)
|
||||
f("12345678901234.5123", 12345678_901_234_512)
|
||||
f("12345678901234.567891", 12345678_901_234_567)
|
||||
|
||||
// milliseconds
|
||||
f("-1234567890123", -1234567890123000000)
|
||||
f("1234567890123", 1234567890123000000)
|
||||
f("1234567890123.456", 1234567890123456000)
|
||||
f("-1234567890123", -1234567890_123_000_000)
|
||||
f("1234567890123", 1234567890_123_000_000)
|
||||
f("1234567890123.456", 1234567890_123_456_000)
|
||||
|
||||
// seconds
|
||||
f("-1234567890", -1234567890000000000)
|
||||
f("1234567890", 1234567890000000000)
|
||||
f("1234567890.123456789", 1234567890123456789)
|
||||
f("1234567890.12345678", 1234567890123456780)
|
||||
f("1234567890.1234567", 1234567890123456700)
|
||||
f("-1234567890.123456", -1234567890123456000)
|
||||
f("-1234567890.12345", -1234567890123450000)
|
||||
f("-1234567890.1234", -1234567890123400000)
|
||||
f("-1234567890.123", -1234567890123000000)
|
||||
f("-1234567890.12", -1234567890120000000)
|
||||
f("-1234567890.1", -1234567890100000000)
|
||||
f("-1234567890", -1234567890_000_000_000)
|
||||
f("1234567890", 1234567890_000_000_000)
|
||||
f("1234567890.123456789", 1234567890_123_456_789)
|
||||
f("1234567890.12345678", 1234567890_123_456_780)
|
||||
f("1234567890.1234567", 1234567890_123_456_700)
|
||||
f("-1234567890.123456", -1234567890_123_456_000)
|
||||
f("-1234567890.12345", -1234567890_123_450_000)
|
||||
f("-1234567890.1234", -1234567890_123_400_000)
|
||||
f("-1234567890.123", -1234567890_123_000_000)
|
||||
f("-1234567890.12", -1234567890_120_000_000)
|
||||
f("-1234567890.1", -1234567890_100_000_000)
|
||||
f("12", 12_000_000_000)
|
||||
f("12.", 12_000_000_000)
|
||||
f("12.0", 12_000_000_000)
|
||||
f("12.34", 12_340_000_000)
|
||||
f("12.999999999000000000", 12_999_999_999)
|
||||
f("0.1234567890123456789123", 123_456_789)
|
||||
f("-0.1234567890123456789123", -123_456_789)
|
||||
f("-12", -12_000_000_000)
|
||||
f("-12.34", -12_340_000_000)
|
||||
f("8223372", 8223372_000_000_000)
|
||||
f("8223372.0", 8223372_000_000_000)
|
||||
f("1700000000", 1700000000_000_000_000)
|
||||
f("1700000000.0", 1700000000_000_000_000)
|
||||
|
||||
// scientific notation
|
||||
f("1e9", 1000000000000000000)
|
||||
f("1.234e9", 1234000000000000000)
|
||||
f("-1.23456789e9", -1234567890000000000)
|
||||
f("1.234567890123456789e18", 1234567890123456789)
|
||||
f("-1.234567890123456789e18", -1234567890123456789)
|
||||
f("0.23456789e9", 234567890000000000)
|
||||
f("123.456789123e9", 123456789123000000)
|
||||
f("-1234.5678912e9", -1234567891200000000)
|
||||
f("123.678912e7", 1236789120000000000)
|
||||
f("1.23e7", 12300000000000000)
|
||||
f("1.23e6", 1230000000000000)
|
||||
f("1.23e5", 123000000000000)
|
||||
f("1.23e4", 12300000000000)
|
||||
f("1.23e3", 1230000000000)
|
||||
f("1.23e2", 123000000000)
|
||||
f("1.2e1", 12000000000)
|
||||
f("1123.456789123456789E15", 1123456789123456789)
|
||||
f("1e9", 1000000000_000_000_000)
|
||||
f("1.234e9", 1234000000_000_000_000)
|
||||
f("-1.23456789e9", -1234567890_000_000_000)
|
||||
f("1.234567890123456789e18", 1234567890_123_456_789)
|
||||
f("-1.234567890123456789e18", -1234567890_123_456_789)
|
||||
f("0.23456789e9", 234567890_000_000_000)
|
||||
f("123.456789123e9", 123456789_123_000_000)
|
||||
f("-1234.5678912e9", -1234567891_200_000_000)
|
||||
f("123.678912e7", 1236789120_000_000_000)
|
||||
f("1.23e7", 12300000_000_000_000)
|
||||
f("1.23e6", 1230000_000_000_000)
|
||||
f("1.23e5", 123000_000_000_000)
|
||||
f("1.23e4", 12300_000_000_000)
|
||||
f("1.23e3", 1230_000_000_000)
|
||||
f("1.23e2", 123_000_000_000)
|
||||
f("1.2e1", 12_000_000_000)
|
||||
f("1123.456789123456789E15", 1123456789_123_456_789)
|
||||
|
||||
// scientific notation with sub-second precision, i.e. more fractional digits
|
||||
// than the exponent shifts (https://github.com/VictoriaMetrics/VictoriaMetrics/issues/11268).
|
||||
// These must match the equivalent plain fractional form.
|
||||
f("1.784144612388E9", 1784144612388000000) // == 1784144612.388
|
||||
f("1.784144612388e9", 1784144612388000000)
|
||||
f("-1.784144612388e9", -1784144612388000000)
|
||||
f("1.5000000005e9", 1500000000500000000) // == 1500000000.5
|
||||
f("1.23456789e9", 1234567890000000000) // exponent consumes all frac digits (integer result)
|
||||
f("1.23e1", 12300000000000) // == 12.3
|
||||
f("1.234e0", 1234000000000) // == 1.234
|
||||
f("1.784144612388E9", 1784144612_388_000_000) // == 1784144612.388
|
||||
f("1.784144612388e9", 1784144612_388_000_000)
|
||||
f("-1.784144612388e9", -1784144612_388_000_000)
|
||||
f("1.5000000005e9", 1500000000_500_000_000) // == 1500000000.5
|
||||
f("1.23456789e9", 1234567890_000_000_000) // exponent consumes all frac digits (integer result)
|
||||
f("1.23e1", 12_300_000_000) // == 12.3
|
||||
f("1.234e0", 1_234_000_000) // == 1.234
|
||||
f("1234567890123456789.0e0", 1234567890_123_456_789)
|
||||
|
||||
}
|
||||
|
||||
func TestTryParseUnixTimestamp_Failure(t *testing.T) {
|
||||
@@ -97,30 +118,20 @@ func TestTryParseUnixTimestamp_Failure(t *testing.T) {
|
||||
f("foobar")
|
||||
f("foo.bar")
|
||||
f("1.12345671x34")
|
||||
f("1.123456789x")
|
||||
f("1.3e12345678x0123")
|
||||
f("1xs.12345671")
|
||||
f("1xs.12345671e5")
|
||||
f("-1xs.12345671e5")
|
||||
|
||||
// missing fractional part
|
||||
f("1233344.")
|
||||
|
||||
// too big timestamp
|
||||
f("12345678901234567.891")
|
||||
f("12345678901234567890")
|
||||
f("12345678901234.567891")
|
||||
f("12345678901234567890e3")
|
||||
f("12345678901234567890.234e3")
|
||||
f("-12345678901234567890")
|
||||
f("12345678901234567890.235424")
|
||||
f("12345678901234567890.235424e3")
|
||||
f("-12345678901234567890.235424")
|
||||
f("12345678901234567.89")
|
||||
f("12345678901234567.8")
|
||||
|
||||
// too big fractional part
|
||||
f("0.1234567890123456789123")
|
||||
f("-0.1234567890123456789123")
|
||||
|
||||
// too big decimal exponent
|
||||
f("1e19")
|
||||
@@ -129,6 +140,7 @@ func TestTryParseUnixTimestamp_Failure(t *testing.T) {
|
||||
// negative decimal exponent
|
||||
f("1E-1")
|
||||
f("1.3e-123456789090123")
|
||||
|
||||
}
|
||||
|
||||
func TestParseTimeAtSuccess(t *testing.T) {
|
||||
@@ -146,27 +158,27 @@ func TestParseTimeAtSuccess(t *testing.T) {
|
||||
now := time.Now().UnixNano()
|
||||
|
||||
// unix timestamp in seconds
|
||||
f("1562529662", now, 1562529662*1e9)
|
||||
f("1562529662.6", now, 1562529662600*1e6)
|
||||
f("1562529662.67", now, 1562529662670*1e6)
|
||||
f("1562529662.678", now, 1562529662678*1e6)
|
||||
f("1562529662.678123", now, 1562529662678123*1e3)
|
||||
f("1562529662.678123456", now, 1562529662678123456)
|
||||
f("1562529662", now, 1562529662_000_000_000)
|
||||
f("1562529662.6", now, 1562529662_600_000_000)
|
||||
f("1562529662.67", now, 1562529662_670_000_000)
|
||||
f("1562529662.678", now, 1562529662_678_000_000)
|
||||
f("1562529662.678123", now, 1562529662_678_123_000)
|
||||
f("1562529662.678123456", now, 1562529662_678_123_456)
|
||||
|
||||
// unix timestamp in milliseconds
|
||||
f("1562529662678", now, 1562529662678*1e6)
|
||||
f("1562529662678.9", now, 1562529662678900*1e3)
|
||||
f("1562529662678.901", now, 1562529662678901*1e3)
|
||||
f("1562529662678.901324", now, 1562529662678901324)
|
||||
f("1562529662678", now, 1562529662_678_000_000)
|
||||
f("1562529662678.9", now, 1562529662_678_900_000)
|
||||
f("1562529662678.901", now, 1562529662_678_901_000)
|
||||
f("1562529662678.901324", now, 1562529662_678_901_324)
|
||||
|
||||
// unix timestamp in microseconds
|
||||
f("1562529662678901", now, 1562529662678901*1e3)
|
||||
f("1562529662678901.3", now, 1562529662678901300)
|
||||
f("1562529662678901.32", now, 1562529662678901320)
|
||||
f("1562529662678901.321", now, 1562529662678901321)
|
||||
f("1562529662678901", now, 1562529662_678_901_000)
|
||||
f("1562529662678901.3", now, 1562529662_678_901_300)
|
||||
f("1562529662678901.32", now, 1562529662_678_901_320)
|
||||
f("1562529662678901.321", now, 1562529662_678_901_321)
|
||||
|
||||
// unix timestamp in nanoseconds
|
||||
f("1562529662678901234", now, 1562529662678901234)
|
||||
f("1562529662678901234", now, 1562529662_678_901_234)
|
||||
|
||||
// duration relative to the current time
|
||||
f("now", now, now)
|
||||
@@ -175,7 +187,7 @@ func TestParseTimeAtSuccess(t *testing.T) {
|
||||
// negative duration relative to the current time
|
||||
f("-5m", now, now-5*60*1e9)
|
||||
f("-123", now, now-123*1e9)
|
||||
f("-123.456", now, now-123456*1e6)
|
||||
f("-123.456", now, now-123_456*1e6)
|
||||
f("now-1h5m", now, now-(3600+5*60)*1e9)
|
||||
|
||||
// Year
|
||||
@@ -209,9 +221,9 @@ func TestParseTimeAtSuccess(t *testing.T) {
|
||||
f("2023-05-20T04:57:43-02:30", now, 1.684567663e+09*1e9)
|
||||
|
||||
// milliseconds
|
||||
f("2023-05-20T04:57:43.123Z", now, 1684558663123000000)
|
||||
f("2023-05-20T04:57:43.123456789+02:30", now, 1684549663123456789)
|
||||
f("2023-05-20T04:57:43.123456789-02:30", now, 1684567663123456789)
|
||||
f("2023-05-20T04:57:43.123Z", now, 1684558663_123_000_000)
|
||||
f("2023-05-20T04:57:43.123456789+02:30", now, 1684549663_123_456_789)
|
||||
f("2023-05-20T04:57:43.123456789-02:30", now, 1684567663_123_456_789)
|
||||
}
|
||||
|
||||
func TestParseTimeAtLimits(t *testing.T) {
|
||||
|
||||
Reference in New Issue
Block a user