Repository: VictoriaMetrics/VictoriaMetrics
Pull request #3361 (2022-11-17 23:58:39)

vmui: minor fixes
- solve the infinity loop on the page "Dashboards"
- fix show list of autocomplete values
- fix keypress while the autocomplete is enabled: https://github.com/VictoriaMetrics/VictoriaMetrics/pull/3298#issuecomment-1317807862
- reset the value of the switches "Trace request" and "Disable cache: https://github.com/VictoriaMetrics/VictoriaMetrics/pull/3298#issuecomment-1317807862
- add text cursor for inputs: https://github.com/VictoriaMetrics/VictoriaMetrics/pull/3298#issuecomment-1317810873




Patch:
diff --git a/README.md b/README.md
index 2eaa7d47a..558f17c6b 100644
--- a/README.md
+++ b/README.md
@@ -2035,6 +2035,8 @@ Pass `-help` to VictoriaMetrics in order to see the list of supported command-li
 ```
   -bigMergeConcurrency int
      The maximum number of CPU cores to use for big merges. Default value is used if set to 0
+  -cacheExpireDuration duration
+     Items are removed from in-memory caches after they aren't accessed for this duration. Lower values may reduce memory usage at the cost of higher CPU usage. See also -prevCacheRemovalPercent (default 30m0s)
   -configAuthKey string
      Authorization key for accessing /config page. It must be passed via authKey query arg
   -csvTrimTimestamp duration
@@ -2053,7 +2055,7 @@ Pass `-help` to VictoriaMetrics in order to see the list of supported command-li
   -denyQueryTracing
      Whether to disable the ability to trace queries. See https://docs.victoriametrics.com/#query-tracing
   -downsampling.period array
-     Comma-separated downsampling periods in the format 'offset:period'. For example, '30d:10m' instructs to leave a single sample per 10 minutes for samples older than 30 days. See https://docs.victoriametrics.com/#downsampling for details. This flag is available only in enterprise version of VictoriaMetrics
+     Comma-separated downsampling periods in the format 'offset:period'. For example, '30d:10m' instructs to leave a single sample per 10 minutes for samples older than 30 days. See https://docs.victoriametrics.com/#downsampling for details. This flag is available only in VictoriaMetrics enterprise. See https://docs.victoriametrics.com/enterprise.html
      Supports an array of values separated by comma or specified via multiple flags.
   -dryRun
      Whether to check only -promscrape.config and then exit. Unknown config entries aren't allowed in -promscrape.config by default. This can be changed with -promscrape.config.strictParse=false command-line flag
@@ -2064,7 +2066,7 @@ Pass `-help` to VictoriaMetrics in order to see the list of supported command-li
   -envflag.prefix string
      Prefix for environment variables if -envflag.enable is set
   -eula
-     By specifying this flag, you confirm that you have an enterprise license and accept the EULA https://victoriametrics.com/assets/VM_EULA.pdf . This flag is available only in enterprise version of VictoriaMetrics
+     By specifying this flag, you confirm that you have an enterprise license and accept the EULA https://victoriametrics.com/assets/VM_EULA.pdf . This flag is available only in VictoriaMetrics enterprise. See https://docs.victoriametrics.com/enterprise.html
   -finalMergeDelay duration
      The delay before starting final merge for per-month partition after no new data is ingested into it. Final merge may require additional disk IO and CPU resources. Final merge may increase query speed and reduce disk space usage in some cases. Zero value disables final merge
   -flagsAuthKey string
@@ -2168,7 +2170,7 @@ Pass `-help` to VictoriaMetrics in order to see the list of supported command-li
   -precisionBits int
      The number of precision bits to store per each value. Lower precision bits improves data compression at the cost of precision loss (default 64)
   -prevCacheRemovalPercent float
-     The previous cache is removed when the percent of requests it serves becomes lower than this value. Higher values reduce average memory usage at the cost of higher CPU usage (default 0.2)
+     Items in the previous caches are removed when the percent of requests it serves becomes lower than this value. Higher values reduce memory usage at the cost of higher CPU usage. See also -cacheExpireDuration (default 0.1)
   -promscrape.azureSDCheckInterval duration
      Interval for checking for changes in Azure. This works only if azure_sd_configs is configured in '-promscrape.config' file. See https://docs.victoriametrics.com/sd_configs.html#azure_sd_configs for details (default 1m0s)
   -promscrape.cluster.memberNum string
@@ -2263,7 +2265,7 @@ Pass `-help` to VictoriaMetrics in order to see the list of supported command-li
   -relabelDebug
      Whether to log metrics before and after relabeling with -relabelConfig. If the -relabelDebug is enabled, then the metrics aren't sent to storage. This is useful for debugging the relabeling configs
   -retentionFilter array
-     Retention filter in the format 'filter:retention'. For example, '{env="dev"}:3d' configures the retention for time series with env="dev" label to 3 days. See https://docs.victoriametrics.com/#retention-filters for details. This flag is available only in enterprise version of VictoriaMetrics
+     Retention filter in the format 'filter:retention'. For example, '{env="dev"}:3d' configures the retention for time series with env="dev" label to 3 days. See https://docs.victoriametrics.com/#retention-filters for details. This flag is available only in VictoriaMetrics enterprise. See https://docs.victoriametrics.com/enterprise.html
      Supports an array of values separated by comma or specified via multiple flags.
   -retentionPeriod value
      Data with timestamps outside the retentionPeriod is automatically deleted. See also -retentionFilter
@@ -2277,9 +2279,9 @@ Pass `-help` to VictoriaMetrics in order to see the list of supported command-li
   -search.disableCache
      Whether to disable response caching. This may be useful during data backfilling
   -search.graphiteMaxPointsPerSeries int
-     The maximum number of points per series Graphite render API can return. This flag is available only in enterprise version of VictoriaMetrics (default 1000000)
+     The maximum number of points per series Graphite render API can return. This flag is available only in VictoriaMetrics enterprise. See https://docs.victoriametrics.com/enterprise.html (default 1000000)
   -search.graphiteStorageStep duration
-     The interval between datapoints stored in the database. It is used at Graphite Render API handler for normalizing the interval between datapoints in case it isn't normalized. It can be overridden by sending 'storage_step' query arg to /render API or by sending the desired interval via 'Storage-Step' http header during querying /render API. This flag is available only in enterprise version of VictoriaMetrics (default 10s)
+     The interval between datapoints stored in the database. It is used at Graphite Render API handler for normalizing the interval between datapoints in case it isn't normalized. It can be overridden by sending 'storage_step' query arg to /render API or by sending the desired interval via 'Storage-Step' http header during querying /render API. This flag is available only in VictoriaMetrics enterprise. See https://docs.victoriametrics.com/enterprise.html (default 10s)
   -search.latencyOffset duration
      The time when data points become visible in query results after the collection. Too small value can result in incomplete last points for query results (default 30s)
   -search.logSlowQueryDuration duration
@@ -2293,7 +2295,7 @@ Pass `-help` to VictoriaMetrics in order to see the list of supported command-li
   -search.maxFederateSeries int
      The maximum number of time series, which can be returned from /federate. This option allows limiting memory usage (default 1000000)
   -search.maxGraphiteSeries int
-     The maximum number of time series, which can be scanned during queries to Graphite Render API. See https://docs.victoriametrics.com/#graphite-render-api-usage . This flag is available only in enterprise version of VictoriaMetrics (default 300000)
+     The maximum number of time series, which can be scanned during queries to Graphite Render API. See https://docs.victoriametrics.com/#graphite-render-api-usage . This flag is available only in VictoriaMetrics enterprise. See https://docs.victoriametrics.com/enterprise.html (default 300000)
   -search.maxLookback duration
      Synonym to -search.lookback-delta from Prometheus. The value is dynamically detected from interval between time series datapoints if not set. It can be overridden on per-query basis via max_lookback arg. See also '-search.maxStalenessInterval' flag, which has the same meaining due to historical reasons
   -search.maxMemoryPerQuery size
diff --git a/app/vmagent/README.md b/app/vmagent/README.md
index c98eb2c2d..7514e1167 100644
--- a/app/vmagent/README.md
+++ b/app/vmagent/README.md
@@ -1107,6 +1107,8 @@ vmagent collects metrics data via popular data ingestion protocols and routes th
 
 See the docs at https://docs.victoriametrics.com/vmagent.html .
 
+  -cacheExpireDuration duration
+     Items are removed from in-memory caches after they aren't accessed for this duration. Lower values may reduce memory usage at the cost of higher CPU usage. See also -prevCacheRemovalPercent (default 30m0s)
   -configAuthKey string
      Authorization key for accessing /config page. It must be passed via authKey query arg
   -csvTrimTimestamp duration
@@ -1127,7 +1129,7 @@ See the docs at https://docs.victoriametrics.com/vmagent.html .
   -envflag.prefix string
      Prefix for environment variables if -envflag.enable is set
   -eula
-     By specifying this flag, you confirm that you have an enterprise license and accept the EULA https://victoriametrics.com/assets/VM_EULA.pdf . This flag is available only in enterprise version of VictoriaMetrics
+     By specifying this flag, you confirm that you have an enterprise license and accept the EULA https://victoriametrics.com/assets/VM_EULA.pdf . This flag is available only in VictoriaMetrics enterprise. See https://docs.victoriametrics.com/enterprise.html
   -flagsAuthKey string
      Auth key for /flags endpoint. It must be passed via authKey query arg. It overrides httpAuth.* settings
   -fs.disableMmap
@@ -1178,30 +1180,30 @@ See the docs at https://docs.victoriametrics.com/vmagent.html .
   -insert.maxQueueDuration duration
      The maximum duration for waiting in the queue for insert requests due to -maxConcurrentInserts (default 1m0s)
   -kafka.consumer.topic array
-     Kafka topic names for data consumption. This flag is available only in enterprise version of VictoriaMetrics
+     Kafka topic names for data consumption. This flag is available only in VictoriaMetrics enterprise. See https://docs.victoriametrics.com/enterprise.html
      Supports an array of values separated by comma or specified via multiple flags.
   -kafka.consumer.topic.basicAuth.password array
-     Optional basic auth password for -kafka.consumer.topic. Must be used in conjunction with any supported auth methods for kafka client, specified by flag -kafka.consumer.topic.options='security.protocol=SASL_SSL;sasl.mechanisms=PLAIN' . This flag is available only in enterprise version of VictoriaMetrics
+     Optional basic auth password for -kafka.consumer.topic. Must be used in conjunction with any supported auth methods for kafka client, specified by flag -kafka.consumer.topic.options='security.protocol=SASL_SSL;sasl.mechanisms=PLAIN' . This flag is available only in VictoriaMetrics enterprise. See https://docs.victoriametrics.com/enterprise.html
      Supports an array of values separated by comma or specified via multiple flags.
   -kafka.consumer.topic.basicAuth.username array
-     Optional basic auth username for -kafka.consumer.topic. Must be used in conjunction with any supported auth methods for kafka client, specified by flag -kafka.consumer.topic.options='security.protocol=SASL_SSL;sasl.mechanisms=PLAIN' . This flag is available only in enterprise version of VictoriaMetrics
+     Optional basic auth username for -kafka.consumer.topic. Must be used in conjunction with any supported auth methods for kafka client, specified by flag -kafka.consumer.topic.options='security.protocol=SASL_SSL;sasl.mechanisms=PLAIN' . This flag is available only in VictoriaMetrics enterprise. See https://docs.victoriametrics.com/enterprise.html
      Supports an array of values separated by comma or specified via multiple flags.
   -kafka.consumer.topic.brokers array
-     List of brokers to connect for given topic, e.g. -kafka.consumer.topic.broker=host-1:9092;host-2:9092 . This flag is available only in enterprise version of VictoriaMetrics
+     List of brokers to connect for given topic, e.g. -kafka.consumer.topic.broker=host-1:9092;host-2:9092 . This flag is available only in VictoriaMetrics enterprise. See https://docs.victoriametrics.com/enterprise.html
      Supports an array of values separated by comma or specified via multiple flags.
   -kafka.consumer.topic.defaultFormat string
-     Expected data format in the topic if -kafka.consumer.topic.format is skipped. This flag is available only in enterprise version of VictoriaMetrics (default "promremotewrite")
+     Expected data format in the topic if -kafka.consumer.topic.format is skipped. This flag is available only in VictoriaMetrics enterprise. See https://docs.victoriametrics.com/enterprise.html (default "promremotewrite")
   -kafka.consumer.topic.format array
-     data format for corresponding kafka topic. Valid formats: influx, prometheus, promremotewrite, graphite, jsonline . This flag is available only in enterprise version of VictoriaMetrics
+     data format for corresponding kafka topic. Valid formats: influx, prometheus, promremotewrite, graphite, jsonline . This flag is available only in VictoriaMetrics enterprise. See https://docs.victoriametrics.com/enterprise.html
      Supports an array of values separated by comma or specified via multiple flags.
   -kafka.consumer.topic.groupID array
-     Defines group.id for topic. This flag is available only in enterprise version of VictoriaMetrics
+     Defines group.id for topic. This flag is available only in VictoriaMetrics enterprise. See https://docs.victoriametrics.com/enterprise.html
      Supports an array of values separated by comma or specified via multiple flags.
   -kafka.consumer.topic.isGzipped array
-     Enables gzip setting for topic messages payload. Only prometheus, jsonline and influx formats accept gzipped messages.This flag is available only in enterprise version of VictoriaMetrics
+     Enables gzip setting for topic messages payload. Only prometheus, jsonline and influx formats accept gzipped messages.This flag is available only in VictoriaMetrics enterprise. See https://docs.victoriametrics.com/enterprise.html
      Supports array of values separated by comma or specified via multiple flags.
   -kafka.consumer.topic.options array
-     Optional key=value;key1=value2 settings for topic consumer. See full configuration options at https://github.com/edenhill/librdkafka/blob/master/CONFIGURATION.md . This flag is available only in enterprise version of VictoriaMetrics
+     Optional key=value;key1=value2 settings for topic consumer. See full configuration options at https://github.com/edenhill/librdkafka/blob/master/CONFIGURATION.md . This flag is available only in VictoriaMetrics enterprise. See https://docs.victoriametrics.com/enterprise.html
      Supports an array of values separated by comma or specified via multiple flags.
   -loggerDisableTimestamps
      Whether to disable writing timestamps in logs
@@ -1242,6 +1244,8 @@ See the docs at https://docs.victoriametrics.com/vmagent.html .
      Trim timestamps for OpenTSDB HTTP data to this duration. Minimum practical duration is 1ms. Higher duration (i.e. 1s) may be used for reducing disk space usage for timestamp data (default 1ms)
   -pprofAuthKey string
      Auth key for /debug/pprof/* endpoints. It must be passed via authKey query arg. It overrides httpAuth.* settings
+  -prevCacheRemovalPercent float
+     Items in the previous caches are removed when the percent of requests it serves becomes lower than this value. Higher values reduce memory usage at the cost of higher CPU usage. See also -cacheExpireDuration (default 0.1)
   -promscrape.azureSDCheckInterval duration
      Interval for checking for changes in Azure. This works only if azure_sd_configs is configured in '-promscrape.config' file. See https://docs.victoriametrics.com/sd_configs.html#azure_sd_configs for details (default 1m0s)
   -promscrape.cluster.memberNum string
diff --git a/app/vmalert/README.md b/app/vmalert/README.md
index b356b2f4c..6dcce9d67 100644
--- a/app/vmalert/README.md
+++ b/app/vmalert/README.md
@@ -673,10 +673,12 @@ See full description for these flags in `./vmalert -help`.
 ## Monitoring
 
 `vmalert` exports various metrics in Prometheus exposition format at `http://vmalert-host:8880/metrics` page.
+The default list of alerting rules for these metric can be found [here](https://github.com/VictoriaMetrics/VictoriaMetrics/tree/master/deployment/docker).
 We recommend setting up regular scraping of this page either through `vmagent` or by Prometheus so that the exported
 metrics may be analyzed later.
 
-Use the official [Grafana dashboard](https://grafana.com/grafana/dashboards/14950) for `vmalert` overview. Graphs on this dashboard contain useful hints - hover the `i` icon at the top left corner of each graph in order to read it.
+Use the official [Grafana dashboard](https://grafana.com/grafana/dashboards/14950) for `vmalert` overview. 
+Graphs on this dashboard contain useful hints - hover the `i` icon in the top left corner of each graph in order to read it.
 If you have suggestions for improvements or have found a bug - please open an issue on github or add
 a review to the dashboard.
 
@@ -781,7 +783,7 @@ The shortlist of configuration flags is the following:
 {% raw  %}
 ```
   -clusterMode
-     If clusterMode is enabled, then vmalert automatically adds the tenant specified in config groups to -datasource.url, -remoteWrite.url and -remoteRead.url. See https://docs.victoriametrics.com/vmalert.html#multitenancy . This flag is available only in enterprise version of VictoriaMetrics
+     If clusterMode is enabled, then vmalert automatically adds the tenant specified in config groups to -datasource.url, -remoteWrite.url and -remoteRead.url. See https://docs.victoriametrics.com/vmalert.html#multitenancy . This flag is available only in VictoriaMetrics enterprise. See https://docs.victoriametrics.com/enterprise.html
   -configCheckInterval duration
      Interval for checking for changes in '-rule' or '-notifier.config' files. By default the checking is disabled. Send SIGHUP signal in order to force config check for changes.
   -datasource.appendTypePrefix
@@ -805,11 +807,11 @@ The shortlist of configuration flags is the following:
   -datasource.maxIdleConnections int
      Defines the number of idle (keep-alive connections) to each configured datasource. Consider setting this value equal to the value: groups_total * group.concurrency. Too low a value may result in a high number of sockets in TIME_WAIT state. (default 100)
   -datasource.oauth2.clientID string
-     Optional OAuth2 clientID to use for -datasource.url.
+     Optional OAuth2 clientID to use for -datasource.url. 
   -datasource.oauth2.clientSecret string
      Optional OAuth2 clientSecret to use for -datasource.url.
   -datasource.oauth2.clientSecretFile string
-     Optional OAuth2 clientSecretFile to use for -datasource.url.
+     Optional OAuth2 clientSecretFile to use for -datasource.url. 
   -datasource.oauth2.scopes string
      Optional OAuth2 scopes to use for -datasource.url. Scopes must be delimited by ';'
   -datasource.oauth2.tokenUrl string
@@ -835,9 +837,9 @@ The shortlist of configuration flags is the following:
   -datasource.url string
      Datasource compatible with Prometheus HTTP API. It can be single node VictoriaMetrics or vmselect URL. Required parameter. E.g. http://127.0.0.1:8428 . See also '-datasource.disablePathAppend', '-datasource.showURL'.
   -defaultTenant.graphite string
-     Default tenant for Graphite alerting groups. See https://docs.victoriametrics.com/vmalert.html#multitenancy .This flag is available only in enterprise version of VictoriaMetrics
+     Default tenant for Graphite alerting groups. See https://docs.victoriametrics.com/vmalert.html#multitenancy .This flag is available only in VictoriaMetrics enterprise. See https://docs.victoriametrics.com/enterprise.html
   -defaultTenant.prometheus string
-     Default tenant for Prometheus alerting groups. See https://docs.victoriametrics.com/vmalert.html#multitenancy . This flag is available only in enterprise version of VictoriaMetrics
+     Default tenant for Prometheus alerting groups. See https://docs.victoriametrics.com/vmalert.html#multitenancy . This flag is available only in VictoriaMetrics enterprise. See https://docs.victoriametrics.com/enterprise.html
   -disableAlertgroupLabel
      Whether to disable adding group's Name as label to generated alerts and time series.
   -dryRun
@@ -849,12 +851,11 @@ The shortlist of configuration flags is the following:
   -envflag.prefix string
      Prefix for environment variables if -envflag.enable is set
   -eula
-     By specifying this flag, you confirm that you have an enterprise license and accept the EULA https://victoriametrics.com/assets/VM_EULA.pdf . This flag is available only in enterprise version of VictoriaMetrics
+     By specifying this flag, you confirm that you have an enterprise license and accept the EULA https://victoriametrics.com/assets/VM_EULA.pdf . This flag is available only in VictoriaMetrics enterprise. See https://docs.victoriametrics.com/enterprise.html
   -evaluationInterval duration
      How often to evaluate the rules (default 1m0s)
   -external.alert.source string
-     External Alert Source allows to override the Source link for alerts sent to AlertManager for cases where you want to build a custom link to Grafana, Prometheus or any other service. Supports templating - see https://docs.victoriametrics.com/vmalert.html#templating . For example, link to Grafana: -external.alert.source='explore?orgId=1&left=["now-1h","now","VictoriaMetrics",{"expr":{{$expr|jsonEscape|queryEscape}} },{"mode":"Metrics"},{"ui":[true,true,true,"none"]}]' . If empty 'vmalert/alert?group_id={{.GroupID}}&alert_id={{.AlertID}}' is used
-     If empty 'vmalert/alert?group_id={{.GroupID}}&alert_id={{.AlertID}}' is used.
+     External Alert Source allows to override the Source link for alerts sent to AlertManager for cases where you want to build a custom link to Grafana, Prometheus or any other service. Supports templating - see https://docs.victoriametrics.com/vmalert.html#templating . For example, link to Grafana: -external.alert.source='explore?orgId=1&left=["now-1h","now","VictoriaMetrics",{"expr":{{$expr|jsonEscape|queryEscape}} },{"mode":"Metrics"},{"ui":[true,true,true,"none"]}]' . If empty 'vmalert/alert?group_id={{.GroupID}}&alert_id={{.AlertID}}' is used.
   -external.label array
      Optional label in the form 'Name=value' to add to all generated recording rules and alerts. Pass multiple -label flags in order to add multiple label sets.
      Supports an array of values separated by comma or specified via multiple flags.
@@ -1002,7 +1003,7 @@ The shortlist of configuration flags is the following:
   -remoteRead.oauth2.scopes string
      Optional OAuth2 scopes to use for -remoteRead.url. Scopes must be delimited by ';'.
   -remoteRead.oauth2.tokenUrl string
-     Optional OAuth2 tokenURL to use for -remoteRead.url.
+     Optional OAuth2 tokenURL to use for -remoteRead.url. 
   -remoteRead.showURL
      Whether to show -remoteRead.url in the exported metrics. It is hidden by default, since it can contain sensitive info such as auth key
   -remoteRead.tlsCAFile string
diff --git a/app/vmauth/README.md b/app/vmauth/README.md
index 2fad07707..89e102430 100644
--- a/app/vmauth/README.md
+++ b/app/vmauth/README.md
@@ -239,7 +239,7 @@ See the docs at https://docs.victoriametrics.com/vmauth.html .
   -envflag.prefix string
      Prefix for environment variables if -envflag.enable is set
   -eula
-     By specifying this flag, you confirm that you have an enterprise license and accept the EULA https://victoriametrics.com/assets/VM_EULA.pdf . This flag is available only in enterprise version of VictoriaMetrics
+     By specifying this flag, you confirm that you have an enterprise license and accept the EULA https://victoriametrics.com/assets/VM_EULA.pdf . This flag is available only in VictoriaMetrics enterprise. See https://docs.victoriametrics.com/enterprise.html
   -flagsAuthKey string
      Auth key for /flags endpoint. It must be passed via authKey query arg. It overrides httpAuth.* settings
   -fs.disableMmap
diff --git a/app/vmbackup/README.md b/app/vmbackup/README.md
index b194f9ce9..cfb2f96c1 100644
--- a/app/vmbackup/README.md
+++ b/app/vmbackup/README.md
@@ -196,7 +196,7 @@ See [this article](https://medium.com/@valyala/speeding-up-backups-for-big-time-
   -envflag.prefix string
      Prefix for environment variables if -envflag.enable is set
   -eula
-     By specifying this flag, you confirm that you have an enterprise license and accept the EULA https://victoriametrics.com/assets/VM_EULA.pdf . This flag is available only in enterprise version of VictoriaMetrics
+     By specifying this flag, you confirm that you have an enterprise license and accept the EULA https://victoriametrics.com/assets/VM_EULA.pdf . This flag is available only in VictoriaMetrics enterprise. See https://docs.victoriametrics.com/enterprise.html
   -flagsAuthKey string
      Auth key for /flags endpoint. It must be passed via authKey query arg. It overrides httpAuth.* settings
   -fs.disableMmap
diff --git a/app/vmbackupmanager/README.md b/app/vmbackupmanager/README.md
index 6c12c5c4c..281794ec6 100644
--- a/app/vmbackupmanager/README.md
+++ b/app/vmbackupmanager/README.md
@@ -299,6 +299,13 @@ The shortlist of configuration flags is the following:
 ```
 vmbackupmanager performs regular backups according to the provided configs.
 
+subcommands:
+ backup: provides auxiliary backup-related commands
+ restore: restores backup specified by restore mark if it exists
+
+command-line flags:
+  -apiURL string
+     vmbackupmanager address to perform API requests (default "http://127.0.0.1:8300")
   -concurrency int
      The number of concurrent workers. Higher concurrency may reduce backup duration (default 10)
   -configFilePath string
@@ -328,7 +335,7 @@ vmbackupmanager performs regular backups according to the provided configs.
   -envflag.prefix string
      Prefix for environment variables if -envflag.enable is set
   -eula
-     By specifying this flag, you confirm that you have an enterprise license and accept the EULA https://victoriametrics.com/assets/VM_EULA.pdf . This flag is available only in enterprise version of VictoriaMetrics
+     By specifying this flag, you confirm that you have an enterprise license and accept the EULA https://victoriametrics.com/assets/VM_EULA.pdf . This flag is available only in VictoriaMetrics enterprise. See https://docs.victoriametrics.com/enterprise.html
   -flagsAuthKey string
      Auth key for /flags endpoint. It must be passed via authKey query arg. It overrides httpAuth.* settings
   -fs.disableMmap
@@ -392,8 +399,6 @@ vmbackupmanager performs regular backups according to the provided configs.
   -pushmetrics.url array
      Optional URL to push metrics exposed at /metrics page. See https://docs.victoriametrics.com/#push-metrics . By default metrics exposed at /metrics page aren't pushed to any remote storage
      Supports an array of values separated by comma or specified via multiple flags.
-  -restoreOnStart
-     Check if backup restore was requested and restore requested backup.
   -runOnStart
      Upload backups immediately after start of the service. Otherwise the backup starts on new hour
   -s3ForcePathStyle
diff --git a/app/vmgateway/README.md b/app/vmgateway/README.md
index f32011537..dbfd17cc7 100644
--- a/app/vmgateway/README.md
+++ b/app/vmgateway/README.md
@@ -176,8 +176,8 @@ curl 'http://localhost:8431/api/v1/labels' -H 'Authorization: Bearer eyJhbGciOiJ
 The shortlist of configuration flags include the following:
 
 ```console
-  -auth.httpHeader
-    HTTP header name to look for JWT authorization token
+  -auth.httpHeader string
+     HTTP header name to look for JWT authorization token (default "Authorization")
   -clusterMode
      enable this for the cluster version
   -datasource.appendTypePrefix
@@ -201,17 +201,17 @@ The shortlist of configuration flags include the following:
   -datasource.maxIdleConnections int
      Defines the number of idle (keep-alive connections) to each configured datasource. Consider setting this value equal to the value: groups_total * group.concurrency. Too low a value may result in a high number of sockets in TIME_WAIT state. (default 100)
   -datasource.oauth2.clientID string
-     Optional OAuth2 clientID to use for -datasource.url.
+     Optional OAuth2 clientID to use for -datasource.url. 
   -datasource.oauth2.clientSecret string
      Optional OAuth2 clientSecret to use for -datasource.url.
   -datasource.oauth2.clientSecretFile string
-     Optional OAuth2 clientSecretFile to use for -datasource.url.
+     Optional OAuth2 clientSecretFile to use for -datasource.url. 
   -datasource.oauth2.scopes string
      Optional OAuth2 scopes to use for -datasource.url. Scopes must be delimited by ';'
   -datasource.oauth2.tokenUrl string
      Optional OAuth2 tokenURL to use for -datasource.url.
   -datasource.queryStep duration
-     queryStep defines how far a value can fallback to when evaluating queries. For example, if datasource.queryStep=15s then param "step" with value "15s" will be added to every query.If queryStep isn't specified, rule's evaluationInterval will be used instead.
+     How far a value can fallback to when evaluating queries. For example, if -datasource.queryStep=15s then param "step" with value "15s" will be added to every query. If set to 0, rule's evaluation interval will be used instead. (default 5m0s)
   -datasource.queryTimeAlignment
      Whether to align "time" parameter with evaluation interval.Alignment supposed to produce deterministic results despite of number of vmalert replicas or time they were started. See more details here https://github.com/VictoriaMetrics/VictoriaMetrics/pull/1257 (default true)
   -datasource.roundDigits int
@@ -241,7 +241,7 @@ The shortlist of configuration flags include the following:
   -envflag.prefix string
      Prefix for environment variables if -envflag.enable is set
   -eula
-     By specifying this flag, you confirm that you have an enterprise license and accept the EULA https://victoriametrics.com/assets/VM_EULA.pdf . This flag is available only in enterprise version of VictoriaMetrics
+     By specifying this flag, you confirm that you have an enterprise license and accept the EULA https://victoriametrics.com/assets/VM_EULA.pdf . This flag is available only in VictoriaMetrics enterprise. See https://docs.victoriametrics.com/enterprise.html
   -flagsAuthKey string
      Auth key for /flags endpoint. It must be passed via authKey query arg. It overrides httpAuth.* settings
   -fs.disableMmap
diff --git a/app/vmrestore/README.md b/app/vmrestore/README.md
index e26ca0890..960775d3f 100644
--- a/app/vmrestore/README.md
+++ b/app/vmrestore/README.md
@@ -100,7 +100,7 @@ i.e. the end result would be similar to [rsync --delete](https://askubuntu.com/q
   -envflag.prefix string
      Prefix for environment variables if -envflag.enable is set
   -eula
-     By specifying this flag, you confirm that you have an enterprise license and accept the EULA https://victoriametrics.com/assets/VM_EULA.pdf . This flag is available only in enterprise version of VictoriaMetrics
+     By specifying this flag, you confirm that you have an enterprise license and accept the EULA https://victoriametrics.com/assets/VM_EULA.pdf . This flag is available only in VictoriaMetrics enterprise. See https://docs.victoriametrics.com/enterprise.html
   -flagsAuthKey string
      Auth key for /flags endpoint. It must be passed via authKey query arg. It overrides httpAuth.* settings
   -fs.disableMmap
diff --git a/app/vmselect/netstorage/netstorage.go b/app/vmselect/netstorage/netstorage.go
index f8bf40754..f7c1daca5 100644
--- a/app/vmselect/netstorage/netstorage.go
+++ b/app/vmselect/netstorage/netstorage.go
@@ -1011,7 +1011,10 @@ func ProcessSearchQuery(qt *querytracer.Tracer, sq *storage.SearchQuery, deadlin
 	startTime := time.Now()
 	maxSeriesCount := sr.Init(qt, vmstorage.Storage, tfss, tr, sq.MaxMetrics, deadline.Deadline())
 	indexSearchDuration.UpdateDuration(startTime)
-	m := make(map[string][]blockRef, maxSeriesCount)
+	type blockRefs struct {
+		brs []blockRef
+	}
+	m := make(map[string]*blockRefs, maxSeriesCount)
 	orderedMetricNames := make([]string, 0, maxSeriesCount)
 	blocksRead := 0
 	samples := 0
@@ -1040,13 +1043,14 @@ func ProcessSearchQuery(qt *querytracer.Tracer, sq *storage.SearchQuery, deadlin
 		}
 		metricName := sr.MetricBlockRef.MetricName
 		brs := m[string(metricName)]
-		brs = append(brs, blockRef{
+		if brs == nil {
+			brs = &blockRefs{}
+		}
+		brs.brs = append(brs.brs, blockRef{
 			partRef: br.PartRef(),
 			addr:    addr,
 		})
-		if len(brs) > 1 {
-			m[string(metricName)] = brs
-		} else {
+		if len(brs.brs) == 1 {
 			// An optimization for big number of time series with long metricName values:
 			// use only a single copy of metricName for both orderedMetricNames and m.
 			orderedMetricNames = append(orderedMetricNames, string(metricName))
@@ -1075,7 +1079,7 @@ func ProcessSearchQuery(qt *querytracer.Tracer, sq *storage.SearchQuery, deadlin
 	for i, metricName := range orderedMetricNames {
 		pts[i] = packedTimeseries{
 			metricName: metricName,
-			brs:        m[metricName],
+			brs:        m[metricName].brs,
 		}
 	}
 	rss.packedTimeseries = pts
diff --git a/app/vmselect/promql/eval.go b/app/vmselect/promql/eval.go
index a0afdef0b..1118de005 100644
--- a/app/vmselect/promql/eval.go
+++ b/app/vmselect/promql/eval.go
@@ -488,6 +488,12 @@ func execBinaryOpArgs(qt *querytracer.Tracer, ec *EvalConfig, exprFirst, exprSec
 	if err != nil {
 		return nil, nil, err
 	}
+	if len(tssFirst) == 0 && strings.ToLower(be.Op) != "or" {
+		// Fast path: there is no sense in executing the exprSecond when exprFirst returns an empty result,
+		// since the "exprFirst op exprSecond" would return an empty result in any case.
+		// See https://github.com/VictoriaMetrics/VictoriaMetrics/issues/3349
+		return nil, nil, nil
+	}
 	lfs := getCommonLabelFilters(tssFirst)
 	lfs = metricsql.TrimFiltersByGroupModifier(lfs, be)
 	exprSecond = metricsql.PushdownBinaryOpFilters(exprSecond, lfs)
diff --git a/app/vmselect/promql/transform.go b/app/vmselect/promql/transform.go
index 8b3f8d338..f4d151295 100644
--- a/app/vmselect/promql/transform.go
+++ b/app/vmselect/promql/transform.go
@@ -91,6 +91,7 @@ var transformFuncs = map[string]transformFunc{
 	"range_linear_regression":    transformRangeLinearRegression,
 	"range_max":                  newTransformFuncRange(runningMax),
 	"range_min":                  newTransformFuncRange(runningMin),
+	"range_normalize":            transformRangeNormalize,
 	"range_quantile":             transformRangeQuantile,
 	"range_stddev":               transformRangeStddev,
 	"range_stdvar":               transformRangeStdvar,
@@ -142,6 +143,7 @@ var transformFuncsKeepMetricName = map[string]bool{
 	"range_linear_regression": true,
 	"range_max":               true,
 	"range_min":               true,
+	"range_normalize":         true,
 	"range_quantile":          true,
 	"range_stdvar":            true,
 	"range_sddev":             true,
@@ -1240,6 +1242,38 @@ func newTransformFuncRange(rf func(a, b float64, idx int) float64) transformFunc
 	}
 }
 
+func transformRangeNormalize(tfa *transformFuncArg) ([]*timeseries, error) {
+	args := tfa.args
+	var rvs []*timeseries
+	for _, tss := range args {
+		for _, ts := range tss {
+			values := ts.Values
+			vMin := inf
+			vMax := -inf
+			for _, v := range values {
+				if math.IsNaN(v) {
+					continue
+				}
+				if v < vMin {
+					vMin = v
+				}
+				if v > vMax {
+					vMax = v
+				}
+			}
+			d := vMax - vMin
+			if math.IsInf(d, 0) {
+				continue
+			}
+			for i, v := range values {
+				values[i] = (v - vMin) / d
+			}
+			rvs = append(rvs, ts)
+		}
+	}
+	return rvs, nil
+}
+
 func transformRangeLinearRegression(tfa *transformFuncArg) ([]*timeseries, error) {
 	args := tfa.args
 	if err := expectTransformArgsNum(args, 1); err != nil {
@@ -1943,6 +1977,8 @@ func transformLimitOffset(tfa *transformFuncArg) ([]*timeseries, error) {
 	rvs := removeEmptySeries(args[2])
 	if len(rvs) >= offset {
 		rvs = rvs[offset:]
+	} else {
+		rvs = nil
 	}
 	if len(rvs) > limit {
 		rvs = rvs[:limit]
diff --git a/app/vmui/packages/vmui/src/components/Chart/ChartTooltip/ChartTooltip.tsx b/app/vmui/packages/vmui/src/components/Chart/ChartTooltip/ChartTooltip.tsx
new file mode 100644
index 000000000..099771946
--- /dev/null
+++ b/app/vmui/packages/vmui/src/components/Chart/ChartTooltip/ChartTooltip.tsx
@@ -0,0 +1,181 @@
+import React, { FC, useEffect, useMemo, useRef, useState } from "preact/compat";
+import uPlot, { Series } from "uplot";
+import { MetricResult } from "../../../api/types";
+import { formatPrettyNumber, getColorLine, getLegendLabel } from "../../../utils/uplot/helpers";
+import dayjs from "dayjs";
+import { DATE_FULL_TIMEZONE_FORMAT } from "../../../constants/date";
+import ReactDOM from "react-dom";
+import get from "lodash.get";
+import Button from "../../Main/Button/Button";
+import { CloseIcon, DragIcon } from "../../Main/Icons";
+import classNames from "classnames";
+import { MouseEvent as ReactMouseEvent } from "react";
+import "./style.scss";
+
+export interface ChartTooltipProps {
+  id: string,
+  u: uPlot,
+  metrics: MetricResult[],
+  series: Series[],
+  unit?: string,
+  isSticky?: boolean,
+  tooltipOffset: { left: number, top: number },
+  tooltipIdx: { seriesIdx: number, dataIdx: number },
+  onClose?: (id: string) => void
+}
+
+const ChartTooltip: FC<ChartTooltipProps> = ({
+  u,
+  id,
+  unit = "",
+  metrics,
+  series,
+  tooltipIdx,
+  tooltipOffset,
+  isSticky,
+  onClose
+}) => {
+  const tooltipRef = useRef<HTMLDivElement>(null);
+
+  const [position, setPosition] = useState({ top: -999, left: -999 });
+  const [moving, setMoving] = useState(false);
+  const [moved, setMoved] = useState(false);
+
+  const [seriesIdx, setSeriesIdx] = useState(tooltipIdx.seriesIdx);
+  const [dataIdx, setDataIdx] = useState(tooltipIdx.dataIdx);
+
+  const targetPortal = useMemo(() => u.root.querySelector(".u-wrap"), [u]);
+
+  const value = useMemo(() => get(u, ["data", seriesIdx, dataIdx], 0), [u, seriesIdx, dataIdx]);
+  const valueFormat = useMemo(() => formatPrettyNumber(value), [value]);
+  const dataTime = useMemo(() => u.data[0][dataIdx], [u, dataIdx]);
+  const date = useMemo(() => dayjs(new Date(dataTime * 1000)).format(DATE_FULL_TIMEZONE_FORMAT), [dataTime]);
+
+  const color = useMemo(() => getColorLine(series[seriesIdx]?.label || ""), [series, seriesIdx]);
+
+  const name = useMemo(() => {
+    const metricName = (series[seriesIdx]?.label || "").replace(/{.+}/gmi, "").trim();
+    return getLegendLabel(metricName);
+  }, []);
+
+  const fields = useMemo(() => {
+    const metric = metrics[seriesIdx - 1]?.metric || {};
+    const fields = Object.keys(metric).filter(k => k !== "__name__");
+    return fields.map(key => `${key}="${metric[key]}"`);
+  }, [metrics, seriesIdx]);
+
+  const handleClose = () => {
+    onClose && onClose(id);
+  };
+
+  const handleMouseDown = (e: ReactMouseEvent<HTMLButtonElement, MouseEvent>) => {
+    setMoved(true);
+    setMoving(true);
+    const { clientX, clientY } = e;
+    setPosition({ top: clientY, left: clientX });
+  };
+
+  const handleMouseMove = (e: MouseEvent) => {
+    if (!moving) return;
+    const { clientX, clientY } = e;
+    setPosition({ top: clientY, left: clientX });
+  };
+
+  const handleMouseUp = () => {
+    setMoving(false);
+  };
+
+  const calcPosition = () => {
+    if (!tooltipRef.current) return;
+
+    const topOnChart = u.valToPos((value || 0), series[seriesIdx]?.scale || "1");
+    const leftOnChart = u.valToPos(dataTime, "x");
+    const { width: tooltipWidth, height: tooltipHeight } = tooltipRef.current.getBoundingClientRect();
+    const { width, height } = u.over.getBoundingClientRect();
+
+    const margin = 10;
+    const overflowX = leftOnChart + tooltipWidth >= width ? tooltipWidth + (2 * margin) : 0;
+    const overflowY = topOnChart + tooltipHeight >= height ? tooltipHeight + (2 * margin) : 0;
+
+    setPosition({
+      top: topOnChart + tooltipOffset.top + margin - overflowY,
+      left: leftOnChart + tooltipOffset.left + margin - overflowX
+    });
+  };
+
+  useEffect(calcPosition, [u, value, dataTime, seriesIdx, tooltipOffset, tooltipRef]);
+
+  useEffect(() => {
+    setSeriesIdx(tooltipIdx.seriesIdx);
+    setDataIdx(tooltipIdx.dataIdx);
+  }, [tooltipIdx]);
+
+  useEffect(() => {
+    if (moving) {
+      document.addEventListener("mousemove", handleMouseMove);
+      document.addEventListener("mouseup", handleMouseUp);
+    }
+
+    return () => {
+      document.removeEventListener("mousemove", handleMouseMove);
+      document.removeEventListener("mouseup", handleMouseUp);
+    };
+  }, [moving]);
+
+  if (!targetPortal || tooltipIdx.seriesIdx < 0 || tooltipIdx.dataIdx < 0) return null;
+
+  return ReactDOM.createPortal((
+    <div
+      className={classNames({
+        "vm-chart-tooltip": true,
+        "vm-chart-tooltip_sticky": isSticky,
+        "vm-chart-tooltip_moved": moved
+
+      })}
+      ref={tooltipRef}
+      style={position}
+    >
+      <div className="vm-chart-tooltip-header">
+        <div className="vm-chart-tooltip-header__date">{date}</div>
+        {isSticky && (
+          <>
+            <Button
+              className="vm-chart-tooltip-header__drag"
+              variant="text"
+              size="small"
+              startIcon={<DragIcon/>}
+              onMouseDown={handleMouseDown}
+            />
+            <Button
+              className="vm-chart-tooltip-header__close"
+              variant="text"
+              size="small"
+              startIcon={<CloseIcon/>}
+              onClick={handleClose}
+            />
+          </>
+        )}
+      </div>
+      <div className="vm-chart-tooltip-data">
+        <div
+          className="vm-chart-tooltip-data__marker"
+          style={{ background: color }}
+        />
+        <p>
+          {name}:
+          <b className="vm-chart-tooltip-data__value">{valueFormat}</b>
+          {unit}
+        </p>
+      </div>
+      {!!fields.length && (
+        <div className="vm-chart-tooltip-info">
+          {fields.map((f, i) => (
+            <div key={`${f}_${i}`}>{f}</div>
+          ))}
+        </div>
+      )}
+    </div>
+  ), targetPortal);
+};
+
+export default ChartTooltip;
diff --git a/app/vmui/packages/vmui/src/components/Chart/ChartTooltip/style.scss b/app/vmui/packages/vmui/src/components/Chart/ChartTooltip/style.scss
new file mode 100644
index 000000000..9c8cedc94
--- /dev/null
+++ b/app/vmui/packages/vmui/src/components/Chart/ChartTooltip/style.scss
@@ -0,0 +1,77 @@
+@use "src/styles/variables" as *;
+$chart-tooltip-width: 300px;
+$chart-tooltip-icon-width: 25px;
+$chart-tooltip-date-width: $chart-tooltip-width - (2*$chart-tooltip-icon-width) - (2*$padding-global) - $padding-small;
+$chart-tooltip-x: -1 * ($padding-small + $padding-global + $chart-tooltip-date-width + ($chart-tooltip-icon-width/2));
+$chart-tooltip-y: -1 * ($padding-small + ($chart-tooltip-icon-width/2));
+
+.vm-chart-tooltip {
+  position: absolute;
+  display: grid;
+  gap: $padding-global;
+  width: $chart-tooltip-width;
+  padding: $padding-small;
+  border-radius: $border-radius-medium;
+  background: $color-background-tooltip;
+  color: $color-white;
+  font-size: $font-size-small;
+  font-weight: normal;
+  line-height: 150%;
+  word-wrap: break-word;
+  font-family: $font-family-monospace;
+  z-index: 98;
+  user-select: text;
+  pointer-events: none;
+
+  &_sticky {
+    background-color: $color-dove-gray;
+    pointer-events: auto;
+    z-index: 99;
+  }
+
+  &_moved {
+    position: fixed;
+    margin-top: $chart-tooltip-y;
+    margin-left: $chart-tooltip-x;
+  }
+
+  &-header {
+    display: grid;
+    grid-template-columns: 1fr $chart-tooltip-icon-width $chart-tooltip-icon-width;
+    gap: $padding-small;
+    align-items: center;
+    justify-content: center;
+    min-height: 25px;
+
+    &__close {
+      color: $color-white;
+    }
+
+    &__drag {
+      color: $color-white;
+      cursor: move;
+    }
+  }
+
+  &-data {
+    display: flex;
+    flex-wrap: wrap;
+    align-items: center;
+
+    &__value {
+      padding: 4px;
+      font-weight: bold;
+    }
+
+    &__marker {
+      width: 12px;
+      height: 12px;
+      margin-right: $padding-small;
+    }
+  }
+
+  &-info {
+    display: grid;
+    grid-gap: 4px;
+  }
+}
diff --git a/app/vmui/packages/vmui/src/components/Chart/LineChart/LineChart.tsx b/app/vmui/packages/vmui/src/components/Chart/LineChart/LineChart.tsx
index b8c37503f..1e7e4ff7c 100644
--- a/app/vmui/packages/vmui/src/components/Chart/LineChart/LineChart.tsx
+++ b/app/vmui/packages/vmui/src/components/Chart/LineChart/LineChart.tsx
@@ -1,9 +1,15 @@
-import React, { FC, useCallback, useEffect, useRef, useState } from "preact/compat";
-import uPlot, { AlignedData as uPlotData, Options as uPlotOptions, Series as uPlotSeries, Range, Scales, Scale } from "uplot";
+import React, { FC, useCallback, useEffect, useMemo, useRef, useState } from "preact/compat";
+import uPlot, {
+  AlignedData as uPlotData,
+  Options as uPlotOptions,
+  Series as uPlotSeries,
+  Range,
+  Scales,
+  Scale,
+} from "uplot";
 import { defaultOptions } from "../../../utils/uplot/helpers";
 import { dragChart } from "../../../utils/uplot/events";
 import { getAxes, getMinMaxBuffer } from "../../../utils/uplot/axes";
-import { setTooltip } from "../../../utils/uplot/tooltip";
 import { MetricResult } from "../../../api/types";
 import { limitsDurations } from "../../../utils/time";
 import throttle from "lodash.throttle";
@@ -13,6 +19,7 @@ import { YaxisState } from "../../../state/graph/reducer";
 import "uplot/dist/uPlot.min.css";
 import "./style.scss";
 import classNames from "classnames";
+import ChartTooltip, { ChartTooltipProps } from "../ChartTooltip/ChartTooltip";
 
 export interface LineChartProps {
   metrics: MetricResult[];
@@ -24,21 +31,30 @@ export interface LineChartProps {
   setPeriod: ({ from, to }: {from: Date, to: Date}) => void;
   container: HTMLDivElement | null
 }
-enum typeChartUpdate {xRange = "xRange", yRange = "yRange", data = "data"}
 
-const LineChart: FC<LineChartProps> = ({ data, series, metrics = [],
-  period, yaxis, unit, setPeriod, container }) => {
+enum typeChartUpdate {xRange = "xRange", yRange = "yRange", data = "data"}
 
+const LineChart: FC<LineChartProps> = ({
+  data,
+  series,
+  metrics = [],
+  period,
+  yaxis,
+  unit,
+  setPeriod,
+  container
+}) => {
   const uPlotRef = useRef<HTMLDivElement>(null);
   const [isPanning, setPanning] = useState(false);
   const [xRange, setXRange] = useState({ min: period.start, max: period.end });
   const [uPlotInst, setUPlotInst] = useState<uPlot>();
   const layoutSize = useResize(container);
 
-  const tooltip = document.createElement("div");
-  tooltip.className = "u-tooltip";
-  const tooltipIdx: {seriesIdx: number | null, dataIdx: number | undefined} = { seriesIdx: null, dataIdx: undefined };
-  const tooltipOffset = { left: 0, top: 0 };
+  const [showTooltip, setShowTooltip] = useState(false);
+  const [tooltipIdx, setTooltipIdx] = useState({ seriesIdx: -1, dataIdx: -1 });
+  const [tooltipOffset, setTooltipOffset] = useState({ left: 0, top: 0 });
+  const [stickyTooltips, setStickyToolTips] = useState<ChartTooltipProps[]>([]);
+  const tooltipId = useMemo(() => `${tooltipIdx.seriesIdx}_${tooltipIdx.dataIdx}`, [tooltipIdx]);
 
   const setScale = ({ min, max }: { min: number, max: number }): void => {
     setPeriod({ from: new Date(min * 1000), to: new Date(max * 1000) });
@@ -54,12 +70,13 @@ const LineChart: FC<LineChartProps> = ({ data, series, metrics = [],
 
   const onReadyChart = (u: uPlot) => {
     const factor = 0.9;
-    tooltipOffset.left = parseFloat(u.over.style.left);
-    tooltipOffset.top = parseFloat(u.over.style.top);
-    u.root.querySelector(".u-wrap")?.appendChild(tooltip);
+    setTooltipOffset({
+      left: parseFloat(u.over.style.left),
+      top: parseFloat(u.over.style.top)
+    });
     u.over.addEventListener("mousedown", e => {
-      const { ctrlKey, metaKey } = e;
-      const leftClick = e.button === 0;
+      const { ctrlKey, metaKey, button } = e;
+      const leftClick = button === 0;
       const leftClickWithMeta = leftClick && (ctrlKey || metaKey);
       if (leftClickWithMeta) {
         // drag pan
@@ -98,21 +115,37 @@ const LineChart: FC<LineChartProps> = ({ data, series, metrics = [],
     }
   };
 
-  const setCursor = (u: uPlot) => {
-    if (tooltipIdx.dataIdx === u.cursor.idx) return;
-    tooltipIdx.dataIdx = u.cursor.idx || 0;
-    if (tooltipIdx.seriesIdx !== null && tooltipIdx.dataIdx !== undefined) {
-      setTooltip({ u, tooltipIdx, metrics, series, tooltip, tooltipOffset, unit });
+  const handleClick = () => {
+    const id = `${tooltipIdx.seriesIdx}_${tooltipIdx.dataIdx}`;
+    const props = {
+      id,
+      unit,
+      series,
+      metrics,
+      tooltipIdx,
+      tooltipOffset,
+    };
+
+    if (!stickyTooltips.find(t => t.id === id)) {
+      const tooltipProps = JSON.parse(JSON.stringify(props));
+      setStickyToolTips(prev => [...prev, tooltipProps]);
     }
   };
 
+  const handleUnStick = (id:string) => {
+    setStickyToolTips(prev => prev.filter(t => t.id !== id));
+  };
+
+  const setCursor = (u: uPlot) => {
+    const dataIdx = u.cursor.idx ?? -1;
+    setTooltipIdx(prev => ({ ...prev, dataIdx }));
+  };
+
   const seriesFocus = (u: uPlot, sidx: (number | null)) => {
-    if (tooltipIdx.seriesIdx === sidx) return;
-    tooltipIdx.seriesIdx = sidx;
-    sidx && tooltipIdx.dataIdx !== undefined
-      ? setTooltip({ u, tooltipIdx, metrics, series, tooltip, tooltipOffset, unit })
-      : tooltip.style.display = "none";
+    const seriesIdx = sidx ?? -1;
+    setTooltipIdx(prev => ({ ...prev, seriesIdx }));
   };
+
   const getRangeX = (): Range.MinMax => [xRange.min, xRange.max];
   const getRangeY = (u: uPlot, min = 0, max = 1, axis: string): Range.MinMax => {
     if (yaxis.limits.enable) return yaxis.limits.range[axis];
@@ -168,6 +201,8 @@ const LineChart: FC<LineChartProps> = ({ data, series, metrics = [],
   useEffect(() => setXRange({ min: period.start, max: period.end }), [period]);
 
   useEffect(() => {
+    setStickyToolTips([]);
+    setTooltipIdx({ seriesIdx: -1, dataIdx: -1 });
     if (!uPlotRef.current) return;
     const u = new uPlot(options, data, uPlotRef.current);
     setUPlotInst(u);
@@ -187,6 +222,17 @@ const LineChart: FC<LineChartProps> = ({ data, series, metrics = [],
   useEffect(() => updateChart(typeChartUpdate.xRange), [xRange]);
   useEffect(() => updateChart(typeChartUpdate.yRange), [yaxis]);
 
+  useEffect(() => {
+    const show = tooltipIdx.dataIdx !== -1 && tooltipIdx.seriesIdx !== -1;
+    setShowTooltip(show);
+
+    if (show) window.addEventListener("click", handleClick);
+
+    return () => {
+      window.removeEventListener("click", handleClick);
+    };
+  }, [tooltipIdx, stickyTooltips]);
+
   return (
     <div
       className={classNames({
@@ -194,7 +240,31 @@ const LineChart: FC<LineChartProps> = ({ data, series, metrics = [],
         "vm-line-chart_panning": isPanning
       })}
     >
-      <div ref={uPlotRef}/>
+      <div
+        className="vm-line-chart__u-plot"
+        ref={uPlotRef}
+      />
+      {uPlotInst && showTooltip && (
+        <ChartTooltip
+          unit={unit}
+          u={uPlotInst}
+          series={series}
+          metrics={metrics}
+          tooltipIdx={tooltipIdx}
+          tooltipOffset={tooltipOffset}
+          id={tooltipId}
+        />
+      )}
+
+      {uPlotInst && stickyTooltips.map(t => (
+        <ChartTooltip
+          {...t}
+          isSticky
+          u={uPlotInst}
+          key={t.id}
+          onClose={handleUnStick}
+        />
+      ))}
     </div>
   );
 };
diff --git a/app/vmui/packages/vmui/src/components/Chart/LineChart/style.scss b/app/vmui/packages/vmui/src/components/Chart/LineChart/style.scss
index d1b3b26de..30186608f 100644
--- a/app/vmui/packages/vmui/src/components/Chart/LineChart/style.scss
+++ b/app/vmui/packages/vmui/src/components/Chart/LineChart/style.scss
@@ -7,45 +7,8 @@
   &_panning {
     pointer-events: none;
   }
-}
-
-.u-tooltip {
-  position: absolute;
-  display: none;
-  grid-gap: $padding-global;
-  max-width: 300px;
-  padding: $padding-small;
-  border-radius: $border-radius-medium;
-  background: $color-background-tooltip;
-  color: $color-white;
-  font-size: $font-size-small;
-  font-weight: normal;
-  line-height: 1.4;
-  word-wrap: break-word;
-  font-family: monospace;
-  pointer-events: none;
-  z-index: 100;
-
-  &-data {
-    display: flex;
-    flex-wrap: wrap;
-    align-items: center;
-    line-height: 150%;
-
-    &__value {
-      padding: 4px;
-      font-weight: bold;
-    }
-  }
-
-  &__info {
-    display: grid;
-    grid-gap: 4px;
-  }
 
-  &__marker {
-    width: 12px;
-    height: 12px;
-    margin-right: $padding-small;
+  &__u-plot {
+    position: relative;
   }
 }
diff --git a/app/vmui/packages/vmui/src/components/Configurators/QueryEditor/QueryEditor.tsx b/app/vmui/packages/vmui/src/components/Configurators/QueryEditor/QueryEditor.tsx
index 0fb1b13d9..6dec9e180 100644
--- a/app/vmui/packages/vmui/src/components/Configurators/QueryEditor/QueryEditor.tsx
+++ b/app/vmui/packages/vmui/src/components/Configurators/QueryEditor/QueryEditor.tsx
@@ -41,7 +41,6 @@ const QueryEditor: FC<QueryEditorProps> = ({
   const wrapperEl = useRef<HTMLDivElement>(null);
 
   const foundOptions = useMemo(() => {
-    setFocusOption(0);
     if (!openAutocomplete) return [];
     try {
       const regexp = new RegExp(String(value), "i");
@@ -50,7 +49,11 @@ const QueryEditor: FC<QueryEditorProps> = ({
     } catch (e) {
       return [];
     }
-  }, [openAutocomplete, options]);
+  }, [openAutocomplete, options, value]);
+
+  const handleCloseAutocomplete = () => {
+    setOpenAutocomplete(false);
+  };
 
   const handleKeyDown = (e: KeyboardEvent) => {
     const { key, ctrlKey, metaKey, shiftKey } = e;
@@ -59,8 +62,10 @@ const QueryEditor: FC<QueryEditorProps> = ({
     const arrowUp = key === "ArrowUp";
     const arrowDown = key === "ArrowDown";
     const enter = key === "Enter";
+    const escape = key === "Escape";
 
     const hasAutocomplete = openAutocomplete && foundOptions.length;
+    const valueAutocomplete = foundOptions[focusOption];
 
     const isArrows = arrowUp || arrowDown;
     const arrowsByOptions = isArrows && hasAutocomplete;
@@ -86,17 +91,19 @@ const QueryEditor: FC<QueryEditorProps> = ({
     }
 
     // Enter
-    if (enter && hasAutocomplete && !shiftKey && !ctrlMetaKey) {
+    if (valueAutocomplete && enter && hasAutocomplete && !shiftKey && !ctrlMetaKey) {
       if (disabled) return;
-      onChange(foundOptions[focusOption]);
-      setOpenAutocomplete(false);
+      onChange(valueAutocomplete);
+      handleCloseAutocomplete();
     } else if (enter && !shiftKey) {
       onEnter();
+      handleCloseAutocomplete();
     }
-  };
 
-  const handleCloseAutocomplete = () => {
-    setOpenAutocomplete(false);
+    // Escape
+    if (escape && openAutocomplete) {
+      handleCloseAutocomplete();
+    }
   };
 
   const createHandlerOnChangeAutocomplete = (item: string) => () => {
@@ -106,9 +113,11 @@ const QueryEditor: FC<QueryEditorProps> = ({
   };
 
   useEffect(() => {
+    if (!autocomplete || !foundOptions.length) return;
+    setFocusOption(-1);
     const words = (value.match(/[a-zA-Z_:.][a-zA-Z0-9_:.]*/gm) || []).length;
     setOpenAutocomplete(autocomplete && value.length > 2 && words <= 1);
-  }, [autocomplete, value]);
+  }, [autocomplete, value, foundOptions]);
 
   useEffect(() => {
     if (!wrapperEl.current) return;
@@ -116,7 +125,7 @@ const QueryEditor: FC<QueryEditorProps> = ({
     if (target?.scrollIntoView) target.scrollIntoView({ block: "center" });
   }, [focusOption]);
 
-  useClickOutside(autocompleteAnchorEl, () => setOpenAutocomplete(false), wrapperEl);
+  useClickOutside(autocompleteAnchorEl, handleCloseAutocomplete, wrapperEl);
 
   return <div
     className="vm-query-editor"
diff --git a/app/vmui/packages/vmui/src/components/Main/Button/Button.tsx b/app/vmui/packages/vmui/src/components/Main/Button/Button.tsx
index 09d5c9edd..ad54f6168 100644
--- a/app/vmui/packages/vmui/src/components/Main/Button/Button.tsx
+++ b/app/vmui/packages/vmui/src/components/Main/Button/Button.tsx
@@ -14,6 +14,7 @@ interface ButtonProps {
   children?: ReactNode
   className?: string
   onClick?: (e: ReactMouseEvent<HTMLButtonElement, MouseEvent>) => void
+  onMouseDown?: (e: ReactMouseEvent<HTMLButtonElement, MouseEvent>) => void
 }
 
 const Button: FC<ButtonProps> = ({
@@ -27,6 +28,7 @@ const Button: FC<ButtonProps> = ({
   className,
   disabled,
   onClick,
+  onMouseDown,
 }) => {
 
   const classesButton = classNames({
@@ -45,6 +47,7 @@ const Button: FC<ButtonProps> = ({
       className={classesButton}
       disabled={disabled}
       onClick={onClick}
+      onMouseDown={onMouseDown}
     >
       <>
         {startIcon && <span className="vm-button__start-icon">{startIcon}</span>}
diff --git a/app/vmui/packages/vmui/src/components/Main/Icons/index.tsx b/app/vmui/packages/vmui/src/components/Main/Icons/index.tsx
index 68ab7a9bf..cd7ea24dc 100644
--- a/app/vmui/packages/vmui/src/components/Main/Icons/index.tsx
+++ b/app/vmui/packages/vmui/src/components/Main/Icons/index.tsx
@@ -300,3 +300,12 @@ export const CopyIcon = () => (
     ></path>
   </svg>
 );
+
+export const DragIcon = () => (
+  <svg
+    viewBox="0 0 24 24"
+    fill="currentColor"
+  >
+    <path d="M20 9H4v2h16V9zM4 15h16v-2H4v2z"></path>
+  </svg>
+);
diff --git a/app/vmui/packages/vmui/src/components/Main/TextField/style.scss b/app/vmui/packages/vmui/src/components/Main/TextField/style.scss
index a73074cf0..dab69b89e 100644
--- a/app/vmui/packages/vmui/src/components/Main/TextField/style.scss
+++ b/app/vmui/packages/vmui/src/components/Main/TextField/style.scss
@@ -29,6 +29,7 @@
   &__helper-text, {
     position: absolute;
     left: calc($padding-global/2);
+    max-width: calc(100% - $padding-global);
     padding: 0 3px;
     font-size: $font-size-small;
     line-height: $font-size-small;
@@ -36,6 +37,12 @@
     user-select: none;
     background-color: $color-background-block;
     z-index: 2;
+    overflow: hidden;
+    text-overflow: ellipsis;
+    display: -webkit-box;
+    -webkit-line-clamp: 2; /* number of lines to show */
+    line-clamp: 2;
+    -webkit-box-orient: vertical;
   }
 
   &__label {
@@ -44,7 +51,7 @@
   }
 
   &__error {
-    bottom: calc($font-size-small/-2);
+    top: calc(100% - ($font-size-small/2));
     color: $color-error;
   }
 
diff --git a/app/vmui/packages/vmui/src/hooks/useFetchQuery.ts b/app/vmui/packages/vmui/src/hooks/useFetchQuery.ts
index bfd7953b2..781530d5f 100644
--- a/app/vmui/packages/vmui/src/hooks/useFetchQuery.ts
+++ b/app/vmui/packages/vmui/src/hooks/useFetchQuery.ts
@@ -20,7 +20,7 @@ interface FetchQueryParams {
   hideQuery?: number[]
 }
 
-export const useFetchQuery = ({ predefinedQuery, visible, display, customStep, hideQuery = [] }: FetchQueryParams): {
+export const useFetchQuery = ({ predefinedQuery, visible, display, customStep, hideQuery }: FetchQueryParams): {
   fetchUrl?: string[],
   isLoading: boolean,
   graphData?: MetricResult[],
@@ -101,6 +101,12 @@ export const useFetchQuery = ({ predefinedQuery, visible, display, customStep, h
 
   const throttledFetchData = useCallback(debounce(fetchData, 800), []);
 
+  const filterExpr = (q: string, i: number) => {
+    const byQuery = q.trim();
+    const byHideQuery = hideQuery ? !hideQuery.includes(i) : true;
+    return byQuery && byHideQuery;
+  };
+
   const fetchUrl = useMemo(() => {
     const expr = predefinedQuery ?? query;
     const displayChart = (display || displayType) === "chart";
@@ -112,7 +118,7 @@ export const useFetchQuery = ({ predefinedQuery, visible, display, customStep, h
     } else if (isValidHttpUrl(serverUrl)) {
       const updatedPeriod = { ...period };
       updatedPeriod.step = customStep;
-      return expr.filter((q, i) => q.trim() && !hideQuery.includes(i)).map(q => displayChart
+      return expr.filter(filterExpr).map(q => displayChart
         ? getQueryRangeUrl(serverUrl, q, updatedPeriod, nocache, isTracingEnabled)
         : getQueryUrl(serverUrl, q, updatedPeriod, isTracingEnabled));
     } else {
diff --git a/app/vmui/packages/vmui/src/state/customPanel/reducer.ts b/app/vmui/packages/vmui/src/state/customPanel/reducer.ts
index cc28d05dc..55b12528c 100644
--- a/app/vmui/packages/vmui/src/state/customPanel/reducer.ts
+++ b/app/vmui/packages/vmui/src/state/customPanel/reducer.ts
@@ -1,5 +1,4 @@
 import { DisplayType, displayTypeTabs } from "../../pages/CustomPanel/DisplayTypeSwitch";
-import { getFromStorage, saveToStorage } from "../../utils/storage";
 import { getQueryStringValue } from "../../utils/query-string";
 
 export interface CustomPanelState {
@@ -18,8 +17,8 @@ const displayType = displayTypeTabs.find(t => t.prometheusCode === +queryTab ||
 
 export const initialCustomPanelState: CustomPanelState = {
   displayType: (displayType?.value || "chart") as DisplayType,
-  nocache: getFromStorage("NO_CACHE") as boolean || false,
-  isTracingEnabled: getFromStorage("QUERY_TRACING") as boolean || false,
+  nocache: false,
+  isTracingEnabled: false,
 };
 
 export function reducer(state: CustomPanelState, action: CustomPanelAction): CustomPanelState {
@@ -30,14 +29,12 @@ export function reducer(state: CustomPanelState, action: CustomPanelAction): Cus
         displayType: action.payload
       };
     case "TOGGLE_QUERY_TRACING":
-      saveToStorage("QUERY_TRACING", !state.isTracingEnabled);
       return {
         ...state,
         isTracingEnabled: !state.isTracingEnabled,
 
       };
     case "TOGGLE_NO_CACHE":
-      saveToStorage("NO_CACHE", !state.nocache);
       return {
         ...state,
         nocache: !state.nocache
diff --git a/app/vmui/packages/vmui/src/styles/core.scss b/app/vmui/packages/vmui/src/styles/core.scss
index a7a7fd91f..1fc75cd73 100644
--- a/app/vmui/packages/vmui/src/styles/core.scss
+++ b/app/vmui/packages/vmui/src/styles/core.scss
@@ -28,6 +28,11 @@ b {
   font-weight: bold;
 }
 
+textarea,
+input {
+  cursor: text;
+}
+
 input[type=number]::-webkit-inner-spin-button,
 input[type=number]::-webkit-outer-spin-button {
   -webkit-appearance: none;
diff --git a/app/vmui/packages/vmui/src/styles/variables.scss b/app/vmui/packages/vmui/src/styles/variables.scss
index 094acc677..a3c55ae3d 100644
--- a/app/vmui/packages/vmui/src/styles/variables.scss
+++ b/app/vmui/packages/vmui/src/styles/variables.scss
@@ -18,6 +18,7 @@ $color-text-secondary: rgba($color-text, 0.6);
 $color-text-disabled: rgba($color-text, 0.4);
 
 $color-black: #110f0f;
+$color-dove-gray: #616161;
 $color-silver: #C4C4C4;
 $color-alto: #D8D8D8;
 $color-white: #ffffff;
@@ -30,7 +31,7 @@ $color-tropical-blue: #C9E3F6;
 $color-background-body: var(--color-background-body);
 $color-background-block: var(--color-background-block);
 $color-background-modal: rgba($color-black, 0.7);
-$color-background-tooltip: rgba(97, 97, 97, 0.92);
+$color-background-tooltip: rgba($color-dove-gray, 0.92);
 
 
 /************* padding *************/
diff --git a/app/vmui/packages/vmui/src/utils/uplot/tooltip.ts b/app/vmui/packages/vmui/src/utils/uplot/tooltip.ts
deleted file mode 100644
index 970da5b5e..000000000
--- a/app/vmui/packages/vmui/src/utils/uplot/tooltip.ts
+++ /dev/null
@@ -1,36 +0,0 @@
-import dayjs from "dayjs";
-import { SetupTooltip } from "./types";
-import { getColorLine, formatPrettyNumber, getLegendLabel } from "./helpers";
-import { DATE_FULL_TIMEZONE_FORMAT } from "../../constants/date";
-
-// TODO create jsx component
-export const setTooltip = ({ u, tooltipIdx, metrics, series, tooltip, tooltipOffset, unit = "" }: SetupTooltip): void => {
-  const { seriesIdx, dataIdx } = tooltipIdx;
-  if (seriesIdx === null || dataIdx === undefined) return;
-  const dataSeries = u.data[seriesIdx][dataIdx];
-  const dataTime = u.data[0][dataIdx];
-  const metric = metrics[seriesIdx - 1]?.metric || {};
-  const selectedSeries = series[seriesIdx];
-  const color = getColorLine(selectedSeries.label || "");
-
-  const { width, height } = u.over.getBoundingClientRect();
-  const top = u.valToPos((dataSeries || 0), series[seriesIdx]?.scale || "1");
-  const lft = u.valToPos(dataTime, "x");
-  const { width: tooltipWidth, height: tooltipHeight } = tooltip.getBoundingClientRect();
-  const overflowX = lft + tooltipWidth >= width;
-  const overflowY = top + tooltipHeight >= height;
-
-  tooltip.style.display = "grid";
-  tooltip.style.top = `${tooltipOffset.top + top + 10 - (overflowY ? tooltipHeight + 10 : 0)}px`;
-  tooltip.style.left = `${tooltipOffset.left + lft + 10 - (overflowX ? tooltipWidth + 20 : 0)}px`;
-  const metricName = (selectedSeries.label || "").replace(/{.+}/gmi, "").trim();
-  const name = getLegendLabel(metricName);
-  const date = dayjs(new Date(dataTime * 1000)).format(DATE_FULL_TIMEZONE_FORMAT);
-  const info = Object.keys(metric).filter(k => k !== "__name__").map(k => `<div><b>${k}</b>: ${metric[k]}</div>`).join("");
-  const marker = `<div class="u-tooltip__marker" style="background: ${color}"></div>`;
-  tooltip.innerHTML = `<div>${date}</div>
-                       <div class="u-tooltip-data">
-                         ${marker}${name}: <b class="u-tooltip-data__value">${formatPrettyNumber(dataSeries)}</b> ${unit}
-                       </div>
-                       <div class="u-tooltip__info">${info}</div>`;
-};
diff --git a/app/vmui/packages/vmui/src/utils/uplot/types.ts b/app/vmui/packages/vmui/src/utils/uplot/types.ts
index 604b86549..e46850228 100644
--- a/app/vmui/packages/vmui/src/utils/uplot/types.ts
+++ b/app/vmui/packages/vmui/src/utils/uplot/types.ts
@@ -1,21 +1,4 @@
 import uPlot, { Series } from "uplot";
-import { MetricResult } from "../../api/types";
-
-export interface SetupTooltip {
-    u: uPlot,
-    metrics: MetricResult[],
-    series: Series[],
-    tooltip: HTMLDivElement,
-    unit?: string,
-    tooltipOffset: {
-        left: number,
-        top: number
-    },
-    tooltipIdx: {
-        seriesIdx: number | null,
-        dataIdx: number | undefined
-    }
-}
 
 export interface HideSeriesArgs {
     hideSeries: string[],
diff --git a/deployment/docker/alerts-vmalert.yml b/deployment/docker/alerts-vmalert.yml
new file mode 100644
index 000000000..5e84ea4b6
--- /dev/null
+++ b/deployment/docker/alerts-vmalert.yml
@@ -0,0 +1,72 @@
+# File contains default list of alerts for мьфдуке service.
+# The alerts below are just recommendations and may require some updates
+# and threshold calibration according to every specific setup.
+groups:
+  # Alerts group for vmalert assumes that Grafana dashboard
+  # https://grafana.com/grafana/dashboards/14950-victoriametrics-vmalert is installed.
+  # Pls update the `dashboard` annotation according to your setup.
+  - name: vmalert
+    interval: 30s
+    rules:
+      - alert: ConfigurationReloadFailure
+        expr: vmalert_config_last_reload_successful != 1
+        labels:
+          severity: warning
+        annotations:
+          summary: "Configuration reload failed for vmalert instance {{ $labels.instance }}"
+          description: "Configuration hot-reload failed for vmalert on instance {{ $labels.instance }}.
+            Check vmalert's logs for detailed error message."
+
+      - alert: AlertingRulesError
+        expr: sum(vmalert_alerting_rules_error) by(job, instance, group) > 0
+        for: 5m
+        labels:
+          severity: warning
+        annotations:
+          dashboard: "http://localhost:3000/d/LzldHAVnz?viewPanel=13&var-instance={{ $labels.instance }}&var-group={{ $labels.group }}"
+          summary: "Alerting rules are failing for vmalert instance {{ $labels.instance }}"
+          description: "Alerting rules execution is failing for group \"{{ $labels.group }}\".
+            Check vmalert's logs for detailed error message."
+
+      - alert: RecordingRulesError
+        expr: sum(vmalert_recording_rules_error) by(job, instance, group) > 0
+        for: 5m
+        labels:
+          severity: warning
+        annotations:
+          dashboard: "http://localhost:3000/d/LzldHAVnz?viewPanel=30&var-instance={{ $labels.instance }}&var-group={{ $labels.group }}"
+          summary: "Recording rules are failing for vmalert instance {{ $labels.instance }}"
+          description: "Recording rules execution is failing for group \"{{ $labels.group }}\".
+            Check vmalert's logs for detailed error message."
+
+      - alert: RecordingRulesNoData
+        expr: sum(vmalert_recording_rules_last_evaluation_samples) by(job, group, recording) < 1
+        for: 30m
+        labels:
+          severity: warning
+        annotations:
+          dashboard: "http://localhost:3000/d/LzldHAVnz?viewPanel=33&var-group={{ $labels.group }}"
+          summary: "Recording rule {{ $labels.recording }} ({ $labels.group }}) produces no data"
+          description: "Recording rule \"{{ $labels.recording }}\" from group \"{{ $labels.group }}\" 
+            produces 0 samples over the last 30min. It might be caused by a misconfiguration 
+            or incorrect query expression."
+
+      - alert: RemoteWriteErrors
+        expr: sum(increase(vmalert_remotewrite_errors_total[5m])) by(job, instance) > 0
+        for: 15m
+        labels:
+          severity: warning
+        annotations:
+          summary: "vmalert instance {{ $labels.instance }} is failing to push metrics to remote write URL"
+          description: "vmalert instance {{ $labels.instance }} is failing to push metrics generated via alerting 
+            or recording rules to the configured remote write URL. Check vmalert's logs for detailed error message."
+
+      - alert: AlertmanagerErrors
+        expr: sum(increase(vmalert_alerts_send_errors_total[5m])) by(job, instance, addr) > 0
+        for: 15m
+        labels:
+          severity: warning
+        annotations:
+          summary: "vmalert instance {{ $labels.instance }} is failing to send notifications to Alertmanager"
+          description: "vmalert instance {{ $labels.instance }} is failing to send alert notifications to \"{{ $labels.addr }}\".
+            Check vmalert's logs for detailed error message."
diff --git a/deployment/docker/docker-compose-cluster.yml b/deployment/docker/docker-compose-cluster.yml
index 2b6621e6f..1069e6674 100644
--- a/deployment/docker/docker-compose-cluster.yml
+++ b/deployment/docker/docker-compose-cluster.yml
@@ -91,6 +91,7 @@ services:
       - ./alerts-cluster.yml:/etc/alerts/alerts.yml
       - ./alerts-health.yml:/etc/alerts/alerts-health.yml
       - ./alerts-vmagent.yml:/etc/alerts/alerts-vmagent.yml
+      - ./alerts-vmalert.yml:/etc/alerts/alerts-vmalert.yml
     command:
       - '--datasource.url=http://vmselect:8481/select/0/prometheus'
       - '--remoteRead.url=http://vmselect:8481/select/0/prometheus'
diff --git a/deployment/docker/docker-compose.yml b/deployment/docker/docker-compose.yml
index 3f1733403..3d6a8a47c 100644
--- a/deployment/docker/docker-compose.yml
+++ b/deployment/docker/docker-compose.yml
@@ -66,6 +66,7 @@ services:
       - ./alerts.yml:/etc/alerts/alerts.yml
       - ./alerts-health.yml:/etc/alerts/alerts-health.yml
       - ./alerts-vmagent.yml:/etc/alerts/alerts-vmagent.yml
+      - ./alerts-vmalert.yml:/etc/alerts/alerts-vmalert.yml
     command:
       - "--datasource.url=http://victoriametrics:8428/"
       - "--remoteRead.url=http://victoriametrics:8428/"
diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md
index 299ec6bf4..8f922c3a1 100644
--- a/docs/CHANGELOG.md
+++ b/docs/CHANGELOG.md
@@ -15,12 +15,20 @@ The following tip changes can be tested by building VictoriaMetrics components f
 
 ## tip
 
+* FEATURE: [VictoriaMetrics enterprise](https://docs.victoriametrics.com/enterprise.html): add `-storageNode.filter` command-line flag for filtering the [discovered vmstorage nodes](https://docs.victoriametrics.com/Cluster-VictoriaMetrics.html#automatic-vmstorage-discovery) with arbitrary regular expressions. See [this feature request](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/3353).
+* FEATURE: [MetricsQL](https://docs.victoriametrics.com/MetricsQL.html): allow using numeric values with `K`, `Ki`, `M`, `Mi`, `G`, `Gi`, `T` and `Ti` suffixes inside MetricsQL queries. For example `8Ki` equals to `8*1024`, while `8.2M` equals to `8.2*1000*1000`.
+* FEATURE: [MetricsQL](https://docs.victoriametrics.com/MetricsQL.html): add [range_normalize](https://docs.victoriametrics.com/MetricsQL.html#range_normalize) function for normalizing multiple time series into `[0...1]` value range. This function is useful for correlation analyzis of time series with distinct value ranges. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/3167).
 * FEATURE: [MetricsQL](https://docs.victoriametrics.com/MetricsQL.html): add [range_linear_regression](https://docs.victoriametrics.com/MetricsQL.html#range_linear_regression) function for calculating [simple linear regression](https://en.wikipedia.org/wiki/Simple_linear_regression) over the input time series on the selected time range. This function is useful for predictions and capacity planning. For example, `range_linear_regression(process_resident_memory_bytes)` can predict future memory usage based on the past memory usage.
 * FEATURE: [MetricsQL](https://docs.victoriametrics.com/MetricsQL.html): add [range_stddev](https://docs.victoriametrics.com/MetricsQL.html#range_stddev) and [range_stdvar](https://docs.victoriametrics.com/MetricsQL.html#range_stdvar) functions.
+* FEATURE: [MetricsQL](https://docs.victoriametrics.com/MetricsQL.html): optimize `expr1 op expr2` query when `expr1` returns an empty result. In this case there is no sense in executing `expr2` for `op` not equal to `or`, since the end result will be empty according to [PromQL series matching rules](https://prometheus.io/docs/prometheus/latest/querying/operators/#vector-matching). See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/3349). Thanks to @jianglinjian for pointing to this case.
 * FEATURE: [vmui](https://docs.victoriametrics.com/#vmui): add the ability to upload/paste JSON to investigate the trace. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/3308) and [this pull request](https://github.com/VictoriaMetrics/VictoriaMetrics/pull/3310).
 * FEATURE: [vmui](https://docs.victoriametrics.com/#vmui): reduce JS bundle size from 200Kb to 100Kb. See [this pull request](https://github.com/VictoriaMetrics/VictoriaMetrics/pull/3298).
 * FEATURE: [vmui](https://docs.victoriametrics.com/#vmui): add the ability to hide results of a particular query by clicking the `eye` icon. See [this pull request](https://github.com/VictoriaMetrics/VictoriaMetrics/pull/3359).
+* FEATURE: [vmui](https://docs.victoriametrics.com/#vmui): add the ability to "stick" a tooltip on the chart by clicking on a data point. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/3321) and [this pull request](https://github.com/VictoriaMetrics/VictoriaMetrics/pull/3376)
+* FEATURE: [vmalert](https://docs.victoriametrics.com/vmalert.html): add default alert list for vmalert's metrics. See [alerts-vmalert.yml](https://github.com/VictoriaMetrics/VictoriaMetrics/blob/master/deployment/docker/alerts-vmalert.yml).
 
+* BUGFIX: [MetricsQL](https://docs.victoriametrics.com/MetricsQL.html): properly return an empty result from [limit_offset](https://docs.victoriametrics.com/MetricsQL.html#limit_offset) if the `offset` arg exceeds the number of inner time series. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/3312).
+* BUGFIX: [vmagent](https://docs.victoriametrics.com/vmagent.html): properly discover GCE zones when `filter` option is set at [gce_sd_configs](https://docs.victoriametrics.com/sd_configs.html#gce_sd_configs). See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/3202).
 * BUGFIX: [vmui](https://docs.victoriametrics.com/#vmui): properly display the requested graph on the requested time range when navigating from Prometheus URL in Grafana.
 * BUGFIX: reduce CPU usage spikes and memory usage spikes under high data ingestion rate introduced in [v1.83.0](https://docs.victoriametrics.com/CHANGELOG.html#v1830). See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/3343).
 
diff --git a/docs/Cluster-VictoriaMetrics.md b/docs/Cluster-VictoriaMetrics.md
index c2d072ef9..1393d3d64 100644
--- a/docs/Cluster-VictoriaMetrics.md
+++ b/docs/Cluster-VictoriaMetrics.md
@@ -215,6 +215,10 @@ For example, `-storageNode='dns+srv:vmstorage-hot' -storageNode='dns+srv:vmstora
 It is OK to pass regular static `vmstorage` addresses together with `dns+srv` addresses at `-storageNode`. For example,
 `-storageNode=vmstorage1,vmstorage2 -storageNode='dns+srv:vmstorage-autodiscovery'`.
 
+The discovered addresses can be filtered with optional `-storageNode.filter` command-line flag, which can contain arbitrary regular expression filter.
+For example, `-storageNode.filter='^[^:]+:8400$'` would leave discovered addresses ending with `8400` port only, e.g. the default port used
+for sending data from `vminsert` to `vmstorage` node according to `-vminsertAddr` command-line flag.
+
 The currently discovered `vmstorage` nodes can be [monitored](#monitoring) with `vm_rpc_vmstorage_is_reachable` and `vm_rpc_vmstorage_is_read_only` metrics.
 
 ## mTLS protection
@@ -708,6 +712,8 @@ Report bugs and propose new features [here](https://github.com/VictoriaMetrics/V
 Below is the output for `/path/to/vminsert -help`:
 
 ```
+  -cacheExpireDuration duration
+     Items are removed from in-memory caches after they aren't accessed for this duration. Lower values may reduce memory usage at the cost of higher CPU usage. See also -prevCacheRemovalPercent (default 30m0s)
   -cluster.tls
      Whether to use TLS for connections to -storageNode. See https://docs.victoriametrics.com/Cluster-VictoriaMetrics.html#mtls-protection .This flag is available only in enterprise version of VictoriaMetrics
   -cluster.tlsCAFile string
@@ -719,7 +725,7 @@ Below is the output for `/path/to/vminsert -help`:
   -cluster.tlsKeyFile string
      Path to client-side TLS key file to use when connecting to -storageNode if -cluster.tls flag is set. See https://docs.victoriametrics.com/Cluster-VictoriaMetrics.html#mtls-protection . This flag is available only in enterprise version of VictoriaMetrics
   -clusternativeListenAddr string
-     TCP address to listen for data from other vminsert nodes in multi-level cluster setup. See https://docs.victoriametrics.com/Cluster-VictoriaMetrics.html#multi-level-cluster-setup . Usually :8400 must be set. Doesn't work if empty
+     TCP address to listen for data from other vminsert nodes in multi-level cluster setup. See https://docs.victoriametrics.com/Cluster-VictoriaMetrics.html#multi-level-cluster-setup . Usually :8400 should be set to match default vmstorage port for vminsert. Disabled work if empty
   -csvTrimTimestamp duration
      Trim timestamps when importing csv data to this duration. Minimum practical duration is 1ms. Higher duration (i.e. 1s) may be used for reducing disk space usage for timestamp data (default 1ms)
   -datadog.maxInsertRequestSize size
@@ -740,7 +746,7 @@ Below is the output for `/path/to/vminsert -help`:
   -envflag.prefix string
      Prefix for environment variables if -envflag.enable is set
   -eula
-     By specifying this flag, you confirm that you have an enterprise license and accept the EULA https://victoriametrics.com/assets/VM_EULA.pdf . This flag is available only in enterprise version of VictoriaMetrics
+     By specifying this flag, you confirm that you have an enterprise license and accept the EULA https://victoriametrics.com/assets/VM_EULA.pdf . This flag is available only in VictoriaMetrics enterprise. See https://docs.victoriametrics.com/enterprise.html
   -flagsAuthKey string
      Auth key for /flags endpoint. It must be passed via authKey query arg. It overrides httpAuth.* settings
   -fs.disableMmap
@@ -833,6 +839,8 @@ Below is the output for `/path/to/vminsert -help`:
      Trim timestamps for OpenTSDB HTTP data to this duration. Minimum practical duration is 1ms. Higher duration (i.e. 1s) may be used for reducing disk space usage for timestamp data (default 1ms)
   -pprofAuthKey string
      Auth key for /debug/pprof/* endpoints. It must be passed via authKey query arg. It overrides httpAuth.* settings
+  -prevCacheRemovalPercent float
+     Items in the previous caches are removed when the percent of requests it serves becomes lower than this value. Higher values reduce memory usage at the cost of higher CPU usage. See also -cacheExpireDuration (default 0.1)
   -pushmetrics.extraLabel array
      Optional labels to add to metrics pushed to -pushmetrics.url . For example, -pushmetrics.extraLabel='instance="foo"' adds instance="foo" label to all the metrics pushed to -pushmetrics.url
      Supports an array of values separated by comma or specified via multiple flags.
@@ -854,6 +862,8 @@ Below is the output for `/path/to/vminsert -help`:
   -storageNode array
      Comma-separated addresses of vmstorage nodes; usage: -storageNode=vmstorage-host1,...,vmstorage-hostN . Enterprise version of VictoriaMetrics supports automatic discovery of vmstorage addresses via dns+srv records. For example, -storageNode=dns+srv:vmstorage.addrs . See https://docs.victoriametrics.com/Cluster-VictoriaMetrics.html#automatic-vmstorage-discovery
      Supports an array of values separated by comma or specified via multiple flags.
+  -storageNode.filter string
+     An optional regexp filter for discovered -storageNode addresses according to https://docs.victoriametrics.com/Cluster-VictoriaMetrics.html#automatic-vmstorage-discovery. Discovered addresses matching the filter are retained, while other addresses are ignored. This flag is available only in VictoriaMetrics enterprise. See https://docs.victoriametrics.com/enterprise.html
   -tls
      Whether to enable TLS for incoming HTTP requests at -httpListenAddr (aka https). -tlsCertFile and -tlsKeyFile must be set if -tls is set
   -tlsCertFile string
@@ -880,6 +890,8 @@ Below is the output for `/path/to/vmselect -help`:
 ```
   -cacheDataPath string
      Path to directory for cache files. Cache isn't saved if empty
+  -cacheExpireDuration duration
+     Items are removed from in-memory caches after they aren't accessed for this duration. Lower values may reduce memory usage at the cost of higher CPU usage. See also -prevCacheRemovalPercent (default 30m0s)
   -cluster.tls
      Whether to use TLS for connections to -storageNode. See https://docs.victoriametrics.com/Cluster-VictoriaMetrics.html#mtls-protection .This flag is available only in enterprise version of VictoriaMetrics
   -cluster.tlsCAFile string
@@ -912,13 +924,13 @@ Below is the output for `/path/to/vmselect -help`:
   -clusternative.tlsKeyFile string
      Path to server-side TLS key file to use when accepting connections at -clusternativeListenAddr if -clusternative.tls flag is set. See https://docs.victoriametrics.com/Cluster-VictoriaMetrics.html#mtls-protection
   -clusternativeListenAddr string
-     TCP address to listen for requests from other vmselect nodes in multi-level cluster setup. See https://docs.victoriametrics.com/Cluster-VictoriaMetrics.html#multi-level-cluster-setup . Usually :8401 must be set. Doesn't work if empty
+     TCP address to listen for requests from other vmselect nodes in multi-level cluster setup. See https://docs.victoriametrics.com/Cluster-VictoriaMetrics.html#multi-level-cluster-setup . Usually :8401 should be set to match default vmstorage port for vmselect. Disabled work if empty
   -dedup.minScrapeInterval duration
      Leave only the last sample in every time series per each discrete interval equal to -dedup.minScrapeInterval > 0. See https://docs.victoriametrics.com/#deduplication for details
   -denyQueryTracing
      Whether to disable the ability to trace queries. See https://docs.victoriametrics.com/#query-tracing
   -downsampling.period array
-     Comma-separated downsampling periods in the format 'offset:period'. For example, '30d:10m' instructs to leave a single sample per 10 minutes for samples older than 30 days. See https://docs.victoriametrics.com/#downsampling for details
+     Comma-separated downsampling periods in the format 'offset:period'. For example, '30d:10m' instructs to leave a single sample per 10 minutes for samples older than 30 days. See https://docs.victoriametrics.com/#downsampling for details. This flag is available only in VictoriaMetrics enterprise. See https://docs.victoriametrics.com/enterprise.html
      Supports an array of values separated by comma or specified via multiple flags.
   -enableTCP6
      Whether to enable IPv6 for listening and dialing. By default only IPv4 TCP and UDP is used
@@ -927,7 +939,7 @@ Below is the output for `/path/to/vmselect -help`:
   -envflag.prefix string
      Prefix for environment variables if -envflag.enable is set
   -eula
-     By specifying this flag, you confirm that you have an enterprise license and accept the EULA https://victoriametrics.com/assets/VM_EULA.pdf . This flag is available only in enterprise version of VictoriaMetrics
+     By specifying this flag, you confirm that you have an enterprise license and accept the EULA https://victoriametrics.com/assets/VM_EULA.pdf . This flag is available only in VictoriaMetrics enterprise. See https://docs.victoriametrics.com/enterprise.html
   -flagsAuthKey string
      Auth key for /flags endpoint. It must be passed via authKey query arg. It overrides httpAuth.* settings
   -fs.disableMmap
@@ -975,6 +987,8 @@ Below is the output for `/path/to/vmselect -help`:
      Auth key for /metrics endpoint. It must be passed via authKey query arg. It overrides httpAuth.* settings
   -pprofAuthKey string
      Auth key for /debug/pprof/* endpoints. It must be passed via authKey query arg. It overrides httpAuth.* settings
+  -prevCacheRemovalPercent float
+     Items in the previous caches are removed when the percent of requests it serves becomes lower than this value. Higher values reduce memory usage at the cost of higher CPU usage. See also -cacheExpireDuration (default 0.1)
   -pushmetrics.extraLabel array
      Optional labels to add to metrics pushed to -pushmetrics.url . For example, -pushmetrics.extraLabel='instance="foo"' adds instance="foo" label to all the metrics pushed to -pushmetrics.url
      Supports an array of values separated by comma or specified via multiple flags.
@@ -984,7 +998,7 @@ Below is the output for `/path/to/vmselect -help`:
      Optional URL to push metrics exposed at /metrics page. See https://docs.victoriametrics.com/#push-metrics . By default metrics exposed at /metrics page aren't pushed to any remote storage
      Supports an array of values separated by comma or specified via multiple flags.
   -replicationFactor int
-     How many copies of every time series is available on vmstorage nodes. See -replicationFactor command-line flag for vminsert nodes (default 1)
+     How many copies of every time series is available on vmstorage nodes. vmselect cancels responses from the slowest -replicationFactor-1 vmstorage nodes if -replicationFactor is set by assuming it already received complete data. It isn't recommended setting this flag to values other than 1 at vmselect nodes, since it may result in incomplete responses after adding new vmstorage nodes even if the replication is enabled at vminsert nodes (default 1)
   -search.cacheTimestampOffset duration
      The maximum duration since the current time for response data, which is always queried from the original raw data, without using the response cache. Increase this value if you see gaps in responses due to time synchronization issues between VictoriaMetrics and data sources (default 5m0s)
   -search.denyPartialResponse
@@ -992,9 +1006,9 @@ Below is the output for `/path/to/vmselect -help`:
   -search.disableCache
      Whether to disable response caching. This may be useful during data backfilling
   -search.graphiteMaxPointsPerSeries int
-     The maximum number of points per series Graphite render API can return. This flag is available only in enterprise version of VictoriaMetrics (default 1000000)
+     The maximum number of points per series Graphite render API can return. This flag is available only in VictoriaMetrics enterprise. See https://docs.victoriametrics.com/enterprise.html (default 1000000)
   -search.graphiteStorageStep duration
-     The interval between datapoints stored in the database. It is used at Graphite Render API handler for normalizing the interval between datapoints in case it isn't normalized. It can be overridden by sending 'storage_step' query arg to /render API or by sending the desired interval via 'Storage-Step' http header during querying /render API. This flag is available only in enterprise version of VictoriaMetrics (default 10s)
+     The interval between datapoints stored in the database. It is used at Graphite Render API handler for normalizing the interval between datapoints in case it isn't normalized. It can be overridden by sending 'storage_step' query arg to /render API or by sending the desired interval via 'Storage-Step' http header during querying /render API. This flag is available only in VictoriaMetrics enterprise. See https://docs.victoriametrics.com/enterprise.html (default 10s)
   -search.latencyOffset duration
      The time when data points become visible in query results after the collection. Too small value can result in incomplete last points for query results (default 30s)
   -search.logSlowQueryDuration duration
@@ -1008,7 +1022,7 @@ Below is the output for `/path/to/vmselect -help`:
   -search.maxFederateSeries int
      The maximum number of time series, which can be returned from /federate. This option allows limiting memory usage (default 1000000)
   -search.maxGraphiteSeries int
-     The maximum number of time series, which can be scanned during queries to Graphite Render API. See https://docs.victoriametrics.com/#graphite-render-api-usage . This flag is available only in enterprise version of VictoriaMetrics (default 300000)
+     The maximum number of time series, which can be scanned during queries to Graphite Render API. See https://docs.victoriametrics.com/#graphite-render-api-usage . This flag is available only in VictoriaMetrics enterprise. See https://docs.victoriametrics.com/enterprise.html (default 300000)
   -search.maxLookback duration
      Synonym to -search.lookback-delta from Prometheus. The value is dynamically detected from interval between time series datapoints if not set. It can be overridden on per-query basis via max_lookback arg. See also '-search.maxStalenessInterval' flag, which has the same meaining due to historical reasons
   -search.maxMemoryPerQuery size
@@ -1061,8 +1075,10 @@ Below is the output for `/path/to/vmselect -help`:
      Comma-separated addresses of vmselect nodes; usage: -selectNode=vmselect-host1,...,vmselect-hostN
      Supports an array of values separated by comma or specified via multiple flags.
   -storageNode array
-     Comma-separated addresses of vmstorage nodes; usage: -storageNode=vmstorage-host1,...,vmstorage-hostN . Enterprise version of VictoriaMetrics supports automatic discovery of vmstorage addresses via dns+srv records. For example, -storageNode=dns+srv:vmstorage.addrs .See https://docs.victoriametrics.com/Cluster-VictoriaMetrics.html#automatic-vmstorage-discovery
+     Comma-separated addresses of vmstorage nodes; usage: -storageNode=vmstorage-host1,...,vmstorage-hostN . Enterprise version of VictoriaMetrics supports automatic discovery of vmstorage addresses via dns+srv records. For example, -storageNode=dns+srv:vmstorage.addrs . See https://docs.victoriametrics.com/Cluster-VictoriaMetrics.html#automatic-vmstorage-discovery
      Supports an array of values separated by comma or specified via multiple flags.
+  -storageNode.filter string
+     An optional regexp filter for discovered -storageNode addresses according to https://docs.victoriametrics.com/Cluster-VictoriaMetrics.html#automatic-vmstorage-discovery. Discovered addresses matching the filter are retained, while other addresses are ignored. This flag is available only in VictoriaMetrics enterprise. See https://docs.victoriametrics.com/enterprise.html
   -tls
      Whether to enable TLS for incoming HTTP requests at -httpListenAddr (aka https). -tlsCertFile and -tlsKeyFile must be set if -tls is set
   -tlsCertFile string
@@ -1089,19 +1105,21 @@ Below is the output for `/path/to/vmstorage -help`:
 ```
   -bigMergeConcurrency int
      The maximum number of CPU cores to use for big merges. Default value is used if set to 0
+  -cacheExpireDuration duration
+     Items are removed from in-memory caches after they aren't accessed for this duration. Lower values may reduce memory usage at the cost of higher CPU usage. See also -prevCacheRemovalPercent (default 30m0s)
   -cluster.tls
-     Whether to use TLS when accepting connections from vminsert and vmselect. See https://docs.victoriametrics.com/Cluster-VictoriaMetrics.html#mtls-protection . This flag is available only in enterprise version of VictoriaMetrics
+     Whether to use TLS when accepting connections from vminsert and vmselect. See https://docs.victoriametrics.com/Cluster-VictoriaMetrics.html#mtls-protection . This flag is available only in VictoriaMetrics enterprise. See https://docs.victoriametrics.com/enterprise.html
   -cluster.tlsCAFile string
-     Path to TLS CA file to use for verifying certificates provided by vminsert and vmselect if -cluster.tls flag is set. By default system CA is used. See https://docs.victoriametrics.com/Cluster-VictoriaMetrics.html#mtls-protection . This flag is available only in enterprise version of VictoriaMetrics
+     Path to TLS CA file to use for verifying certificates provided by vminsert and vmselect if -cluster.tls flag is set. By default system CA is used. See https://docs.victoriametrics.com/Cluster-VictoriaMetrics.html#mtls-protection . This flag is available only in VictoriaMetrics enterprise. See https://docs.victoriametrics.com/enterprise.html
   -cluster.tlsCertFile string
-     Path to server-side TLS certificate file to use when accepting connections from vminsert and vmselect if -cluster.tls flag is set. See https://docs.victoriametrics.com/Cluster-VictoriaMetrics.html#mtls-protection . This flag is available only in enterprise version of VictoriaMetrics
+     Path to server-side TLS certificate file to use when accepting connections from vminsert and vmselect if -cluster.tls flag is set. See https://docs.victoriametrics.com/Cluster-VictoriaMetrics.html#mtls-protection . This flag is available only in VictoriaMetrics enterprise. See https://docs.victoriametrics.com/enterprise.html
   -cluster.tlsCipherSuites array
-     Optional list of TLS cipher suites used for connections from vminsert and vmselect if -cluster.tls flag is set. See the list of supported cipher suites at https://pkg.go.dev/crypto/tls#pkg-constants .This flag is available only in enterprise version of VictoriaMetrics
+     Optional list of TLS cipher suites used for connections from vminsert and vmselect if -cluster.tls flag is set. See the list of supported cipher suites at https://pkg.go.dev/crypto/tls#pkg-constants .This flag is available only in VictoriaMetrics enterprise. See https://docs.victoriametrics.com/enterprise.html
      Supports an array of values separated by comma or specified via multiple flags.
   -cluster.tlsInsecureSkipVerify
-     Whether to skip verification of TLS certificates provided by vminsert and vmselect if -cluster.tls flag is set. Note that disabled TLS certificate verification breaks security. This flag is available only in enterprise version of VictoriaMetrics
+     Whether to skip verification of TLS certificates provided by vminsert and vmselect if -cluster.tls flag is set. Note that disabled TLS certificate verification breaks security. This flag is available only in VictoriaMetrics enterprise. See https://docs.victoriametrics.com/enterprise.html
   -cluster.tlsKeyFile string
-     Path to server-side TLS key file to use when accepting connections from vminsert and vmselect if -cluster.tls flag is set. See https://docs.victoriametrics.com/Cluster-VictoriaMetrics.html#mtls-protection . This flag is available only in enterprise version of VictoriaMetrics
+     Path to server-side TLS key file to use when accepting connections from vminsert and vmselect if -cluster.tls flag is set. See https://docs.victoriametrics.com/Cluster-VictoriaMetrics.html#mtls-protection . This flag is available only in VictoriaMetrics enterprise. See https://docs.victoriametrics.com/enterprise.html
   -dedup.minScrapeInterval duration
      Leave only the last sample in every time series per each discrete interval equal to -dedup.minScrapeInterval > 0. See https://docs.victoriametrics.com/#deduplication for details
   -denyQueriesOutsideRetention
@@ -1109,7 +1127,7 @@ Below is the output for `/path/to/vmstorage -help`:
   -denyQueryTracing
      Whether to disable the ability to trace queries. See https://docs.victoriametrics.com/#query-tracing
   -downsampling.period array
-     Comma-separated downsampling periods in the format 'offset:period'. For example, '30d:10m' instructs to leave a single sample per 10 minutes for samples older than 30 days. See https://docs.victoriametrics.com/#downsampling for details
+     Comma-separated downsampling periods in the format 'offset:period'. For example, '30d:10m' instructs to leave a single sample per 10 minutes for samples older than 30 days. See https://docs.victoriametrics.com/#downsampling for details. This flag is available only in VictoriaMetrics enterprise. See https://docs.victoriametrics.com/enterprise.html
      Supports an array of values separated by comma or specified via multiple flags.
   -enableTCP6
      Whether to enable IPv6 for listening and dialing. By default only IPv4 TCP and UDP is used
@@ -1118,7 +1136,7 @@ Below is the output for `/path/to/vmstorage -help`:
   -envflag.prefix string
      Prefix for environment variables if -envflag.enable is set
   -eula
-     By specifying this flag, you confirm that you have an enterprise license and accept the EULA https://victoriametrics.com/assets/VM_EULA.pdf . This flag is available only in enterprise version of VictoriaMetrics
+     By specifying this flag, you confirm that you have an enterprise license and accept the EULA https://victoriametrics.com/assets/VM_EULA.pdf . This flag is available only in VictoriaMetrics enterprise. See https://docs.victoriametrics.com/enterprise.html
   -finalMergeDelay duration
      The delay before starting final merge for per-month partition after no new data is ingested into it. Final merge may require additional disk IO and CPU resources. Final merge may increase query speed and reduce disk space usage in some cases. Zero value disables final merge
   -flagsAuthKey string
@@ -1175,7 +1193,7 @@ Below is the output for `/path/to/vmstorage -help`:
   -precisionBits int
      The number of precision bits to store per each value. Lower precision bits improves data compression at the cost of precision loss (default 64)
   -prevCacheRemovalPercent float
-        The previous cache is removed when the percent of requests it serves becomes lower than this value. Higher values reduce average memory usage at the cost of higher CPU usage (default 0.2)
+     Items in the previous caches are removed when the percent of requests it serves becomes lower than this value. Higher values reduce memory usage at the cost of higher CPU usage. See also -cacheExpireDuration (default 0.1)
   -pushmetrics.extraLabel array
      Optional labels to add to metrics pushed to -pushmetrics.url . For example, -pushmetrics.extraLabel='instance="foo"' adds instance="foo" label to all the metrics pushed to -pushmetrics.url
      Supports an array of values separated by comma or specified via multiple flags.
@@ -1185,7 +1203,7 @@ Below is the output for `/path/to/vmstorage -help`:
      Optional URL to push metrics exposed at /metrics page. See https://docs.victoriametrics.com/#push-metrics . By default metrics exposed at /metrics page aren't pushed to any remote storage
      Supports an array of values separated by comma or specified via multiple flags.
   -retentionFilter array
-     Retention filter in the format 'filter:retention'. For example, '{env="dev"}:3d' configures the retention for time series with env="dev" label to 3 days. See https://docs.victoriametrics.com/#retention-filters for details. This flag is available only in enterprise version of VictoriaMetrics
+     Retention filter in the format 'filter:retention'. For example, '{env="dev"}:3d' configures the retention for time series with env="dev" label to 3 days. See https://docs.victoriametrics.com/#retention-filters for details. This flag is available only in VictoriaMetrics enterprise. See https://docs.victoriametrics.com/enterprise.html
      Supports an array of values separated by comma or specified via multiple flags.
   -retentionPeriod value
      Data with timestamps outside the retentionPeriod is automatically deleted. See also -retentionFilter
diff --git a/docs/MetricsQL.md b/docs/MetricsQL.md
index 33d1b9c92..e16949ec1 100644
--- a/docs/MetricsQL.md
+++ b/docs/MetricsQL.md
@@ -73,6 +73,7 @@ The list of MetricsQL features:
 * The duration suffix is optional. The duration is in seconds if the suffix is missing.
   For example, `rate(m[300] offset 1800)` is equivalent to `rate(m[5m]) offset 30m`.
 * The duration can be placed anywhere in the query. For example, `sum_over_time(m[1h]) / 1h` is equivalent to `sum_over_time(m[1h]) / 3600`.
+* Numeric values can have `K`, `Ki`, `M`, `Mi`, `G`, `Gi`, `T` and `Ti` suffixes. For example, `8K` is equivalent to `8000`, while `1.2Mi` is equvalent to `1.2*1024*1024`.
 * Trailing commas on all the lists are allowed - label filters, function args and with expressions.
   For instance, the following queries are valid: `m{foo="bar",}`, `f(a, b,)`, `WITH (x=y,) x`.
   This simplifies maintenance of multi-line queries.
@@ -1220,6 +1221,11 @@ over the selected time range per each time series returned by `q`. This function
 
 `range_min(q)` is a [transform function](#transform-functions), which calculates the min value across points per each time series returned by `q`.
 
+#### range_normalize
+
+`range_normalize(q1, ...)` is a [transform function](#transform-functions), which normalizes values for time series returned by `q1, ...` into `[0 ... 1]` range.
+This function is useful for correlating time series with distinct value ranges.
+
 #### range_quantile
 
 `range_quantile(phi, q)` is a [transform function](#transform-functions), which returns `phi`-quantile across points per each time series returned by `q`.
diff --git a/docs/README.md b/docs/README.md
index 21ccbe25f..5953839cf 100644
--- a/docs/README.md
+++ b/docs/README.md
@@ -2036,6 +2036,8 @@ Pass `-help` to VictoriaMetrics in order to see the list of supported command-li
 ```
   -bigMergeConcurrency int
      The maximum number of CPU cores to use for big merges. Default value is used if set to 0
+  -cacheExpireDuration duration
+     Items are removed from in-memory caches after they aren't accessed for this duration. Lower values may reduce memory usage at the cost of higher CPU usage. See also -prevCacheRemovalPercent (default 30m0s)
   -configAuthKey string
      Authorization key for accessing /config page. It must be passed via authKey query arg
   -csvTrimTimestamp duration
@@ -2054,7 +2056,7 @@ Pass `-help` to VictoriaMetrics in order to see the list of supported command-li
   -denyQueryTracing
      Whether to disable the ability to trace queries. See https://docs.victoriametrics.com/#query-tracing
   -downsampling.period array
-     Comma-separated downsampling periods in the format 'offset:period'. For example, '30d:10m' instructs to leave a single sample per 10 minutes for samples older than 30 days. See https://docs.victoriametrics.com/#downsampling for details. This flag is available only in enterprise version of VictoriaMetrics
+     Comma-separated downsampling periods in the format 'offset:period'. For example, '30d:10m' instructs to leave a single sample per 10 minutes for samples older than 30 days. See https://docs.victoriametrics.com/#downsampling for details. This flag is available only in VictoriaMetrics enterprise. See https://docs.victoriametrics.com/enterprise.html
      Supports an array of values separated by comma or specified via multiple flags.
   -dryRun
      Whether to check only -promscrape.config and then exit. Unknown config entries aren't allowed in -promscrape.config by default. This can be changed with -promscrape.config.strictParse=false command-line flag
@@ -2065,7 +2067,7 @@ Pass `-help` to VictoriaMetrics in order to see the list of supported command-li
   -envflag.prefix string
      Prefix for environment variables if -envflag.enable is set
   -eula
-     By specifying this flag, you confirm that you have an enterprise license and accept the EULA https://victoriametrics.com/assets/VM_EULA.pdf . This flag is available only in enterprise version of VictoriaMetrics
+     By specifying this flag, you confirm that you have an enterprise license and accept the EULA https://victoriametrics.com/assets/VM_EULA.pdf . This flag is available only in VictoriaMetrics enterprise. See https://docs.victoriametrics.com/enterprise.html
   -finalMergeDelay duration
      The delay before starting final merge for per-month partition after no new data is ingested into it. Final merge may require additional disk IO and CPU resources. Final merge may increase query speed and reduce disk space usage in some cases. Zero value disables final merge
   -flagsAuthKey string
@@ -2169,7 +2171,7 @@ Pass `-help` to VictoriaMetrics in order to see the list of supported command-li
   -precisionBits int
      The number of precision bits to store per each value. Lower precision bits improves data compression at the cost of precision loss (default 64)
   -prevCacheRemovalPercent float
-     The previous cache is removed when the percent of requests it serves becomes lower than this value. Higher values reduce average memory usage at the cost of higher CPU usage (default 0.2)
+     Items in the previous caches are removed when the percent of requests it serves becomes lower than this value. Higher values reduce memory usage at the cost of higher CPU usage. See also -cacheExpireDuration (default 0.1)
   -promscrape.azureSDCheckInterval duration
      Interval for checking for changes in Azure. This works only if azure_sd_configs is configured in '-promscrape.config' file. See https://docs.victoriametrics.com/sd_configs.html#azure_sd_configs for details (default 1m0s)
   -promscrape.cluster.memberNum string
@@ -2264,7 +2266,7 @@ Pass `-help` to VictoriaMetrics in order to see the list of supported command-li
   -relabelDebug
      Whether to log metrics before and after relabeling with -relabelConfig. If the -relabelDebug is enabled, then the metrics aren't sent to storage. This is useful for debugging the relabeling configs
   -retentionFilter array
-     Retention filter in the format 'filter:retention'. For example, '{env="dev"}:3d' configures the retention for time series with env="dev" label to 3 days. See https://docs.victoriametrics.com/#retention-filters for details. This flag is available only in enterprise version of VictoriaMetrics
+     Retention filter in the format 'filter:retention'. For example, '{env="dev"}:3d' configures the retention for time series with env="dev" label to 3 days. See https://docs.victoriametrics.com/#retention-filters for details. This flag is available only in VictoriaMetrics enterprise. See https://docs.victoriametrics.com/enterprise.html
      Supports an array of values separated by comma or specified via multiple flags.
   -retentionPeriod value
      Data with timestamps outside the retentionPeriod is automatically deleted. See also -retentionFilter
@@ -2278,9 +2280,9 @@ Pass `-help` to VictoriaMetrics in order to see the list of supported command-li
   -search.disableCache
      Whether to disable response caching. This may be useful during data backfilling
   -search.graphiteMaxPointsPerSeries int
-     The maximum number of points per series Graphite render API can return. This flag is available only in enterprise version of VictoriaMetrics (default 1000000)
+     The maximum number of points per series Graphite render API can return. This flag is available only in VictoriaMetrics enterprise. See https://docs.victoriametrics.com/enterprise.html (default 1000000)
   -search.graphiteStorageStep duration
-     The interval between datapoints stored in the database. It is used at Graphite Render API handler for normalizing the interval between datapoints in case it isn't normalized. It can be overridden by sending 'storage_step' query arg to /render API or by sending the desired interval via 'Storage-Step' http header during querying /render API. This flag is available only in enterprise version of VictoriaMetrics (default 10s)
+     The interval between datapoints stored in the database. It is used at Graphite Render API handler for normalizing the interval between datapoints in case it isn't normalized. It can be overridden by sending 'storage_step' query arg to /render API or by sending the desired interval via 'Storage-Step' http header during querying /render API. This flag is available only in VictoriaMetrics enterprise. See https://docs.victoriametrics.com/enterprise.html (default 10s)
   -search.latencyOffset duration
      The time when data points become visible in query results after the collection. Too small value can result in incomplete last points for query results (default 30s)
   -search.logSlowQueryDuration duration
@@ -2294,7 +2296,7 @@ Pass `-help` to VictoriaMetrics in order to see the list of supported command-li
   -search.maxFederateSeries int
      The maximum number of time series, which can be returned from /federate. This option allows limiting memory usage (default 1000000)
   -search.maxGraphiteSeries int
-     The maximum number of time series, which can be scanned during queries to Graphite Render API. See https://docs.victoriametrics.com/#graphite-render-api-usage . This flag is available only in enterprise version of VictoriaMetrics (default 300000)
+     The maximum number of time series, which can be scanned during queries to Graphite Render API. See https://docs.victoriametrics.com/#graphite-render-api-usage . This flag is available only in VictoriaMetrics enterprise. See https://docs.victoriametrics.com/enterprise.html (default 300000)
   -search.maxLookback duration
      Synonym to -search.lookback-delta from Prometheus. The value is dynamically detected from interval between time series datapoints if not set. It can be overridden on per-query basis via max_lookback arg. See also '-search.maxStalenessInterval' flag, which has the same meaining due to historical reasons
   -search.maxMemoryPerQuery size
diff --git a/docs/Single-server-VictoriaMetrics.md b/docs/Single-server-VictoriaMetrics.md
index 3fc46ef80..bb7578f89 100644
--- a/docs/Single-server-VictoriaMetrics.md
+++ b/docs/Single-server-VictoriaMetrics.md
@@ -2039,6 +2039,8 @@ Pass `-help` to VictoriaMetrics in order to see the list of supported command-li
 ```
   -bigMergeConcurrency int
      The maximum number of CPU cores to use for big merges. Default value is used if set to 0
+  -cacheExpireDuration duration
+     Items are removed from in-memory caches after they aren't accessed for this duration. Lower values may reduce memory usage at the cost of higher CPU usage. See also -prevCacheRemovalPercent (default 30m0s)
   -configAuthKey string
      Authorization key for accessing /config page. It must be passed via authKey query arg
   -csvTrimTimestamp duration
@@ -2057,7 +2059,7 @@ Pass `-help` to VictoriaMetrics in order to see the list of supported command-li
   -denyQueryTracing
      Whether to disable the ability to trace queries. See https://docs.victoriametrics.com/#query-tracing
   -downsampling.period array
-     Comma-separated downsampling periods in the format 'offset:period'. For example, '30d:10m' instructs to leave a single sample per 10 minutes for samples older than 30 days. See https://docs.victoriametrics.com/#downsampling for details. This flag is available only in enterprise version of VictoriaMetrics
+     Comma-separated downsampling periods in the format 'offset:period'. For example, '30d:10m' instructs to leave a single sample per 10 minutes for samples older than 30 days. See https://docs.victoriametrics.com/#downsampling for details. This flag is available only in VictoriaMetrics enterprise. See https://docs.victoriametrics.com/enterprise.html
      Supports an array of values separated by comma or specified via multiple flags.
   -dryRun
      Whether to check only -promscrape.config and then exit. Unknown config entries aren't allowed in -promscrape.config by default. This can be changed with -promscrape.config.strictParse=false command-line flag
@@ -2068,7 +2070,7 @@ Pass `-help` to VictoriaMetrics in order to see the list of supported command-li
   -envflag.prefix string
      Prefix for environment variables if -envflag.enable is set
   -eula
-     By specifying this flag, you confirm that you have an enterprise license and accept the EULA https://victoriametrics.com/assets/VM_EULA.pdf . This flag is available only in enterprise version of VictoriaMetrics
+     By specifying this flag, you confirm that you have an enterprise license and accept the EULA https://victoriametrics.com/assets/VM_EULA.pdf . This flag is available only in VictoriaMetrics enterprise. See https://docs.victoriametrics.com/enterprise.html
   -finalMergeDelay duration
      The delay before starting final merge for per-month partition after no new data is ingested into it. Final merge may require additional disk IO and CPU resources. Final merge may increase query speed and reduce disk space usage in some cases. Zero value disables final merge
   -flagsAuthKey string
@@ -2172,7 +2174,7 @@ Pass `-help` to VictoriaMetrics in order to see the list of supported command-li
   -precisionBits int
      The number of precision bits to store per each value. Lower precision bits improves data compression at the cost of precision loss (default 64)
   -prevCacheRemovalPercent float
-     The previous cache is removed when the percent of requests it serves becomes lower than this value. Higher values reduce average memory usage at the cost of higher CPU usage (default 0.2)
+     Items in the previous caches are removed when the percent of requests it serves becomes lower than this value. Higher values reduce memory usage at the cost of higher CPU usage. See also -cacheExpireDuration (default 0.1)
   -promscrape.azureSDCheckInterval duration
      Interval for checking for changes in Azure. This works only if azure_sd_configs is configured in '-promscrape.config' file. See https://docs.victoriametrics.com/sd_configs.html#azure_sd_configs for details (default 1m0s)
   -promscrape.cluster.memberNum string
@@ -2267,7 +2269,7 @@ Pass `-help` to VictoriaMetrics in order to see the list of supported command-li
   -relabelDebug
      Whether to log metrics before and after relabeling with -relabelConfig. If the -relabelDebug is enabled, then the metrics aren't sent to storage. This is useful for debugging the relabeling configs
   -retentionFilter array
-     Retention filter in the format 'filter:retention'. For example, '{env="dev"}:3d' configures the retention for time series with env="dev" label to 3 days. See https://docs.victoriametrics.com/#retention-filters for details. This flag is available only in enterprise version of VictoriaMetrics
+     Retention filter in the format 'filter:retention'. For example, '{env="dev"}:3d' configures the retention for time series with env="dev" label to 3 days. See https://docs.victoriametrics.com/#retention-filters for details. This flag is available only in VictoriaMetrics enterprise. See https://docs.victoriametrics.com/enterprise.html
      Supports an array of values separated by comma or specified via multiple flags.
   -retentionPeriod value
      Data with timestamps outside the retentionPeriod is automatically deleted. See also -retentionFilter
@@ -2281,9 +2283,9 @@ Pass `-help` to VictoriaMetrics in order to see the list of supported command-li
   -search.disableCache
      Whether to disable response caching. This may be useful during data backfilling
   -search.graphiteMaxPointsPerSeries int
-     The maximum number of points per series Graphite render API can return. This flag is available only in enterprise version of VictoriaMetrics (default 1000000)
+     The maximum number of points per series Graphite render API can return. This flag is available only in VictoriaMetrics enterprise. See https://docs.victoriametrics.com/enterprise.html (default 1000000)
   -search.graphiteStorageStep duration
-     The interval between datapoints stored in the database. It is used at Graphite Render API handler for normalizing the interval between datapoints in case it isn't normalized. It can be overridden by sending 'storage_step' query arg to /render API or by sending the desired interval via 'Storage-Step' http header during querying /render API. This flag is available only in enterprise version of VictoriaMetrics (default 10s)
+     The interval between datapoints stored in the database. It is used at Graphite Render API handler for normalizing the interval between datapoints in case it isn't normalized. It can be overridden by sending 'storage_step' query arg to /render API or by sending the desired interval via 'Storage-Step' http header during querying /render API. This flag is available only in VictoriaMetrics enterprise. See https://docs.victoriametrics.com/enterprise.html (default 10s)
   -search.latencyOffset duration
      The time when data points become visible in query results after the collection. Too small value can result in incomplete last points for query results (default 30s)
   -search.logSlowQueryDuration duration
@@ -2297,7 +2299,7 @@ Pass `-help` to VictoriaMetrics in order to see the list of supported command-li
   -search.maxFederateSeries int
      The maximum number of time series, which can be returned from /federate. This option allows limiting memory usage (default 1000000)
   -search.maxGraphiteSeries int
-     The maximum number of time series, which can be scanned during queries to Graphite Render API. See https://docs.victoriametrics.com/#graphite-render-api-usage . This flag is available only in enterprise version of VictoriaMetrics (default 300000)
+     The maximum number of time series, which can be scanned during queries to Graphite Render API. See https://docs.victoriametrics.com/#graphite-render-api-usage . This flag is available only in VictoriaMetrics enterprise. See https://docs.victoriametrics.com/enterprise.html (default 300000)
   -search.maxLookback duration
      Synonym to -search.lookback-delta from Prometheus. The value is dynamically detected from interval between time series datapoints if not set. It can be overridden on per-query basis via max_lookback arg. See also '-search.maxStalenessInterval' flag, which has the same meaining due to historical reasons
   -search.maxMemoryPerQuery size
diff --git a/docs/vmagent.md b/docs/vmagent.md
index 29052bc08..60e3faf6d 100644
--- a/docs/vmagent.md
+++ b/docs/vmagent.md
@@ -1111,6 +1111,8 @@ vmagent collects metrics data via popular data ingestion protocols and routes th
 
 See the docs at https://docs.victoriametrics.com/vmagent.html .
 
+  -cacheExpireDuration duration
+     Items are removed from in-memory caches after they aren't accessed for this duration. Lower values may reduce memory usage at the cost of higher CPU usage. See also -prevCacheRemovalPercent (default 30m0s)
   -configAuthKey string
      Authorization key for accessing /config page. It must be passed via authKey query arg
   -csvTrimTimestamp duration
@@ -1131,7 +1133,7 @@ See the docs at https://docs.victoriametrics.com/vmagent.html .
   -envflag.prefix string
      Prefix for environment variables if -envflag.enable is set
   -eula
-     By specifying this flag, you confirm that you have an enterprise license and accept the EULA https://victoriametrics.com/assets/VM_EULA.pdf . This flag is available only in enterprise version of VictoriaMetrics
+     By specifying this flag, you confirm that you have an enterprise license and accept the EULA https://victoriametrics.com/assets/VM_EULA.pdf . This flag is available only in VictoriaMetrics enterprise. See https://docs.victoriametrics.com/enterprise.html
   -flagsAuthKey string
      Auth key for /flags endpoint. It must be passed via authKey query arg. It overrides httpAuth.* settings
   -fs.disableMmap
@@ -1182,30 +1184,30 @@ See the docs at https://docs.victoriametrics.com/vmagent.html .
   -insert.maxQueueDuration duration
      The maximum duration for waiting in the queue for insert requests due to -maxConcurrentInserts (default 1m0s)
   -kafka.consumer.topic array
-     Kafka topic names for data consumption. This flag is available only in enterprise version of VictoriaMetrics
+     Kafka topic names for data consumption. This flag is available only in VictoriaMetrics enterprise. See https://docs.victoriametrics.com/enterprise.html
      Supports an array of values separated by comma or specified via multiple flags.
   -kafka.consumer.topic.basicAuth.password array
-     Optional basic auth password for -kafka.consumer.topic. Must be used in conjunction with any supported auth methods for kafka client, specified by flag -kafka.consumer.topic.options='security.protocol=SASL_SSL;sasl.mechanisms=PLAIN' . This flag is available only in enterprise version of VictoriaMetrics
+     Optional basic auth password for -kafka.consumer.topic. Must be used in conjunction with any supported auth methods for kafka client, specified by flag -kafka.consumer.topic.options='security.protocol=SASL_SSL;sasl.mechanisms=PLAIN' . This flag is available only in VictoriaMetrics enterprise. See https://docs.victoriametrics.com/enterprise.html
      Supports an array of values separated by comma or specified via multiple flags.
   -kafka.consumer.topic.basicAuth.username array
-     Optional basic auth username for -kafka.consumer.topic. Must be used in conjunction with any supported auth methods for kafka client, specified by flag -kafka.consumer.topic.options='security.protocol=SASL_SSL;sasl.mechanisms=PLAIN' . This flag is available only in enterprise version of VictoriaMetrics
+     Optional basic auth username for -kafka.consumer.topic. Must be used in conjunction with any supported auth methods for kafka client, specified by flag -kafka.consumer.topic.options='security.protocol=SASL_SSL;sasl.mechanisms=PLAIN' . This flag is available only in VictoriaMetrics enterprise. See https://docs.victoriametrics.com/enterprise.html
      Supports an array of values separated by comma or specified via multiple flags.
   -kafka.consumer.topic.brokers array
-     List of brokers to connect for given topic, e.g. -kafka.consumer.topic.broker=host-1:9092;host-2:9092 . This flag is available only in enterprise version of VictoriaMetrics
+     List of brokers to connect for given topic, e.g. -kafka.consumer.topic.broker=host-1:9092;host-2:9092 . This flag is available only in VictoriaMetrics enterprise. See https://docs.victoriametrics.com/enterprise.html
      Supports an array of values separated by comma or specified via multiple flags.
   -kafka.consumer.topic.defaultFormat string
-     Expected data format in the topic if -kafka.consumer.topic.format is skipped. This flag is available only in enterprise version of VictoriaMetrics (default "promremotewrite")
+     Expected data format in the topic if -kafka.consumer.topic.format is skipped. This flag is available only in VictoriaMetrics enterprise. See https://docs.victoriametrics.com/enterprise.html (default "promremotewrite")
   -kafka.consumer.topic.format array
-     data format for corresponding kafka topic. Valid formats: influx, prometheus, promremotewrite, graphite, jsonline . This flag is available only in enterprise version of VictoriaMetrics
+     data format for corresponding kafka topic. Valid formats: influx, prometheus, promremotewrite, graphite, jsonline . This flag is available only in VictoriaMetrics enterprise. See https://docs.victoriametrics.com/enterprise.html
      Supports an array of values separated by comma or specified via multiple flags.
   -kafka.consumer.topic.groupID array
-     Defines group.id for topic. This flag is available only in enterprise version of VictoriaMetrics
+     Defines group.id for topic. This flag is available only in VictoriaMetrics enterprise. See https://docs.victoriametrics.com/enterprise.html
      Supports an array of values separated by comma or specified via multiple flags.
   -kafka.consumer.topic.isGzipped array
-     Enables gzip setting for topic messages payload. Only prometheus, jsonline and influx formats accept gzipped messages.This flag is available only in enterprise version of VictoriaMetrics
+     Enables gzip setting for topic messages payload. Only prometheus, jsonline and influx formats accept gzipped messages.This flag is available only in VictoriaMetrics enterprise. See https://docs.victoriametrics.com/enterprise.html
      Supports array of values separated by comma or specified via multiple flags.
   -kafka.consumer.topic.options array
-     Optional key=value;key1=value2 settings for topic consumer. See full configuration options at https://github.com/edenhill/librdkafka/blob/master/CONFIGURATION.md . This flag is available only in enterprise version of VictoriaMetrics
+     Optional key=value;key1=value2 settings for topic consumer. See full configuration options at https://github.com/edenhill/librdkafka/blob/master/CONFIGURATION.md . This flag is available only in VictoriaMetrics enterprise. See https://docs.victoriametrics.com/enterprise.html
      Supports an array of values separated by comma or specified via multiple flags.
   -loggerDisableTimestamps
      Whether to disable writing timestamps in logs
@@ -1246,6 +1248,8 @@ See the docs at https://docs.victoriametrics.com/vmagent.html .
      Trim timestamps for OpenTSDB HTTP data to this duration. Minimum practical duration is 1ms. Higher duration (i.e. 1s) may be used for reducing disk space usage for timestamp data (default 1ms)
   -pprofAuthKey string
      Auth key for /debug/pprof/* endpoints. It must be passed via authKey query arg. It overrides httpAuth.* settings
+  -prevCacheRemovalPercent float
+     Items in the previous caches are removed when the percent of requests it serves becomes lower than this value. Higher values reduce memory usage at the cost of higher CPU usage. See also -cacheExpireDuration (default 0.1)
   -promscrape.azureSDCheckInterval duration
      Interval for checking for changes in Azure. This works only if azure_sd_configs is configured in '-promscrape.config' file. See https://docs.victoriametrics.com/sd_configs.html#azure_sd_configs for details (default 1m0s)
   -promscrape.cluster.memberNum string
diff --git a/docs/vmalert.md b/docs/vmalert.md
index 319f6f479..60402d01d 100644
--- a/docs/vmalert.md
+++ b/docs/vmalert.md
@@ -677,10 +677,12 @@ See full description for these flags in `./vmalert -help`.
 ## Monitoring
 
 `vmalert` exports various metrics in Prometheus exposition format at `http://vmalert-host:8880/metrics` page.
+The default list of alerting rules for these metric can be found [here](https://github.com/VictoriaMetrics/VictoriaMetrics/tree/master/deployment/docker).
 We recommend setting up regular scraping of this page either through `vmagent` or by Prometheus so that the exported
 metrics may be analyzed later.
 
-Use the official [Grafana dashboard](https://grafana.com/grafana/dashboards/14950) for `vmalert` overview. Graphs on this dashboard contain useful hints - hover the `i` icon at the top left corner of each graph in order to read it.
+Use the official [Grafana dashboard](https://grafana.com/grafana/dashboards/14950) for `vmalert` overview. 
+Graphs on this dashboard contain useful hints - hover the `i` icon in the top left corner of each graph in order to read it.
 If you have suggestions for improvements or have found a bug - please open an issue on github or add
 a review to the dashboard.
 
@@ -785,7 +787,7 @@ The shortlist of configuration flags is the following:
 {% raw  %}
 ```
   -clusterMode
-     If clusterMode is enabled, then vmalert automatically adds the tenant specified in config groups to -datasource.url, -remoteWrite.url and -remoteRead.url. See https://docs.victoriametrics.com/vmalert.html#multitenancy . This flag is available only in enterprise version of VictoriaMetrics
+     If clusterMode is enabled, then vmalert automatically adds the tenant specified in config groups to -datasource.url, -remoteWrite.url and -remoteRead.url. See https://docs.victoriametrics.com/vmalert.html#multitenancy . This flag is available only in VictoriaMetrics enterprise. See https://docs.victoriametrics.com/enterprise.html
   -configCheckInterval duration
      Interval for checking for changes in '-rule' or '-notifier.config' files. By default the checking is disabled. Send SIGHUP signal in order to force config check for changes.
   -datasource.appendTypePrefix
@@ -809,11 +811,11 @@ The shortlist of configuration flags is the following:
   -datasource.maxIdleConnections int
      Defines the number of idle (keep-alive connections) to each configured datasource. Consider setting this value equal to the value: groups_total * group.concurrency. Too low a value may result in a high number of sockets in TIME_WAIT state. (default 100)
   -datasource.oauth2.clientID string
-     Optional OAuth2 clientID to use for -datasource.url.
+     Optional OAuth2 clientID to use for -datasource.url. 
   -datasource.oauth2.clientSecret string
      Optional OAuth2 clientSecret to use for -datasource.url.
   -datasource.oauth2.clientSecretFile string
-     Optional OAuth2 clientSecretFile to use for -datasource.url.
+     Optional OAuth2 clientSecretFile to use for -datasource.url. 
   -datasource.oauth2.scopes string
      Optional OAuth2 scopes to use for -datasource.url. Scopes must be delimited by ';'
   -datasource.oauth2.tokenUrl string
@@ -839,9 +841,9 @@ The shortlist of configuration flags is the following:
   -datasource.url string
      Datasource compatible with Prometheus HTTP API. It can be single node VictoriaMetrics or vmselect URL. Required parameter. E.g. http://127.0.0.1:8428 . See also '-datasource.disablePathAppend', '-datasource.showURL'.
   -defaultTenant.graphite string
-     Default tenant for Graphite alerting groups. See https://docs.victoriametrics.com/vmalert.html#multitenancy .This flag is available only in enterprise version of VictoriaMetrics
+     Default tenant for Graphite alerting groups. See https://docs.victoriametrics.com/vmalert.html#multitenancy .This flag is available only in VictoriaMetrics enterprise. See https://docs.victoriametrics.com/enterprise.html
   -defaultTenant.prometheus string
-     Default tenant for Prometheus alerting groups. See https://docs.victoriametrics.com/vmalert.html#multitenancy . This flag is available only in enterprise version of VictoriaMetrics
+     Default tenant for Prometheus alerting groups. See https://docs.victoriametrics.com/vmalert.html#multitenancy . This flag is available only in VictoriaMetrics enterprise. See https://docs.victoriametrics.com/enterprise.html
   -disableAlertgroupLabel
      Whether to disable adding group's Name as label to generated alerts and time series.
   -dryRun
@@ -853,12 +855,11 @@ The shortlist of configuration flags is the following:
   -envflag.prefix string
      Prefix for environment variables if -envflag.enable is set
   -eula
-     By specifying this flag, you confirm that you have an enterprise license and accept the EULA https://victoriametrics.com/assets/VM_EULA.pdf . This flag is available only in enterprise version of VictoriaMetrics
+     By specifying this flag, you confirm that you have an enterprise license and accept the EULA https://victoriametrics.com/assets/VM_EULA.pdf . This flag is available only in VictoriaMetrics enterprise. See https://docs.victoriametrics.com/enterprise.html
   -evaluationInterval duration
      How often to evaluate the rules (default 1m0s)
   -external.alert.source string
-     External Alert Source allows to override the Source link for alerts sent to AlertManager for cases where you want to build a custom link to Grafana, Prometheus or any other service. Supports templating - see https://docs.victoriametrics.com/vmalert.html#templating . For example, link to Grafana: -external.alert.source='explore?orgId=1&left=["now-1h","now","VictoriaMetrics",{"expr":{{$expr|jsonEscape|queryEscape}} },{"mode":"Metrics"},{"ui":[true,true,true,"none"]}]' . If empty 'vmalert/alert?group_id={{.GroupID}}&alert_id={{.AlertID}}' is used
-     If empty 'vmalert/alert?group_id={{.GroupID}}&alert_id={{.AlertID}}' is used.
+     External Alert Source allows to override the Source link for alerts sent to AlertManager for cases where you want to build a custom link to Grafana, Prometheus or any other service. Supports templating - see https://docs.victoriametrics.com/vmalert.html#templating . For example, link to Grafana: -external.alert.source='explore?orgId=1&left=["now-1h","now","VictoriaMetrics",{"expr":{{$expr|jsonEscape|queryEscape}} },{"mode":"Metrics"},{"ui":[true,true,true,"none"]}]' . If empty 'vmalert/alert?group_id={{.GroupID}}&alert_id={{.AlertID}}' is used.
   -external.label array
      Optional label in the form 'Name=value' to add to all generated recording rules and alerts. Pass multiple -label flags in order to add multiple label sets.
      Supports an array of values separated by comma or specified via multiple flags.
@@ -1006,7 +1007,7 @@ The shortlist of configuration flags is the following:
   -remoteRead.oauth2.scopes string
      Optional OAuth2 scopes to use for -remoteRead.url. Scopes must be delimited by ';'.
   -remoteRead.oauth2.tokenUrl string
-     Optional OAuth2 tokenURL to use for -remoteRead.url.
+     Optional OAuth2 tokenURL to use for -remoteRead.url. 
   -remoteRead.showURL
      Whether to show -remoteRead.url in the exported metrics. It is hidden by default, since it can contain sensitive info such as auth key
   -remoteRead.tlsCAFile string
diff --git a/docs/vmauth.md b/docs/vmauth.md
index 252d501fd..4912ca638 100644
--- a/docs/vmauth.md
+++ b/docs/vmauth.md
@@ -243,7 +243,7 @@ See the docs at https://docs.victoriametrics.com/vmauth.html .
   -envflag.prefix string
      Prefix for environment variables if -envflag.enable is set
   -eula
-     By specifying this flag, you confirm that you have an enterprise license and accept the EULA https://victoriametrics.com/assets/VM_EULA.pdf . This flag is available only in enterprise version of VictoriaMetrics
+     By specifying this flag, you confirm that you have an enterprise license and accept the EULA https://victoriametrics.com/assets/VM_EULA.pdf . This flag is available only in VictoriaMetrics enterprise. See https://docs.victoriametrics.com/enterprise.html
   -flagsAuthKey string
      Auth key for /flags endpoint. It must be passed via authKey query arg. It overrides httpAuth.* settings
   -fs.disableMmap
diff --git a/docs/vmbackup.md b/docs/vmbackup.md
index 5c4a901c7..2caffde57 100644
--- a/docs/vmbackup.md
+++ b/docs/vmbackup.md
@@ -200,7 +200,7 @@ See [this article](https://medium.com/@valyala/speeding-up-backups-for-big-time-
   -envflag.prefix string
      Prefix for environment variables if -envflag.enable is set
   -eula
-     By specifying this flag, you confirm that you have an enterprise license and accept the EULA https://victoriametrics.com/assets/VM_EULA.pdf . This flag is available only in enterprise version of VictoriaMetrics
+     By specifying this flag, you confirm that you have an enterprise license and accept the EULA https://victoriametrics.com/assets/VM_EULA.pdf . This flag is available only in VictoriaMetrics enterprise. See https://docs.victoriametrics.com/enterprise.html
   -flagsAuthKey string
      Auth key for /flags endpoint. It must be passed via authKey query arg. It overrides httpAuth.* settings
   -fs.disableMmap
diff --git a/docs/vmbackupmanager.md b/docs/vmbackupmanager.md
index 9b7a67294..4b8980a90 100644
--- a/docs/vmbackupmanager.md
+++ b/docs/vmbackupmanager.md
@@ -303,6 +303,13 @@ The shortlist of configuration flags is the following:
 ```
 vmbackupmanager performs regular backups according to the provided configs.
 
+subcommands:
+ backup: provides auxiliary backup-related commands
+ restore: restores backup specified by restore mark if it exists
+
+command-line flags:
+  -apiURL string
+     vmbackupmanager address to perform API requests (default "http://127.0.0.1:8300")
   -concurrency int
      The number of concurrent workers. Higher concurrency may reduce backup duration (default 10)
   -configFilePath string
@@ -332,7 +339,7 @@ vmbackupmanager performs regular backups according to the provided configs.
   -envflag.prefix string
      Prefix for environment variables if -envflag.enable is set
   -eula
-     By specifying this flag, you confirm that you have an enterprise license and accept the EULA https://victoriametrics.com/assets/VM_EULA.pdf . This flag is available only in enterprise version of VictoriaMetrics
+     By specifying this flag, you confirm that you have an enterprise license and accept the EULA https://victoriametrics.com/assets/VM_EULA.pdf . This flag is available only in VictoriaMetrics enterprise. See https://docs.victoriametrics.com/enterprise.html
   -flagsAuthKey string
      Auth key for /flags endpoint. It must be passed via authKey query arg. It overrides httpAuth.* settings
   -fs.disableMmap
@@ -396,8 +403,6 @@ vmbackupmanager performs regular backups according to the provided configs.
   -pushmetrics.url array
      Optional URL to push metrics exposed at /metrics page. See https://docs.victoriametrics.com/#push-metrics . By default metrics exposed at /metrics page aren't pushed to any remote storage
      Supports an array of values separated by comma or specified via multiple flags.
-  -restoreOnStart
-     Check if backup restore was requested and restore requested backup.
   -runOnStart
      Upload backups immediately after start of the service. Otherwise the backup starts on new hour
   -s3ForcePathStyle
diff --git a/docs/vmgateway.md b/docs/vmgateway.md
index 93f6dc45f..19c9a4ed4 100644
--- a/docs/vmgateway.md
+++ b/docs/vmgateway.md
@@ -180,8 +180,8 @@ curl 'http://localhost:8431/api/v1/labels' -H 'Authorization: Bearer eyJhbGciOiJ
 The shortlist of configuration flags include the following:
 
 ```console
-  -auth.httpHeader
-    HTTP header name to look for JWT authorization token
+  -auth.httpHeader string
+     HTTP header name to look for JWT authorization token (default "Authorization")
   -clusterMode
      enable this for the cluster version
   -datasource.appendTypePrefix
@@ -205,17 +205,17 @@ The shortlist of configuration flags include the following:
   -datasource.maxIdleConnections int
      Defines the number of idle (keep-alive connections) to each configured datasource. Consider setting this value equal to the value: groups_total * group.concurrency. Too low a value may result in a high number of sockets in TIME_WAIT state. (default 100)
   -datasource.oauth2.clientID string
-     Optional OAuth2 clientID to use for -datasource.url.
+     Optional OAuth2 clientID to use for -datasource.url. 
   -datasource.oauth2.clientSecret string
      Optional OAuth2 clientSecret to use for -datasource.url.
   -datasource.oauth2.clientSecretFile string
-     Optional OAuth2 clientSecretFile to use for -datasource.url.
+     Optional OAuth2 clientSecretFile to use for -datasource.url. 
   -datasource.oauth2.scopes string
      Optional OAuth2 scopes to use for -datasource.url. Scopes must be delimited by ';'
   -datasource.oauth2.tokenUrl string
      Optional OAuth2 tokenURL to use for -datasource.url.
   -datasource.queryStep duration
-     queryStep defines how far a value can fallback to when evaluating queries. For example, if datasource.queryStep=15s then param "step" with value "15s" will be added to every query.If queryStep isn't specified, rule's evaluationInterval will be used instead.
+     How far a value can fallback to when evaluating queries. For example, if -datasource.queryStep=15s then param "step" with value "15s" will be added to every query. If set to 0, rule's evaluation interval will be used instead. (default 5m0s)
   -datasource.queryTimeAlignment
      Whether to align "time" parameter with evaluation interval.Alignment supposed to produce deterministic results despite of number of vmalert replicas or time they were started. See more details here https://github.com/VictoriaMetrics/VictoriaMetrics/pull/1257 (default true)
   -datasource.roundDigits int
@@ -245,7 +245,7 @@ The shortlist of configuration flags include the following:
   -envflag.prefix string
      Prefix for environment variables if -envflag.enable is set
   -eula
-     By specifying this flag, you confirm that you have an enterprise license and accept the EULA https://victoriametrics.com/assets/VM_EULA.pdf . This flag is available only in enterprise version of VictoriaMetrics
+     By specifying this flag, you confirm that you have an enterprise license and accept the EULA https://victoriametrics.com/assets/VM_EULA.pdf . This flag is available only in VictoriaMetrics enterprise. See https://docs.victoriametrics.com/enterprise.html
   -flagsAuthKey string
      Auth key for /flags endpoint. It must be passed via authKey query arg. It overrides httpAuth.* settings
   -fs.disableMmap
diff --git a/docs/vmrestore.md b/docs/vmrestore.md
index 3a8f25352..23d3e98f3 100644
--- a/docs/vmrestore.md
+++ b/docs/vmrestore.md
@@ -104,7 +104,7 @@ i.e. the end result would be similar to [rsync --delete](https://askubuntu.com/q
   -envflag.prefix string
      Prefix for environment variables if -envflag.enable is set
   -eula
-     By specifying this flag, you confirm that you have an enterprise license and accept the EULA https://victoriametrics.com/assets/VM_EULA.pdf . This flag is available only in enterprise version of VictoriaMetrics
+     By specifying this flag, you confirm that you have an enterprise license and accept the EULA https://victoriametrics.com/assets/VM_EULA.pdf . This flag is available only in VictoriaMetrics enterprise. See https://docs.victoriametrics.com/enterprise.html
   -flagsAuthKey string
      Auth key for /flags endpoint. It must be passed via authKey query arg. It overrides httpAuth.* settings
   -fs.disableMmap
diff --git a/go.mod b/go.mod
index 0c8db875c..4ec30937b 100644
--- a/go.mod
+++ b/go.mod
@@ -12,7 +12,7 @@ require (
 	// like https://github.com/valyala/fasthttp/commit/996610f021ff45fdc98c2ce7884d5fa4e7f9199b
 	github.com/VictoriaMetrics/fasthttp v1.1.0
 	github.com/VictoriaMetrics/metrics v1.23.0
-	github.com/VictoriaMetrics/metricsql v0.47.0
+	github.com/VictoriaMetrics/metricsql v0.49.0
 	github.com/aws/aws-sdk-go-v2 v1.17.1
 	github.com/aws/aws-sdk-go-v2/config v1.18.1
 	github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.11.40
diff --git a/go.sum b/go.sum
index 62b35fb06..9ecd8cf86 100644
--- a/go.sum
+++ b/go.sum
@@ -100,8 +100,8 @@ github.com/VictoriaMetrics/fasthttp v1.1.0/go.mod h1:/7DMcogqd+aaD3G3Hg5kFgoFwlR
 github.com/VictoriaMetrics/metrics v1.18.1/go.mod h1:ArjwVz7WpgpegX/JpB0zpNF2h2232kErkEnzH1sxMmA=
 github.com/VictoriaMetrics/metrics v1.23.0 h1:WzfqyzCaxUZip+OBbg1+lV33WChDSu4ssYII3nxtpeA=
 github.com/VictoriaMetrics/metrics v1.23.0/go.mod h1:rAr/llLpEnAdTehiNlUxKgnjcOuROSzpw0GvjpEbvFc=
-github.com/VictoriaMetrics/metricsql v0.47.0 h1:PQwadjoQnKKkaUiupkDq0ZbCAHX2qP8OOexJ9oJwupo=
-github.com/VictoriaMetrics/metricsql v0.47.0/go.mod h1:6pP1ZeLVJHqJrHlF6Ij3gmpQIznSsgktEcZgsAWYel0=
+github.com/VictoriaMetrics/metricsql v0.49.0 h1:7R04eab3gU0PKu8Ksak7SJnORXm0K+hSGt2+t3XGyKg=
+github.com/VictoriaMetrics/metricsql v0.49.0/go.mod h1:6pP1ZeLVJHqJrHlF6Ij3gmpQIznSsgktEcZgsAWYel0=
 github.com/VividCortex/ewma v1.1.1/go.mod h1:2Tkkvm3sRDVXaiyucHiACn4cqf7DpdyLvmxzcbUokwA=
 github.com/VividCortex/ewma v1.2.0 h1:f58SaIzcDXrSy3kWaHNvuJgJ3Nmz59Zji6XoJR/q1ow=
 github.com/VividCortex/ewma v1.2.0/go.mod h1:nz4BbCtbLyFDeC9SUHbtcT5644juEuWfUAUnGx7j5l4=
diff --git a/lib/promscrape/discovery/gce/api.go b/lib/promscrape/discovery/gce/api.go
index fdf373901..fc6c51438 100644
--- a/lib/promscrape/discovery/gce/api.go
+++ b/lib/promscrape/discovery/gce/api.go
@@ -58,7 +58,9 @@ func newAPIConfig(sdc *SDConfig) (*apiConfig, error) {
 		logger.Infof("autodetected the current GCE zone: %q", zone)
 	} else if len(zones) == 1 && zones[0] == "*" {
 		// Autodetect zones for project.
-		zs, err := getZonesForProject(client, project, sdc.Filter)
+		// Do not pass sdc.Filter when discovering zones, since GCE doesn't support it.
+		// See https://github.com/VictoriaMetrics/VictoriaMetrics/issues/3202
+		zs, err := getZonesForProject(client, project)
 		if err != nil {
 			return nil, fmt.Errorf("cannot obtain zones for project %q: %w", project, err)
 		}
diff --git a/lib/promscrape/discovery/gce/zone.go b/lib/promscrape/discovery/gce/zone.go
index b949bab9e..b3144656c 100644
--- a/lib/promscrape/discovery/gce/zone.go
+++ b/lib/promscrape/discovery/gce/zone.go
@@ -6,13 +6,13 @@ import (
 	"net/http"
 )
 
-func getZonesForProject(client *http.Client, project, filter string) ([]string, error) {
+func getZonesForProject(client *http.Client, project string) ([]string, error) {
 	// See https://cloud.google.com/compute/docs/reference/rest/v1/zones
 	zonesURL := fmt.Sprintf("https://compute.googleapis.com/compute/v1/projects/%s/zones", project)
 	var zones []string
 	pageToken := ""
 	for {
-		data, err := getAPIResponse(client, zonesURL, filter, pageToken)
+		data, err := getAPIResponse(client, zonesURL, "", pageToken)
 		if err != nil {
 			return nil, fmt.Errorf("cannot obtain zones: %w", err)
 		}
diff --git a/vendor/github.com/VictoriaMetrics/metricsql/lexer.go b/vendor/github.com/VictoriaMetrics/metricsql/lexer.go
index 947da2c53..c1a0ec69b 100644
--- a/vendor/github.com/VictoriaMetrics/metricsql/lexer.go
+++ b/vendor/github.com/VictoriaMetrics/metricsql/lexer.go
@@ -149,6 +149,73 @@ func scanString(s string) (string, error) {
 	}
 }
 
+func parsePositiveNumber(s string) (float64, error) {
+	if isSpecialIntegerPrefix(s) {
+		n, err := strconv.ParseInt(s, 0, 64)
+		if err != nil {
+			return 0, err
+		}
+		return float64(n), nil
+	}
+	s = strings.ToLower(s)
+	m := float64(1)
+	switch true {
+	case strings.HasSuffix(s, "kib"):
+		s = s[:len(s)-3]
+		m = 1024
+	case strings.HasSuffix(s, "ki"):
+		s = s[:len(s)-2]
+		m = 1024
+	case strings.HasSuffix(s, "kb"):
+		s = s[:len(s)-2]
+		m = 1000
+	case strings.HasSuffix(s, "k"):
+		s = s[:len(s)-1]
+		m = 1000
+	case strings.HasSuffix(s, "mib"):
+		s = s[:len(s)-3]
+		m = 1024 * 1024
+	case strings.HasSuffix(s, "mi"):
+		s = s[:len(s)-2]
+		m = 1024 * 1024
+	case strings.HasSuffix(s, "mb"):
+		s = s[:len(s)-2]
+		m = 1000 * 1000
+	case strings.HasSuffix(s, "m"):
+		s = s[:len(s)-1]
+		m = 1000 * 1000
+	case strings.HasSuffix(s, "gib"):
+		s = s[:len(s)-3]
+		m = 1024 * 1024 * 1024
+	case strings.HasSuffix(s, "gi"):
+		s = s[:len(s)-2]
+		m = 1024 * 1024 * 1024
+	case strings.HasSuffix(s, "gb"):
+		s = s[:len(s)-2]
+		m = 1000 * 1000 * 1000
+	case strings.HasSuffix(s, "g"):
+		s = s[:len(s)-1]
+		m = 1000 * 1000 * 1000
+	case strings.HasSuffix(s, "tib"):
+		s = s[:len(s)-3]
+		m = 1024 * 1024 * 1024 * 1024
+	case strings.HasSuffix(s, "ti"):
+		s = s[:len(s)-2]
+		m = 1024 * 1024 * 1024 * 1024
+	case strings.HasSuffix(s, "tb"):
+		s = s[:len(s)-2]
+		m = 1000 * 1000 * 1000 * 1000
+	case strings.HasSuffix(s, "t"):
+		s = s[:len(s)-1]
+		m = 1000 * 1000 * 1000 * 1000
+	}
+	v, err := strconv.ParseFloat(s, 64)
+	if err != nil {
+		return 0, err
+	}
+	return v * m, nil
+}
+
 func scanPositiveNumber(s string) (string, error) {
 	// Scan integer part. It may be empty if fractional part exists.
 	i := 0
@@ -171,7 +238,14 @@ func scanPositiveNumber(s string) (string, error) {
 		}
 		return s, nil
 	}
+	if sLen := scanNumMultiplier(s[i:]); sLen > 0 {
+		i += sLen
+		return s[:i], nil
+	}
 	if s[i] != '.' && s[i] != 'e' && s[i] != 'E' {
+		if i == 0 {
+			return "", fmt.Errorf("missing positive number")
+		}
 		return s[:i], nil
 	}
 
@@ -182,14 +256,15 @@ func scanPositiveNumber(s string) (string, error) {
 		for j < len(s) && isDecimalChar(s[j]) {
 			j++
 		}
-		if j == i {
-			return "", fmt.Errorf("missing fractional part in %q", s)
-		}
 		i = j
 		if i == len(s) {
 			return s, nil
 		}
 	}
+	if sLen := scanNumMultiplier(s[i:]); sLen > 0 {
+		i += sLen
+		return s[:i], nil
+	}
 
 	if s[i] != 'e' && s[i] != 'E' {
 		return s[:i], nil
@@ -213,6 +288,46 @@ func scanPositiveNumber(s string) (string, error) {
 	return s[:j], nil
 }
 
+func scanNumMultiplier(s string) int {
+	s = strings.ToLower(s)
+	switch true {
+	case strings.HasPrefix(s, "kib"):
+		return 3
+	case strings.HasPrefix(s, "ki"):
+		return 2
+	case strings.HasPrefix(s, "kb"):
+		return 2
+	case strings.HasPrefix(s, "k"):
+		return 1
+	case strings.HasPrefix(s, "mib"):
+		return 3
+	case strings.HasPrefix(s, "mi"):
+		return 2
+	case strings.HasPrefix(s, "mb"):
+		return 2
+	case strings.HasPrefix(s, "m"):
+		return 1
+	case strings.HasPrefix(s, "gib"):
+		return 3
+	case strings.HasPrefix(s, "gi"):
+		return 2
+	case strings.HasPrefix(s, "gb"):
+		return 2
+	case strings.HasPrefix(s, "g"):
+		return 1
+	case strings.HasPrefix(s, "tib"):
+		return 3
+	case strings.HasPrefix(s, "ti"):
+		return 2
+	case strings.HasPrefix(s, "tb"):
+		return 2
+	case strings.HasPrefix(s, "t"):
+		return 1
+	default:
+		return 0
+	}
+}
+
 func scanIdent(s string) string {
 	i := 0
 	for i < len(s) {
diff --git a/vendor/github.com/VictoriaMetrics/metricsql/optimizer.go b/vendor/github.com/VictoriaMetrics/metricsql/optimizer.go
index e56659b86..3a432e63e 100644
--- a/vendor/github.com/VictoriaMetrics/metricsql/optimizer.go
+++ b/vendor/github.com/VictoriaMetrics/metricsql/optimizer.go
@@ -386,7 +386,7 @@ func getTransformArgIdxForOptimization(funcName string, args []Expr) int {
 		return -1
 	}
 	switch funcName {
-	case "", "absent", "scalar", "union", "vector":
+	case "", "absent", "scalar", "union", "vector", "range_normalize":
 		return -1
 	case "end", "now", "pi", "ru", "start", "step", "time":
 		return -1
diff --git a/vendor/github.com/VictoriaMetrics/metricsql/parser.go b/vendor/github.com/VictoriaMetrics/metricsql/parser.go
index ac64fc438..9b92dbabb 100644
--- a/vendor/github.com/VictoriaMetrics/metricsql/parser.go
+++ b/vendor/github.com/VictoriaMetrics/metricsql/parser.go
@@ -479,24 +479,19 @@ func (p *parser) parsePositiveNumberExpr() (*NumberExpr, error) {
 	if !isPositiveNumberPrefix(p.lex.Token) && !isInfOrNaN(p.lex.Token) {
 		return nil, fmt.Errorf(`positiveNumberExpr: unexpected token %q; want "number"`, p.lex.Token)
 	}
-	var ne NumberExpr
-	if isSpecialIntegerPrefix(p.lex.Token) {
-		in, err := strconv.ParseInt(p.lex.Token, 0, 64)
-		if err != nil {
-			return nil, fmt.Errorf(`positiveNumberExpr: cannot parse integer %q: %s`, p.lex.Token, err)
-		}
-		ne.N = float64(in)
-	} else {
-		n, err := strconv.ParseFloat(p.lex.Token, 64)
-		if err != nil {
-			return nil, fmt.Errorf(`positiveNumberExpr: cannot parse %q: %s`, p.lex.Token, err)
-		}
-		ne.N = n
+	s := p.lex.Token
+	n, err := parsePositiveNumber(s)
+	if err != nil {
+		return nil, fmt.Errorf(`positivenumberExpr: cannot parse %q: %s`, s, err)
 	}
 	if err := p.lex.Next(); err != nil {
 		return nil, err
 	}
-	return &ne, nil
+	ne := &NumberExpr{
+		N: n,
+		s: s,
+	}
+	return ne, nil
 }
 
 func (p *parser) parseStringExpr() (*StringExpr, error) {
@@ -1499,10 +1494,16 @@ func (se *StringExpr) AppendString(dst []byte) []byte {
 type NumberExpr struct {
 	// N is the parsed number, i.e. `1.23`, `-234`, etc.
 	N float64
+
+	// s contains the original string representation for N.
+	s string
 }
 
 // AppendString appends string representation of ne to dst and returns the result.
 func (ne *NumberExpr) AppendString(dst []byte) []byte {
+	if ne.s != "" {
+		return append(dst, ne.s...)
+	}
 	return strconv.AppendFloat(dst, ne.N, 'g', -1, 64)
 }
 
diff --git a/vendor/github.com/VictoriaMetrics/metricsql/transform.go b/vendor/github.com/VictoriaMetrics/metricsql/transform.go
index 40d315832..5876c8290 100644
--- a/vendor/github.com/VictoriaMetrics/metricsql/transform.go
+++ b/vendor/github.com/VictoriaMetrics/metricsql/transform.go
@@ -76,6 +76,7 @@ var transformFuncs = map[string]bool{
 	"range_linear_regression":    true,
 	"range_max":                  true,
 	"range_min":                  true,
+	"range_normalize":            true,
 	"range_quantile":             true,
 	"range_stddev":               true,
 	"range_stdvar":               true,
diff --git a/vendor/modules.txt b/vendor/modules.txt
index 17b3e4dce..c172a7d07 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -69,7 +69,7 @@ github.com/VictoriaMetrics/fasthttp/stackless
 # github.com/VictoriaMetrics/metrics v1.23.0
 ## explicit; go 1.15
 github.com/VictoriaMetrics/metrics
-# github.com/VictoriaMetrics/metricsql v0.47.0
+# github.com/VictoriaMetrics/metricsql v0.49.0
 ## explicit; go 1.13
 github.com/VictoriaMetrics/metricsql
 github.com/VictoriaMetrics/metricsql/binaryop


Test patch:
diff --git a/app/vmselect/promql/exec_test.go b/app/vmselect/promql/exec_test.go
index ed04ba369..49eb8d540 100644
--- a/app/vmselect/promql/exec_test.go
+++ b/app/vmselect/promql/exec_test.go
@@ -2281,6 +2281,16 @@ func TestExecSuccess(t *testing.T) {
 		resultExpected := []netstorage.Result{r}
 		f(q, resultExpected)
 	})
+	t.Run(`limit_offset(too-big-offset)`, func(t *testing.T) {
+		t.Parallel()
+		q := `limit_offset(1, 10, sort_by_label((
+			label_set(time()*1, "foo", "y"),
+			label_set(time()*2, "foo", "a"),
+			label_set(time()*3, "foo", "x"),
+		), "foo"))`
+		resultExpected := []netstorage.Result{}
+		f(q, resultExpected)
+	})
 	t.Run(`limit_offset NaN`, func(t *testing.T) {
 		t.Parallel()
 		// q returns 3 time series, where foo=3 contains only NaN values
@@ -6892,6 +6902,23 @@ func TestExecSuccess(t *testing.T) {
 		resultExpected := []netstorage.Result{r}
 		f(q, resultExpected)
 	})
+	t.Run(`range_normalize(time(),alias(-time(),"negative"))`, func(t *testing.T) {
+		t.Parallel()
+		q := `range_normalize(time(),alias(-time(), "negative"))`
+		r1 := netstorage.Result{
+			MetricName: metricNameExpected,
+			Values:     []float64{0, 0.2, 0.4, 0.6, 0.8, 1},
+			Timestamps: timestampsExpected,
+		}
+		r2 := netstorage.Result{
+			MetricName: metricNameExpected,
+			Values:     []float64{1, 0.8, 0.6, 0.4, 0.2, 0},
+			Timestamps: timestampsExpected,
+		}
+		r2.MetricName.MetricGroup = []byte("negative")
+		resultExpected := []netstorage.Result{r1, r2}
+		f(q, resultExpected)
+	})
 	t.Run(`range_first(time())`, func(t *testing.T) {
 		t.Parallel()
 		q := `range_first(time())`