Repository: VictoriaMetrics/VictoriaMetrics
Pull request #5119 (2023-10-03 14:54:35)

app/vmselect: reduce lock contention for heavy aggregation requests
previously lock contetion may happen on machine with big number of CPU due to enabled string interning. sync.Map was a choke point for all aggregation requests. Now instead of interning, new string is created. It may increase CPU and memory usage for some cases. https://github.com/VictoriaMetrics/VictoriaMetrics/issues/5087

codecov[bot]: ## [Codecov](https://app.codecov.io/gh/VictoriaMetrics/VictoriaMetrics/pull/5119?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=VictoriaMetrics) Report
Attention: `7 lines` in your changes are missing coverage. Please review.
> Comparison is base [(`dc71db9`)](https://app.codecov.io/gh/VictoriaMetrics/VictoriaMetrics/commit/dc71db94705206967f652608acb44e59796b4df3?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=VictoriaMetrics) 59.11% compared to head [(`6d6939c`)](https://app.codecov.io/gh/VictoriaMetrics/VictoriaMetrics/pull/5119?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=VictoriaMetrics) 59.12%.

<details><summary>Additional details and impacted files</summary>


```diff
@@             Coverage Diff             @@
##           cluster    #5119      +/-   ##
===========================================
+ Coverage    59.11%   59.12%   +0.01%     
===========================================
  Files          398      398              
  Lines        75404    75411       +7     
===========================================
+ Hits         44575    44587      +12     
+ Misses       28382    28377       -5     
  Partials      2447     2447              
```


| [Files](https://app.codecov.io/gh/VictoriaMetrics/VictoriaMetrics/pull/5119?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=VictoriaMetrics) | Coverage Δ | |
|---|---|---|
| [app/vmselect/promql/aggr.go](https://app.codecov.io/gh/VictoriaMetrics/VictoriaMetrics/pull/5119?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=VictoriaMetrics#diff-YXBwL3Ztc2VsZWN0L3Byb21xbC9hZ2dyLmdv) | `87.58% <100.00%> (ø)` | |
| [app/vmselect/promql/aggr\_incremental.go](https://app.codecov.io/gh/VictoriaMetrics/VictoriaMetrics/pull/5119?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=VictoriaMetrics#diff-YXBwL3Ztc2VsZWN0L3Byb21xbC9hZ2dyX2luY3JlbWVudGFsLmdv) | `79.39% <100.00%> (-0.91%)` | :arrow_down: |
| [app/vmselect/promql/binary\_op.go](https://app.codecov.io/gh/VictoriaMetrics/VictoriaMetrics/pull/5119?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=VictoriaMetrics#diff-YXBwL3Ztc2VsZWN0L3Byb21xbC9iaW5hcnlfb3AuZ28=) | `90.69% <100.00%> (ø)` | |
| [app/vmselect/promql/eval.go](https://app.codecov.io/gh/VictoriaMetrics/VictoriaMetrics/pull/5119?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=VictoriaMetrics#diff-YXBwL3Ztc2VsZWN0L3Byb21xbC9ldmFsLmdv) | `61.13% <100.00%> (ø)` | |
| [app/vmselect/promql/exec.go](https://app.codecov.io/gh/VictoriaMetrics/VictoriaMetrics/pull/5119?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=VictoriaMetrics#diff-YXBwL3Ztc2VsZWN0L3Byb21xbC9leGVjLmdv) | `80.22% <100.00%> (ø)` | |
| [app/vmselect/promql/rollup\_result\_cache.go](https://app.codecov.io/gh/VictoriaMetrics/VictoriaMetrics/pull/5119?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=VictoriaMetrics#diff-YXBwL3Ztc2VsZWN0L3Byb21xbC9yb2xsdXBfcmVzdWx0X2NhY2hlLmdv) | `60.00% <100.00%> (ø)` | |
| [app/vmselect/promql/transform.go](https://app.codecov.io/gh/VictoriaMetrics/VictoriaMetrics/pull/5119?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=VictoriaMetrics#diff-YXBwL3Ztc2VsZWN0L3Byb21xbC90cmFuc2Zvcm0uZ28=) | `88.15% <100.00%> (-0.15%)` | :arrow_down: |
| [lib/bytesutil/bytesutil.go](https://app.codecov.io/gh/VictoriaMetrics/VictoriaMetrics/pull/5119?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=VictoriaMetrics#diff-bGliL2J5dGVzdXRpbC9ieXRlc3V0aWwuZ28=) | `75.00% <0.00%> (-11.67%)` | :arrow_down: |

... and [9 files with indirect coverage changes](https://app.codecov.io/gh/VictoriaMetrics/VictoriaMetrics/pull/5119/indirect-changes?src=pr&el=tree-more&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=VictoriaMetrics)


</details>

[:umbrella: View full report in Codecov by Sentry](https://app.codecov.io/gh/VictoriaMetrics/VictoriaMetrics/pull/5119?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=VictoriaMetrics).   
:loudspeaker: Have feedback on the report? [Share it here](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=VictoriaMetrics).

f41gh7:  Also, memory usage may be decreased, if bytes pool will be used for local aggregation.

 For instance function `vmrangeBucketsToLE` uses keys for local aggregation and instead of reusing a single pool object:
```
bb.B = marshalMetricNameSorted(bb.B[:0], &ts.MetricName)
k := bytesutil.ToStringOwned(bb.B)
```
we can resize slice and use a tail for storing marshalled keys:
```
bb.B = resizeCopyMayOverAllocate(bb,B, some_size)
bb.B = marshalMetricNameSorted(bb.B[len(bb.B):], &ts.MetricName)
k := bytesutil.ToUnsafeString(bb.B)
```



Patch:
diff --git a/.gitignore b/.gitignore
index 96d97c523..a5c001917 100644
--- a/.gitignore
+++ b/.gitignore
@@ -22,3 +22,13 @@ Gemfile.lock
 /_site
 _site
 *.tmp
+
+# vm binaries
+app/victoria-metrics/victoria-metrics
+app/vmagent/vmagent
+app/vmctl/vmctl
+app/vmalert/vmalert
+
+# vm default data folder
+app/victoria-metrics/victoria-metrics-data/
+app/vmagent/vmagent-remotewrite-data/
\ No newline at end of file
diff --git a/README.md b/README.md
index 783c2a51f..e338f04ae 100644
--- a/README.md
+++ b/README.md
@@ -11,7 +11,19 @@ with the number of CPU cores, RAM and available storage space.
 The single-node version is easier to configure and operate compared to the cluster version, so think twice before choosing the cluster version.
 See [this question](https://docs.victoriametrics.com/FAQ.html#which-victoriametrics-type-is-recommended-for-use-in-production---single-node-or-cluster) for more details.
 
-Join [our Slack](https://slack.victoriametrics.com/) or [contact us](mailto:info@victoriametrics.com) with consulting and support questions.
+There is also user-friendly database for logs - [VictoriaLogs](https://docs.victoriametrics.com/VictoriaLogs/).
+
+If you have questions about VictoriaMetrics, then feel free asking them at [VictoriaMetrics community Slack chat](https://slack.victoriametrics.com/).
+
+[Contact us](mailto:info@victoriametrics.com) if you need enterprise support for VictoriaMetrics. 
+See [features available in enterprise package](https://docs.victoriametrics.com/enterprise.html).
+Enterprise binaries can be downloaded and evaluated for free 
+from [the releases page](https://github.com/VictoriaMetrics/VictoriaMetrics/releases).
+See how to request a free trial license [here](https://victoriametrics.com/products/enterprise/trial/).
+
+VictoriaMetrics is developed at a fast pace, so it is recommended periodically checking the [CHANGELOG](https://docs.victoriametrics.com/CHANGELOG.html) and performing [regular upgrades](#how-to-upgrade-victoriametrics).
+
+VictoriaMetrics has achieved security certifications for Database Software Development and Software-Based Monitoring Services. We apply strict security measures in everything we do. See our [Security page](https://victoriametrics.com/security/) for more details.
 
 ## Prominent features
 
@@ -913,11 +925,13 @@ Below is the output for `/path/to/vminsert -help`:
   -internStringMaxLen int
      The maximum length for strings to intern. A lower limit may save memory at the cost of higher CPU usage. See https://en.wikipedia.org/wiki/String_interning . See also -internStringDisableCache and -internStringCacheExpireDuration (default 500)
   -license string
-     See https://victoriametrics.com/products/enterprise/ for trial license. This flag is available only in VictoriaMetrics enterprise. See https://docs.victoriametrics.com/enterprise.html
+     enterprise license key. This flag is available only in VictoriaMetrics enterprise. Documentation - https://docs.victoriametrics.com/enterprise.html, for more information, visit  https://victoriametrics.com/products/enterprise/ . To request a trial license, go to https://victoriametrics.com/products/enterprise/trial/
   -license.forceOffline
-     See https://victoriametrics.com/products/enterprise/ for trial license. This flag is available only in VictoriaMetrics enterprise. See https://docs.victoriametrics.com/enterprise.html
+     enables offline license verification. License keys issued must support this feature. Contact our support team for license keys with offline check support.
   -licenseFile string
-     See https://victoriametrics.com/products/enterprise/ for trial license. This flag is available only in VictoriaMetrics enterprise. See https://docs.victoriametrics.com/enterprise.html
+     path to file with enterprise license key. This flag is available only in VictoriaMetrics enterprise. Documentation - https://docs.victoriametrics.com/enterprise.html, for more information, visit  https://victoriametrics.com/products/enterprise/ . To request a trial license, go to https://victoriametrics.com/products/enterprise/trial/
+  -logNewSeries
+     Whether to log new series. This option is for debug purposes only. It can lead to performance issues when big number of new series are ingested into VictoriaMetrics
   -loggerDisableTimestamps
      Whether to disable writing timestamps in logs
   -loggerErrorsPerSecondLimit int
diff --git a/app/vmagent/README.md b/app/vmagent/README.md
index 7f9fd0b8a..f1622c5ab 100644
--- a/app/vmagent/README.md
+++ b/app/vmagent/README.md
@@ -1027,6 +1027,7 @@ See also [troubleshooting docs](https://docs.victoriametrics.com/Troubleshooting
 
 The enterprise version of vmagent is available for evaluation at [releases](https://github.com/VictoriaMetrics/VictoriaMetrics/releases) page
 in `vmutils-...-enterprise.tar.gz` archives and in [docker images](https://hub.docker.com/r/victoriametrics/vmagent/tags) with tags containing `enterprise` suffix.
+See how to request a free trial license [here](https://victoriametrics.com/products/enterprise/trial/).
 
 ### Reading metrics from Kafka
 
@@ -1337,11 +1338,11 @@ See the docs at https://docs.victoriametrics.com/vmagent.html .
      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.
   -license string
-     See https://victoriametrics.com/products/enterprise/ for trial license. This flag is available only in VictoriaMetrics enterprise. See https://docs.victoriametrics.com/enterprise.html
+     enterprise license key. This flag is available only in VictoriaMetrics enterprise. Documentation - https://docs.victoriametrics.com/enterprise.html, for more information, visit  https://victoriametrics.com/products/enterprise/ . To request a trial license, go to https://victoriametrics.com/products/enterprise/trial/
   -license.forceOffline
-     See https://victoriametrics.com/products/enterprise/ for trial license. This flag is available only in VictoriaMetrics enterprise. See https://docs.victoriametrics.com/enterprise.html
+     enables offline license verification. License keys issued must support this feature. Contact our support team for license keys with offline check support.
   -licenseFile string
-     See https://victoriametrics.com/products/enterprise/ for trial license. This flag is available only in VictoriaMetrics enterprise. See https://docs.victoriametrics.com/enterprise.html
+     path to file with enterprise license key. This flag is available only in VictoriaMetrics enterprise. Documentation - https://docs.victoriametrics.com/enterprise.html, for more information, visit  https://victoriametrics.com/products/enterprise/ . To request a trial license, go to https://victoriametrics.com/products/enterprise/trial/
   -loggerDisableTimestamps
      Whether to disable writing timestamps in logs
   -loggerErrorsPerSecondLimit int
diff --git a/app/vmalert/README.md b/app/vmalert/README.md
index 1a6693aaa..7708e14f4 100644
--- a/app/vmalert/README.md
+++ b/app/vmalert/README.md
@@ -131,6 +131,15 @@ name: <string>
 # By default, "prometheus" type is used.
 [ type: <string> ]
 
+# Optional
+# The evaluation timestamp will be aligned with group's interval, 
+# instead of using the actual timestamp that evaluation happens at.
+# By default, it's enabled to get more predictable results 
+# and to visually align with results plotted via Grafana or vmui.
+# See https://github.com/VictoriaMetrics/VictoriaMetrics/issues/5049 
+# Available starting from v1.95
+[ eval_alignment: <bool> | default true]
+
 # Optional list of HTTP URL parameters
 # applied for all rules requests within a group
 # For example:
@@ -527,10 +536,6 @@ Alertmanagers.
 To avoid recording rules results and alerts state duplication in VictoriaMetrics server
 don't forget to configure [deduplication](https://docs.victoriametrics.com/Single-server-VictoriaMetrics.html#deduplication).
 The recommended value for `-dedup.minScrapeInterval` must be multiple of vmalert's `-evaluationInterval`.
-If you observe inconsistent or "jumping" values in series produced by vmalert, try disabling `-datasource.queryTimeAlignment`
-command line flag. Because of alignment, two or more vmalert HA pairs will produce results with the same timestamps.
-But due of backfilling (data delivered to the datasource with some delay) values of such results may differ,
-which would affect deduplication logic and result into "jumping" datapoints.
 
 Alertmanager will automatically deduplicate alerts with identical labels, so ensure that
 all `vmalert`s are having the same config.
@@ -820,7 +825,8 @@ and check the `Last updates` section:
 Rows in the section represent ordered rule evaluations and their results. The column `curl` contains an example of
 HTTP request sent by vmalert to the `-datasource.url` during evaluation. If specific state shows that there were
 no samples returned and curl command returns data - then it is very likely there was no data in datasource on the
-moment when rule was evaluated.
+moment when rule was evaluated. Sensitive info is stripped from the `curl` examples - see [security](#security) section
+for more details.
 
 ### Debug mode
 
@@ -836,6 +842,8 @@ Just set `debug: true` in rule's configuration and vmalert will start printing a
 2022-09-15T13:36:56.153Z  DEBUG rule "TestGroup":"Conns" (2601299393013563564) at 2022-09-15T15:36:56+02:00: alert 10705778000901301787 {alertgroup="TestGroup",alertname="Conns",cluster="east-1",instance="localhost:8429",replica="a"} PENDING => FIRING: 1m0s since becoming active at 2022-09-15 15:35:56.126006 +0200 CEST m=+39.384575417
 ```
 
+Sensitive info is stripped from the `curl` examples - see [security](#security) section for more details.
+
 ### Never-firing alerts
 
 vmalert can detect if alert's expression doesn't match any time series in runtime 
@@ -880,6 +888,20 @@ The same issue can be caused by collision of configured `labels` on [Group](#gro
 To fix it one should avoid collisions by carefully picking label overrides in configuration.
 
 
+## Security
+
+See general recommendations regarding security [here](https://docs.victoriametrics.com/Single-server-VictoriaMetrics.html#security).
+
+vmalert [web UI](#web) exposes configuration details such as list of [Groups](#groups), active alerts, 
+[alerts state](#alerts-state), [notifiers](#notifier-configuration-file). Notifier addresses (sanitized) are attached
+as labels to metrics `vmalert_alerts_sent_.*` on `http://<vmalert>/metrics` page. Consider limiting user's access 
+to the web UI or `/metrics` page if this information is sensitive.
+
+[Alerts state](#alerts-state) page or [debug mode](#debug-mode) could emit additional information about configured
+datasource URL, GET params and headers. Sensitive information such as passwords or auth tokens is stripped by default.
+To disable stripping of such info pass `-datasource.showURL` cmd-line flag to vmalert.
+
+
 ## Profiling
 
 `vmalert` provides handlers for collecting the following [Go profiles](https://blog.golang.org/profiling-go-programs):
@@ -958,11 +980,13 @@ The shortlist of configuration flags is the following:
   -datasource.queryStep duration
      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
+     Flag is deprecated and will be removed in next releases, please use `eval_alignment` in rule group instead.
      Whether to align "time" parameter with evaluation interval.Alignment supposed to produce deterministic results despite 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
      Adds "round_digits" GET param to datasource requests. In VM "round_digits" limits the number of digits after the decimal point in response values.
   -datasource.showURL
-     Whether to show -datasource.url in the exported metrics. It is hidden by default, since it can contain sensitive info such as auth key
+     Whether to avoid stripping sensitive information such as auth headers or passwords from URLs in log messages or UI and exported metrics.
+     It is hidden by default, since it can contain sensitive info such as auth key.
   -datasource.tlsCAFile string
      Optional path to TLS CA file to use for verifying connections to -datasource.url. By default, system CA is used
   -datasource.tlsCertFile string
@@ -982,7 +1006,7 @@ The shortlist of configuration flags is the following:
   -disableAlertgroupLabel
      Whether to disable adding group's Name as label to generated alerts and time series.
   -dryRun
-     Whether to check only config files without running vmalert. The rules file are validated. The -rule flag must be specified.
+     Whether to check only config files without running vmalert. The rules file are validated. The -rule flag must be specified.   
   -enableTCP6
      Whether to enable IPv6 for listening and dialing. By default, only IPv4 TCP and UDP are used
   -envflag.enable
@@ -1031,11 +1055,11 @@ The shortlist of configuration flags is the following:
   -internStringMaxLen int
      The maximum length for strings to intern. A lower limit may save memory at the cost of higher CPU usage. See https://en.wikipedia.org/wiki/String_interning . See also -internStringDisableCache and -internStringCacheExpireDuration (default 500)
   -license string
-     See https://victoriametrics.com/products/enterprise/ for trial license. This flag is available only in VictoriaMetrics enterprise. See https://docs.victoriametrics.com/enterprise.html
+     enterprise license key. This flag is available only in VictoriaMetrics enterprise. Documentation - https://docs.victoriametrics.com/enterprise.html, for more information, visit  https://victoriametrics.com/products/enterprise/ . To request a trial license, go to https://victoriametrics.com/products/enterprise/trial/
   -license.forceOffline
-     See https://victoriametrics.com/products/enterprise/ for trial license. This flag is available only in VictoriaMetrics enterprise. See https://docs.victoriametrics.com/enterprise.html
+     enables offline license verification. License keys issued must support this feature. Contact our support team for license keys with offline check support.
   -licenseFile string
-     See https://victoriametrics.com/products/enterprise/ for trial license. This flag is available only in VictoriaMetrics enterprise. See https://docs.victoriametrics.com/enterprise.html
+     path to file with enterprise license key. This flag is available only in VictoriaMetrics enterprise. Documentation - https://docs.victoriametrics.com/enterprise.html, for more information, visit  https://victoriametrics.com/products/enterprise/ . To request a trial license, go to https://victoriametrics.com/products/enterprise/trial/
   -loggerDisableTimestamps
      Whether to disable writing timestamps in logs
   -loggerErrorsPerSecondLimit int
@@ -1111,6 +1135,9 @@ The shortlist of configuration flags is the following:
   -notifier.url array
      Prometheus Alertmanager URL, e.g. http://127.0.0.1:9093. List all Alertmanager URLs if it runs in the cluster mode to ensure high availability.
      Supports an array of values separated by comma or specified via multiple flags.
+  -notifier.showURL bool
+     Whether to avoid stripping sensitive information such as passwords from URLs in log messages or UI for -notifier.url.
+     It is hidden by default, since it can contain sensitive info such as auth key.
   -notifier.blackhole bool
      Whether to blackhole alerting notifications. Enable this flag if you want vmalert to evaluate alerting rules without sending any notifications to external receivers (eg. alertmanager). `-notifier.url`, `-notifier.config` and `-notifier.blackhole` are mutually exclusive.
   -pprofAuthKey string
diff --git a/app/vmalert/alerting.go b/app/vmalert/alerting.go
index 9b2b9267a..779423b6f 100644
--- a/app/vmalert/alerting.go
+++ b/app/vmalert/alerting.go
@@ -72,7 +72,6 @@ func newAlertingRule(qb datasource.QuerierBuilder, group *Group, cfg config.Rule
 		q: qb.BuildWithParams(datasource.QuerierParams{
 			DataSourceType:     group.Type.String(),
 			EvaluationInterval: group.Interval,
-			EvalOffset:         group.EvalOffset,
 			QueryParams:        group.Params,
 			Headers:            group.Headers,
 			Debug:              cfg.Debug,
diff --git a/app/vmalert/config/config.go b/app/vmalert/config/config.go
index ef53d78a7..219dbe00b 100644
--- a/app/vmalert/config/config.go
+++ b/app/vmalert/config/config.go
@@ -39,6 +39,8 @@ type Group struct {
 	Headers []Header `yaml:"headers,omitempty"`
 	// NotifierHeaders contains optional HTTP headers sent to notifiers for generated notifications
 	NotifierHeaders []Header `yaml:"notifier_headers,omitempty"`
+	// EvalAlignment will make the timestamp of group query requests be aligned with interval
+	EvalAlignment *bool `yaml:"eval_alignment,omitempty"`
 	// Catches all undefined fields and must be empty after parsing.
 	XXX map[string]interface{} `yaml:",inline"`
 }
diff --git a/app/vmalert/datasource/datasource.go b/app/vmalert/datasource/datasource.go
index 20cfbec7f..31e4689c4 100644
--- a/app/vmalert/datasource/datasource.go
+++ b/app/vmalert/datasource/datasource.go
@@ -44,7 +44,6 @@ type QuerierBuilder interface {
 type QuerierParams struct {
 	DataSourceType     string
 	EvaluationInterval time.Duration
-	EvalOffset         *time.Duration
 	QueryParams        url.Values
 	Headers            map[string]string
 	Debug              bool
diff --git a/app/vmalert/datasource/init.go b/app/vmalert/datasource/init.go
index d4cd3d1c1..4497151d6 100644
--- a/app/vmalert/datasource/init.go
+++ b/app/vmalert/datasource/init.go
@@ -10,13 +10,14 @@ import (
 
 	"github.com/VictoriaMetrics/VictoriaMetrics/app/vmalert/utils"
 	"github.com/VictoriaMetrics/VictoriaMetrics/lib/flagutil"
+	"github.com/VictoriaMetrics/VictoriaMetrics/lib/logger"
 )
 
 var (
 	addr = flag.String("datasource.url", "", "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 -remoteRead.disablePathAppend and -datasource.showURL")
 	appendTypePrefix  = flag.Bool("datasource.appendTypePrefix", false, "Whether to add type prefix to -datasource.url based on the query type. Set to true if sending different query types to the vmselect URL.")
-	showDatasourceURL = flag.Bool("datasource.showURL", false, "Whether to show -datasource.url in the exported metrics. "+
+	showDatasourceURL = flag.Bool("datasource.showURL", false, "Whether to avoid stripping sensitive information such as auth headers or passwords from URLs in log messages or UI and exported metrics. "+
 		"It is hidden by default, since it can contain sensitive info such as auth key")
 
 	headers = flag.String("datasource.headers", "", "Optional HTTP extraHeaders to send with each request to the corresponding -datasource.url. "+
@@ -46,7 +47,8 @@ var (
 	queryStep = flag.Duration("datasource.queryStep", 5*time.Minute, "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.")
-	queryTimeAlignment = flag.Bool("datasource.queryTimeAlignment", true, `Whether to align "time" parameter with evaluation interval.`+
+	queryTimeAlignment = flag.Bool("datasource.queryTimeAlignment", true, "Flag is deprecated and will be removed in next releases, please use `eval_alignment` in rule group instead."+
+		`Whether to align "time" parameter with evaluation interval.`+
 		"Alignment supposed to produce deterministic results despite number of vmalert replicas or time they were started. See more details here https://github.com/VictoriaMetrics/VictoriaMetrics/pull/1257")
 	maxIdleConnections = flag.Int("datasource.maxIdleConnections", 100, `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.`)
 	disableKeepAlive   = flag.Bool("datasource.disableKeepAlive", false, `Whether to disable long-lived connections to the datasource. `+
@@ -62,6 +64,11 @@ func InitSecretFlags() {
 	}
 }
 
+// ShowDatasourceURL whether to show -datasource.url with sensitive information
+func ShowDatasourceURL() bool {
+	return *showDatasourceURL
+}
+
 // Param represents an HTTP GET param
 type Param struct {
 	Key, Value string
@@ -74,6 +81,9 @@ func Init(extraParams url.Values) (QuerierBuilder, error) {
 	if *addr == "" {
 		return nil, fmt.Errorf("datasource.url is empty")
 	}
+	if !*queryTimeAlignment {
+		logger.Warnf("flag `datasource.queryTimeAlignment` is deprecated and will be removed in next releases, please use `eval_alignment` in rule group instead")
+	}
 
 	tr, err := utils.Transport(*addr, *tlsCertFile, *tlsKeyFile, *tlsCAFile, *tlsServerName, *tlsInsecureSkipVerify)
 	if err != nil {
diff --git a/app/vmalert/datasource/vm.go b/app/vmalert/datasource/vm.go
index ee21ff029..5267cbba2 100644
--- a/app/vmalert/datasource/vm.go
+++ b/app/vmalert/datasource/vm.go
@@ -39,14 +39,8 @@ type VMStorage struct {
 	queryStep        time.Duration
 	dataSourceType   datasourceType
 
-	// evaluationInterval will align the request's timestamp
-	// if `datasource.queryTimeAlignment` is enabled,
-	// will set request's `step` param as well.
+	// evaluationInterval will help setting request's `step` param.
 	evaluationInterval time.Duration
-	// evaluationOffset shifts the request's timestamp, will be equal
-	// to the offset specified evaluationInterval.
-	// See https://github.com/VictoriaMetrics/VictoriaMetrics/pull/4693
-	evaluationOffset *time.Duration
 	// extraParams contains params to be attached to each HTTP request
 	extraParams url.Values
 	// extraHeaders are headers to be attached to each HTTP request
@@ -95,7 +89,6 @@ func (s *VMStorage) Clone() *VMStorage {
 func (s *VMStorage) ApplyParams(params QuerierParams) *VMStorage {
 	s.dataSourceType = toDatasourceType(params.DataSourceType)
 	s.evaluationInterval = params.EvaluationInterval
-	s.evaluationOffset = params.EvalOffset
 	if params.QueryParams != nil {
 		if s.extraParams == nil {
 			s.extraParams = url.Values{}
@@ -198,17 +191,21 @@ func (s *VMStorage) QueryRange(ctx context.Context, query string, start, end tim
 }
 
 func (s *VMStorage) do(ctx context.Context, req *http.Request) (*http.Response, error) {
+	ru := req.URL.Redacted()
+	if *showDatasourceURL {
+		ru = req.URL.String()
+	}
 	if s.debug {
-		logger.Infof("DEBUG datasource request: executing %s request with params %q", req.Method, req.URL.RawQuery)
+		logger.Infof("DEBUG datasource request: executing %s request with params %q", req.Method, ru)
 	}
 	resp, err := s.c.Do(req.WithContext(ctx))
 	if err != nil {
-		return nil, fmt.Errorf("error getting response from %s: %w", req.URL.Redacted(), err)
+		return nil, fmt.Errorf("error getting response from %s: %w", ru, err)
 	}
 	if resp.StatusCode != http.StatusOK {
 		body, _ := io.ReadAll(resp.Body)
 		_ = resp.Body.Close()
-		return nil, fmt.Errorf("unexpected response code %d for %s. Response body %s", resp.StatusCode, req.URL.Redacted(), body)
+		return nil, fmt.Errorf("unexpected response code %d for %s. Response body %s", resp.StatusCode, ru, body)
 	}
 	return resp, nil
 }
diff --git a/app/vmalert/datasource/vm_prom_api.go b/app/vmalert/datasource/vm_prom_api.go
index 19bc50e72..3e68bd009 100644
--- a/app/vmalert/datasource/vm_prom_api.go
+++ b/app/vmalert/datasource/vm_prom_api.go
@@ -161,8 +161,9 @@ func (s *VMStorage) setPrometheusInstantReqParams(r *http.Request, query string,
 		r.URL.Path += "/api/v1/query"
 	}
 	q := r.URL.Query()
-
-	timestamp = s.adjustReqTimestamp(timestamp)
+	if s.lookBack > 0 {
+		timestamp = timestamp.Add(-s.lookBack)
+	}
 	q.Set("time", timestamp.Format(time.RFC3339))
 	if !*disableStepParam && s.evaluationInterval > 0 { // set step as evaluationInterval by default
 		// always convert to seconds to keep compatibility with older
@@ -186,9 +187,6 @@ func (s *VMStorage) setPrometheusRangeReqParams(r *http.Request, query string, s
 		r.URL.Path += "/api/v1/query_range"
 	}
 	q := r.URL.Query()
-	if s.evaluationOffset != nil {
-		start = start.Truncate(s.evaluationInterval).Add(*s.evaluationOffset)
-	}
 	q.Add("start", start.Format(time.RFC3339))
 	q.Add("end", end.Format(time.RFC3339))
 	if s.evaluationInterval > 0 { // set step as evaluationInterval by default
@@ -213,30 +211,3 @@ func (s *VMStorage) setPrometheusReqParams(r *http.Request, query string) {
 	q.Set("query", query)
 	r.URL.RawQuery = q.Encode()
 }
-
-func (s *VMStorage) adjustReqTimestamp(timestamp time.Time) time.Time {
-	if s.evaluationOffset != nil {
-		// calculate the min timestamp on the evaluationInterval
-		intervalStart := timestamp.Truncate(s.evaluationInterval)
-		ts := intervalStart.Add(*s.evaluationOffset)
-		if timestamp.Before(ts) {
-			// if passed timestamp is before the expected evaluation offset,
-			// then we should adjust it to the previous evaluation round.
-			// E.g. request with evaluationInterval=1h and evaluationOffset=30m
-			// was evaluated at 11:20. Then the timestamp should be adjusted
-			// to 10:30, to the previous evaluationInterval.
-			return ts.Add(-s.evaluationInterval)
-		}
-		// evaluationOffset shouldn't interfere with queryTimeAlignment or lookBack,
-		// so we return it immediately
-		return ts
-	}
-	if *queryTimeAlignment {
-		// see https://github.com/VictoriaMetrics/VictoriaMetrics/issues/1232
-		timestamp = timestamp.Truncate(s.evaluationInterval)
-	}
-	if s.lookBack > 0 {
-		timestamp = timestamp.Add(-s.lookBack)
-	}
-	return timestamp
-}
diff --git a/app/vmalert/group.go b/app/vmalert/group.go
index fab8b20c8..8ccd1e7bc 100644
--- a/app/vmalert/group.go
+++ b/app/vmalert/group.go
@@ -52,6 +52,9 @@ type Group struct {
 	evalCancel context.CancelFunc
 
 	metrics *groupMetrics
+	// evalAlignment will make the timestamp of group query
+	// requests be aligned with interval
+	evalAlignment *bool
 }
 
 type groupMetrics struct {
@@ -106,6 +109,7 @@ func newGroup(cfg config.Group, qb datasource.QuerierBuilder, defaultInterval ti
 		Headers:         make(map[string]string),
 		NotifierHeaders: make(map[string]string),
 		Labels:          cfg.Labels,
+		evalAlignment:   cfg.EvalAlignment,
 
 		doneCh:     make(chan struct{}),
 		finishedCh: make(chan struct{}),
@@ -285,10 +289,11 @@ var skipRandSleepOnGroupStart bool
 func (g *Group) start(ctx context.Context, nts func() []notifier.Notifier, rw *remotewrite.Client, rr datasource.QuerierBuilder) {
 	defer func() { close(g.finishedCh) }()
 
+	evalTS := time.Now()
 	// sleep random duration to spread group rules evaluation
 	// over time in order to reduce load on datasource.
 	if !skipRandSleepOnGroupStart {
-		sleepBeforeStart := delayBeforeStart(time.Now(), g.ID(), g.Interval, g.EvalOffset)
+		sleepBeforeStart := delayBeforeStart(evalTS, g.ID(), g.Interval, g.EvalOffset)
 		g.infof("will start in %v", sleepBeforeStart)
 
 		sleepTimer := time.NewTimer(sleepBeforeStart)
@@ -301,10 +306,9 @@ func (g *Group) start(ctx context.Context, nts func() []notifier.Notifier, rw *r
 			return
 		case <-sleepTimer.C:
 		}
+		evalTS = evalTS.Add(sleepBeforeStart)
 	}
 
-	evalTS := time.Now()
-
 	e := &executor{
 		rw:                       rw,
 		notifiers:                nts,
@@ -326,6 +330,7 @@ func (g *Group) start(ctx context.Context, nts func() []notifier.Notifier, rw *r
 		}
 
 		resolveDuration := getResolveDuration(g.Interval, *resendDelay, *maxResolveDuration)
+		ts = g.adjustReqTimestamp(ts)
 		errs := e.execConcurrently(ctx, g.Rules, ts, g.Concurrency, resolveDuration, g.Limit)
 		for err := range errs {
 			if err != nil {
@@ -424,7 +429,7 @@ func delayBeforeStart(ts time.Time, key uint64, interval time.Duration, offset *
 			randSleep += *offset
 		}
 	}
-	return randSleep.Truncate(time.Second)
+	return randSleep
 }
 
 func (g *Group) infof(format string, args ...interface{}) {
@@ -446,6 +451,32 @@ func getResolveDuration(groupInterval, delta, maxDuration time.Duration) time.Du
 	return resolveDuration
 }
 
+func (g *Group) adjustReqTimestamp(timestamp time.Time) time.Time {
+	if g.EvalOffset != nil {
+		// calculate the min timestamp on the evaluationInterval
+		intervalStart := timestamp.Truncate(g.Interval)
+		ts := intervalStart.Add(*g.EvalOffset)
+		if timestamp.Before(ts) {
+			// if passed timestamp is before the expected evaluation offset,
+			// then we should adjust it to the previous evaluation round.
+			// E.g. request with evaluationInterval=1h and evaluationOffset=30m
+			// was evaluated at 11:20. Then the timestamp should be adjusted
+			// to 10:30, to the previous evaluationInterval.
+			return ts.Add(-g.Interval)
+		}
+		// EvalOffset shouldn't interfere with evalAlignment,
+		// so we return it immediately
+		return ts
+	}
+	if g.evalAlignment == nil || *g.evalAlignment {
+		// align query time with interval to get similar result with grafana when plotting time series.
+		// see https://github.com/VictoriaMetrics/VictoriaMetrics/issues/5049
+		// and https://github.com/VictoriaMetrics/VictoriaMetrics/issues/1232
+		return timestamp.Truncate(g.Interval)
+	}
+	return timestamp
+}
+
 type executor struct {
 	notifiers       func() []notifier.Notifier
 	notifierHeaders map[string]string
diff --git a/app/vmalert/main.go b/app/vmalert/main.go
index 4e81ce838..8d7dcdc6d 100644
--- a/app/vmalert/main.go
+++ b/app/vmalert/main.go
@@ -101,6 +101,7 @@ func main() {
 	remoteread.InitSecretFlags()
 	remotewrite.InitSecretFlags()
 	datasource.InitSecretFlags()
+	notifier.InitSecretFlags()
 	buildinfo.Init()
 	logger.Init()
 	pushmetrics.Init()
diff --git a/app/vmalert/notifier/alertmanager.go b/app/vmalert/notifier/alertmanager.go
index 527ad17f8..8d1abbb83 100644
--- a/app/vmalert/notifier/alertmanager.go
+++ b/app/vmalert/notifier/alertmanager.go
@@ -6,6 +6,7 @@ import (
 	"fmt"
 	"io"
 	"net/http"
+	"net/url"
 	"strings"
 	"time"
 
@@ -17,7 +18,7 @@ import (
 // AlertManager represents integration provider with Prometheus alert manager
 // https://github.com/prometheus/alertmanager
 type AlertManager struct {
-	addr    string
+	addr    *url.URL
 	argFunc AlertURLGenerator
 	client  *http.Client
 	timeout time.Duration
@@ -48,7 +49,12 @@ func (am *AlertManager) Close() {
 }
 
 // Addr returns address where alerts are sent.
-func (am AlertManager) Addr() string { return am.addr }
+func (am AlertManager) Addr() string {
+	if *showNotifierURL {
+		return am.addr.String()
+	}
+	return am.addr.Redacted()
+}
 
 // Send an alert or resolve message
 func (am *AlertManager) Send(ctx context.Context, alerts []Alert, headers map[string]string) error {
@@ -64,7 +70,7 @@ func (am *AlertManager) send(ctx context.Context, alerts []Alert, headers map[st
 	b := &bytes.Buffer{}
 	writeamRequest(b, alerts, am.argFunc, am.relabelConfigs)
 
-	req, err := http.NewRequest(http.MethodPost, am.addr, b)
+	req, err := http.NewRequest(http.MethodPost, am.addr.String(), b)
 	if err != nil {
 		return err
 	}
@@ -91,12 +97,16 @@ func (am *AlertManager) send(ctx context.Context, alerts []Alert, headers map[st
 
 	defer func() { _ = resp.Body.Close() }()
 
+	amURL := am.addr.Redacted()
+	if *showNotifierURL {
+		amURL = am.addr.String()
+	}
 	if resp.StatusCode != http.StatusOK {
 		body, err := io.ReadAll(resp.Body)
 		if err != nil {
-			return fmt.Errorf("failed to read response from %q: %w", am.addr, err)
+			return fmt.Errorf("failed to read response from %q: %w", amURL, err)
 		}
-		return fmt.Errorf("invalid SC %d from %q; response body: %s", resp.StatusCode, am.addr, string(body))
+		return fmt.Errorf("invalid SC %d from %q; response body: %s", resp.StatusCode, amURL, string(body))
 	}
 	return nil
 }
@@ -136,8 +146,15 @@ func NewAlertManager(alertManagerURL string, fn AlertURLGenerator, authCfg proma
 		return nil, fmt.Errorf("failed to configure auth: %w", err)
 	}
 
+	amURL, err := url.Parse(alertManagerURL)
+	if err != nil {
+		return nil, fmt.Errorf("provided incorrect notifier url: %w", err)
+	}
+	if !*showNotifierURL {
+		alertManagerURL = amURL.Redacted()
+	}
 	return &AlertManager{
-		addr:           alertManagerURL,
+		addr:           amURL,
 		argFunc:        fn,
 		authCfg:        aCfg,
 		relabelConfigs: relabelCfg,
diff --git a/app/vmalert/notifier/init.go b/app/vmalert/notifier/init.go
index 35cc6d9c1..dc4a6e4e7 100644
--- a/app/vmalert/notifier/init.go
+++ b/app/vmalert/notifier/init.go
@@ -19,6 +19,8 @@ var (
 
 	addrs = flagutil.NewArrayString("notifier.url", "Prometheus Alertmanager URL, e.g. http://127.0.0.1:9093. "+
 		"List all Alertmanager URLs if it runs in the cluster mode to ensure high availability.")
+	showNotifierURL = flag.Bool("notifier.showURL", false, "Whether to avoid stripping sensitive information such as passwords from URL in log messages or UI for -notifier.url. "+
+		"It is hidden by default, since it can contain sensitive info such as auth key")
 	blackHole = flag.Bool("notifier.blackhole", false, "Whether to blackhole alerting notifications. "+
 		"Enable this flag if you want vmalert to evaluate alerting rules without sending any notifications to external receivers (eg. alertmanager). "+
 		"`-notifier.url`, `-notifier.config` and `-notifier.blackhole` are mutually exclusive.")
@@ -129,6 +131,13 @@ func Init(gen AlertURLGenerator, extLabels map[string]string, extURL string) (fu
 	return cw.notifiers, nil
 }
 
+// InitSecretFlags must be called after flag.Parse and before any logging
+func InitSecretFlags() {
+	if !*showNotifierURL {
+		flagutil.RegisterSecretFlag("notifier.url")
+	}
+}
+
 func notifiersFromFlags(gen AlertURLGenerator) ([]Notifier, error) {
 	var notifiers []Notifier
 	for i, addr := range *addrs {
diff --git a/app/vmalert/recording.go b/app/vmalert/recording.go
index 2a9e11c3f..fd137d05e 100644
--- a/app/vmalert/recording.go
+++ b/app/vmalert/recording.go
@@ -61,7 +61,6 @@ func newRecordingRule(qb datasource.QuerierBuilder, group *Group, cfg config.Rul
 		q: qb.BuildWithParams(datasource.QuerierParams{
 			DataSourceType:     group.Type.String(),
 			EvaluationInterval: group.Interval,
-			EvalOffset:         group.EvalOffset,
 			QueryParams:        group.Params,
 			Headers:            group.Headers,
 		}),
diff --git a/app/vmalert/replay.go b/app/vmalert/replay.go
index 1f3763a24..5c9ed96fe 100644
--- a/app/vmalert/replay.go
+++ b/app/vmalert/replay.go
@@ -81,13 +81,15 @@ func replay(groupsCfg []config.Group, qb datasource.QuerierBuilder, rw *remotewr
 func (g *Group) replay(start, end time.Time, rw *remotewrite.Client) int {
 	var total int
 	step := g.Interval * time.Duration(*replayMaxDatapoints)
+	start = g.adjustReqTimestamp(start)
 	ri := rangeIterator{start: start, end: end, step: step}
 	iterations := int(end.Sub(start)/step) + 1
 	fmt.Printf("\nGroup %q"+
 		"\ninterval: \t%v"+
+		"\neval_offset: \t%v"+
 		"\nrequests to make: \t%d"+
 		"\nmax range per request: \t%v\n",
-		g.Name, g.Interval, iterations, step)
+		g.Name, g.Interval, g.EvalOffset, iterations, step)
 	if g.Limit > 0 {
 		fmt.Printf("\nPlease note, `limit: %d` param has no effect during replay.\n",
 			g.Limit)
diff --git a/app/vmalert/rule.go b/app/vmalert/rule.go
index 4d52a30a1..e2860f9c8 100644
--- a/app/vmalert/rule.go
+++ b/app/vmalert/rule.go
@@ -42,7 +42,7 @@ type ruleState struct {
 type ruleStateEntry struct {
 	// stores last moment of time rule.Exec was called
 	time time.Time
-	// stores the timesteamp with which rule.Exec was called
+	// stores the timestamp rule.Exec was called with
 	at time.Time
 	// stores the duration of the last rule.Exec call
 	duration time.Duration
diff --git a/app/vmalert/utils.go b/app/vmalert/utils.go
index bf5aeca75..d5c729825 100644
--- a/app/vmalert/utils.go
+++ b/app/vmalert/utils.go
@@ -7,6 +7,7 @@ import (
 	"strings"
 	"time"
 
+	"github.com/VictoriaMetrics/VictoriaMetrics/app/vmalert/datasource"
 	"github.com/VictoriaMetrics/VictoriaMetrics/lib/prompbmarshal"
 )
 
@@ -80,6 +81,9 @@ func requestToCurl(req *http.Request) string {
 
 	schema := req.URL.Scheme
 	requestURL := req.URL.String()
+	if !datasource.ShowDatasourceURL() {
+		requestURL = req.URL.Redacted()
+	}
 	if schema == "" {
 		schema = "http"
 		if req.TLS != nil {
@@ -103,9 +107,25 @@ func requestToCurl(req *http.Request) string {
 
 	for _, k := range keys {
 		cw.add("-H")
+		if !datasource.ShowDatasourceURL() && isSecreteHeader(k) {
+			cw.addWithEsc(fmt.Sprintf("%s: <secret>", k))
+			continue
+		}
 		cw.addWithEsc(fmt.Sprintf("%s: %s", k, strings.Join(req.Header[k], " ")))
 	}
 
 	cw.addWithEsc(requestURL)
 	return cw.string()
 }
+
+var secretWords = []string{"auth", "pass", "key", "secret", "token"}
+
+func isSecreteHeader(str string) bool {
+	s := strings.ToLower(str)
+	for _, secret := range secretWords {
+		if strings.Contains(s, secret) {
+			return true
+		}
+	}
+	return false
+}
diff --git a/app/vmauth/README.md b/app/vmauth/README.md
index 71a627e01..e03a18cda 100644
--- a/app/vmauth/README.md
+++ b/app/vmauth/README.md
@@ -429,11 +429,11 @@ See the docs at https://docs.victoriametrics.com/vmauth.html .
   -internStringMaxLen int
      The maximum length for strings to intern. A lower limit may save memory at the cost of higher CPU usage. See https://en.wikipedia.org/wiki/String_interning . See also -internStringDisableCache and -internStringCacheExpireDuration (default 500)
   -license string
-     See https://victoriametrics.com/products/enterprise/ for trial license. This flag is available only in VictoriaMetrics enterprise. See https://docs.victoriametrics.com/enterprise.html
+     enterprise license key. This flag is available only in VictoriaMetrics enterprise. Documentation - https://docs.victoriametrics.com/enterprise.html, for more information, visit  https://victoriametrics.com/products/enterprise/ . To request a trial license, go to https://victoriametrics.com/products/enterprise/trial/
   -license.forceOffline
-     See https://victoriametrics.com/products/enterprise/ for trial license. This flag is available only in VictoriaMetrics enterprise. See https://docs.victoriametrics.com/enterprise.html
+     enables offline license verification. License keys issued must support this feature. Contact our support team for license keys with offline check support.
   -licenseFile string
-     See https://victoriametrics.com/products/enterprise/ for trial license. This flag is available only in VictoriaMetrics enterprise. See https://docs.victoriametrics.com/enterprise.html
+     path to file with enterprise license key. This flag is available only in VictoriaMetrics enterprise. Documentation - https://docs.victoriametrics.com/enterprise.html, for more information, visit  https://victoriametrics.com/products/enterprise/ . To request a trial license, go to https://victoriametrics.com/products/enterprise/trial/
   -logInvalidAuthTokens
      Whether to log requests with invalid auth tokens. Such requests are always counted at vmauth_http_request_errors_total{reason="invalid_auth_token"} metric, which is exposed at /metrics page
   -loggerDisableTimestamps
diff --git a/app/vmbackup/README.md b/app/vmbackup/README.md
index a365020e1..185528ae4 100644
--- a/app/vmbackup/README.md
+++ b/app/vmbackup/README.md
@@ -324,11 +324,11 @@ Run `vmbackup -help` in order to see all the available options:
   -internStringMaxLen int
      The maximum length for strings to intern. A lower limit may save memory at the cost of higher CPU usage. See https://en.wikipedia.org/wiki/String_interning . See also -internStringDisableCache and -internStringCacheExpireDuration (default 500)
   -license string
-     See https://victoriametrics.com/products/enterprise/ for trial license. This flag is available only in VictoriaMetrics enterprise. See https://docs.victoriametrics.com/enterprise.html
+     enterprise license key. This flag is available only in VictoriaMetrics enterprise. Documentation - https://docs.victoriametrics.com/enterprise.html, for more information, visit  https://victoriametrics.com/products/enterprise/ . To request a trial license, go to https://victoriametrics.com/products/enterprise/trial/
   -license.forceOffline
-     See https://victoriametrics.com/products/enterprise/ for trial license. This flag is available only in VictoriaMetrics enterprise. See https://docs.victoriametrics.com/enterprise.html
+     enables offline license verification. License keys issued must support this feature. Contact our support team for license keys with offline check support.
   -licenseFile string
-     See https://victoriametrics.com/products/enterprise/ for trial license. This flag is available only in VictoriaMetrics enterprise. See https://docs.victoriametrics.com/enterprise.html
+     path to file with enterprise license key. This flag is available only in VictoriaMetrics enterprise. Documentation - https://docs.victoriametrics.com/enterprise.html, for more information, visit  https://victoriametrics.com/products/enterprise/ . To request a trial license, go to https://victoriametrics.com/products/enterprise/trial/
   -loggerDisableTimestamps
      Whether to disable writing timestamps in logs
   -loggerErrorsPerSecondLimit int
diff --git a/app/vmbackupmanager/README.md b/app/vmbackupmanager/README.md
index 3f46ef722..1482297f1 100644
--- a/app/vmbackupmanager/README.md
+++ b/app/vmbackupmanager/README.md
@@ -1,6 +1,8 @@
 # vmbackupmanager
 
-***vmbackupmanager is a part of [enterprise package](https://docs.victoriametrics.com/enterprise.html). It is available for download and evaluation at [releases page](https://github.com/VictoriaMetrics/VictoriaMetrics/releases)***
+***vmbackupmanager is a part of [enterprise package](https://docs.victoriametrics.com/enterprise.html). 
+It is available for download and evaluation at [releases page](https://github.com/VictoriaMetrics/VictoriaMetrics/releases).
+See how to request a free trial license [here](https://victoriametrics.com/products/enterprise/trial/).***
 
 The VictoriaMetrics backup manager automates regular backup procedures. It supports the following backup intervals: **hourly**, **daily**, **weekly** and **monthly**.
 Multiple backup intervals may be configured simultaneously. I.e. the backup manager creates hourly backups every hour, while it creates daily backups every day, etc.
@@ -471,11 +473,11 @@ command-line flags:
   -keepLastWeekly int
      Keep last N weekly backups. If 0 is specified next retention cycle removes all backups for given time period. (default -1)
   -license string
-     See https://victoriametrics.com/products/enterprise/ for trial license. This flag is available only in VictoriaMetrics enterprise. See https://docs.victoriametrics.com/enterprise.html
+     enterprise license key. This flag is available only in VictoriaMetrics enterprise. Documentation - https://docs.victoriametrics.com/enterprise.html, for more information, visit  https://victoriametrics.com/products/enterprise/ . To request a trial license, go to https://victoriametrics.com/products/enterprise/trial/
   -license.forceOffline
-     See https://victoriametrics.com/products/enterprise/ for trial license. This flag is available only in VictoriaMetrics enterprise. See https://docs.victoriametrics.com/enterprise.html
+     enables offline license verification. License keys issued must support this feature. Contact our support team for license keys with offline check support.
   -licenseFile string
-     See https://victoriametrics.com/products/enterprise/ for trial license. This flag is available only in VictoriaMetrics enterprise. See https://docs.victoriametrics.com/enterprise.html
+     path to file with enterprise license key. This flag is available only in VictoriaMetrics enterprise. Documentation - https://docs.victoriametrics.com/enterprise.html, for more information, visit  https://victoriametrics.com/products/enterprise/ . To request a trial license, go to https://victoriametrics.com/products/enterprise/trial/
   -loggerDisableTimestamps
      Whether to disable writing timestamps in logs
   -loggerErrorsPerSecondLimit int
diff --git a/app/vmgateway/README.md b/app/vmgateway/README.md
index dfc0941a6..1181c31a1 100644
--- a/app/vmgateway/README.md
+++ b/app/vmgateway/README.md
@@ -1,6 +1,8 @@
 # vmgateway
 
-***vmgateway is a part of [enterprise package](https://docs.victoriametrics.com/enterprise.html). It is available for download and evaluation at [releases page](https://github.com/VictoriaMetrics/VictoriaMetrics/releases)***
+***vmgateway is a part of [enterprise package](https://docs.victoriametrics.com/enterprise.html). 
+It is available for download and evaluation at [releases page](https://github.com/VictoriaMetrics/VictoriaMetrics/releases).
+See how to request a free trial license [here](https://victoriametrics.com/products/enterprise/trial/).***
 
 <img alt="vmgateway" src="vmgateway-overview.jpeg">
 
@@ -370,11 +372,11 @@ The shortlist of configuration flags include the following:
   -internStringMaxLen int
      The maximum length for strings to intern. A lower limit may save memory at the cost of higher CPU usage. See https://en.wikipedia.org/wiki/String_interning . See also -internStringDisableCache and -internStringCacheExpireDuration (default 500)
   -license string
-     See https://victoriametrics.com/products/enterprise/ for trial license. This flag is available only in VictoriaMetrics enterprise. See https://docs.victoriametrics.com/enterprise.html
+     enterprise license key. This flag is available only in VictoriaMetrics enterprise. Documentation - https://docs.victoriametrics.com/enterprise.html, for more information, visit  https://victoriametrics.com/products/enterprise/ . To request a trial license, go to https://victoriametrics.com/products/enterprise/trial/
   -license.forceOffline
-     See https://victoriametrics.com/products/enterprise/ for trial license. This flag is available only in VictoriaMetrics enterprise. See https://docs.victoriametrics.com/enterprise.html
+     enables offline license verification. License keys issued must support this feature. Contact our support team for license keys with offline check support.
   -licenseFile string
-     See https://victoriametrics.com/products/enterprise/ for trial license. This flag is available only in VictoriaMetrics enterprise. See https://docs.victoriametrics.com/enterprise.html
+     path to file with enterprise license key. This flag is available only in VictoriaMetrics enterprise. Documentation - https://docs.victoriametrics.com/enterprise.html, for more information, visit  https://victoriametrics.com/products/enterprise/ . To request a trial license, go to https://victoriametrics.com/products/enterprise/trial/
   -loggerDisableTimestamps
      Whether to disable writing timestamps in logs
   -loggerErrorsPerSecondLimit int
diff --git a/app/vmrestore/README.md b/app/vmrestore/README.md
index 36bb2f95b..0510e2eec 100644
--- a/app/vmrestore/README.md
+++ b/app/vmrestore/README.md
@@ -130,11 +130,11 @@ i.e. the end result would be similar to [rsync --delete](https://askubuntu.com/q
   -internStringMaxLen int
      The maximum length for strings to intern. A lower limit may save memory at the cost of higher CPU usage. See https://en.wikipedia.org/wiki/String_interning . See also -internStringDisableCache and -internStringCacheExpireDuration (default 500)
   -license string
-     See https://victoriametrics.com/products/enterprise/ for trial license. This flag is available only in VictoriaMetrics enterprise. See https://docs.victoriametrics.com/enterprise.html
+     enterprise license key. This flag is available only in VictoriaMetrics enterprise. Documentation - https://docs.victoriametrics.com/enterprise.html, for more information, visit  https://victoriametrics.com/products/enterprise/ . To request a trial license, go to https://victoriametrics.com/products/enterprise/trial/
   -license.forceOffline
-     See https://victoriametrics.com/products/enterprise/ for trial license. This flag is available only in VictoriaMetrics enterprise. See https://docs.victoriametrics.com/enterprise.html
+     enables offline license verification. License keys issued must support this feature. Contact our support team for license keys with offline check support.
   -licenseFile string
-     See https://victoriametrics.com/products/enterprise/ for trial license. This flag is available only in VictoriaMetrics enterprise. See https://docs.victoriametrics.com/enterprise.html
+     path to file with enterprise license key. This flag is available only in VictoriaMetrics enterprise. Documentation - https://docs.victoriametrics.com/enterprise.html, for more information, visit  https://victoriametrics.com/products/enterprise/ . To request a trial license, go to https://victoriametrics.com/products/enterprise/trial/
   -loggerDisableTimestamps
      Whether to disable writing timestamps in logs
   -loggerErrorsPerSecondLimit int
diff --git a/app/vmselect/promql/aggr.go b/app/vmselect/promql/aggr.go
index 3ba78615a..c3310ee22 100644
--- a/app/vmselect/promql/aggr.go
+++ b/app/vmselect/promql/aggr.go
@@ -8,7 +8,6 @@ import (
 	"strconv"
 	"strings"
 
-	"github.com/VictoriaMetrics/VictoriaMetrics/lib/bytesutil"
 	"github.com/VictoriaMetrics/VictoriaMetrics/lib/logger"
 	"github.com/VictoriaMetrics/VictoriaMetrics/lib/storage"
 	"github.com/VictoriaMetrics/metrics"
@@ -130,7 +129,7 @@ func aggrPrepareSeries(argOrig []*timeseries, modifier *metricsql.ModifierExpr,
 	for i, ts := range arg {
 		removeGroupTags(&ts.MetricName, modifier)
 		bb.B = marshalMetricNameSorted(bb.B[:0], &ts.MetricName)
-		k := bytesutil.InternBytes(bb.B)
+		k := string(bb.B)
 		if keepOriginal {
 			ts = argOrig[i]
 		}
diff --git a/app/vmselect/promql/aggr_incremental.go b/app/vmselect/promql/aggr_incremental.go
index f3d5bd416..c87ba7bb3 100644
--- a/app/vmselect/promql/aggr_incremental.go
+++ b/app/vmselect/promql/aggr_incremental.go
@@ -6,7 +6,6 @@ import (
 	"unsafe"
 
 	"github.com/VictoriaMetrics/VictoriaMetrics/app/vmselect/netstorage"
-	"github.com/VictoriaMetrics/VictoriaMetrics/lib/bytesutil"
 	"github.com/VictoriaMetrics/metricsql"
 )
 
@@ -105,7 +104,7 @@ func (iafc *incrementalAggrFuncContext) updateTimeseries(tsOrig *timeseries, wor
 	removeGroupTags(&ts.MetricName, &iafc.ae.Modifier)
 	bb := bbPool.Get()
 	bb.B = marshalMetricNameSorted(bb.B[:0], &ts.MetricName)
-	k := bytesutil.InternBytes(bb.B)
+	k := string(bb.B)
 	iac := m[k]
 	if iac == nil {
 		if iafc.ae.Limit > 0 && len(m) >= iafc.ae.Limit {
diff --git a/app/vmselect/promql/binary_op.go b/app/vmselect/promql/binary_op.go
index 3c354946a..d02082556 100644
--- a/app/vmselect/promql/binary_op.go
+++ b/app/vmselect/promql/binary_op.go
@@ -5,7 +5,6 @@ import (
 	"math"
 	"strings"
 
-	"github.com/VictoriaMetrics/VictoriaMetrics/lib/bytesutil"
 	"github.com/VictoriaMetrics/VictoriaMetrics/lib/logger"
 	"github.com/VictoriaMetrics/VictoriaMetrics/lib/storage"
 	"github.com/VictoriaMetrics/metricsql"
@@ -261,8 +260,7 @@ func groupJoin(singleTimeseriesSide string, be *metricsql.BinaryOpExpr, rvsLeft,
 			bb.B = marshalMetricTagsSorted(bb.B[:0], &tsCopy.MetricName)
 			pair, ok := m[string(bb.B)]
 			if !ok {
-				k := bytesutil.InternBytes(bb.B)
-				m[k] = &tsPair{
+				m[string(bb.B)] = &tsPair{
 					left:  &tsCopy,
 					right: tsRight,
 				}
@@ -524,7 +522,7 @@ func createTimeseriesMapByTagSet(be *metricsql.BinaryOpExpr, left, right []*time
 				logger.Panicf("BUG: unexpected binary op modifier %q", groupOp)
 			}
 			bb.B = marshalMetricTagsSorted(bb.B[:0], mn)
-			k := bytesutil.InternBytes(bb.B)
+			k := string(bb.B)
 			m[k] = append(m[k], ts)
 		}
 		storage.PutMetricName(mn)
diff --git a/app/vmselect/promql/eval.go b/app/vmselect/promql/eval.go
index 26bf27207..6766a8855 100644
--- a/app/vmselect/promql/eval.go
+++ b/app/vmselect/promql/eval.go
@@ -563,8 +563,8 @@ func getCommonLabelFilters(tss []*timeseries) []metricsql.LabelFilter {
 		for _, tag := range ts.MetricName.Tags {
 			vc, ok := m[string(tag.Key)]
 			if !ok {
-				k := bytesutil.InternBytes(tag.Key)
-				v := bytesutil.InternBytes(tag.Value)
+				k := string(tag.Key)
+				v := string(tag.Value)
 				m[k] = &valuesCounter{
 					values: map[string]struct{}{
 						v: {},
@@ -581,8 +581,7 @@ func getCommonLabelFilters(tss []*timeseries) []metricsql.LabelFilter {
 			}
 			vc.count++
 			if _, ok := vc.values[string(tag.Value)]; !ok {
-				v := bytesutil.InternBytes(tag.Value)
-				vc.values[v] = struct{}{}
+				vc.values[string(tag.Value)] = struct{}{}
 			}
 		}
 	}
diff --git a/app/vmselect/promql/exec.go b/app/vmselect/promql/exec.go
index 5be2f70ff..a328783dd 100644
--- a/app/vmselect/promql/exec.go
+++ b/app/vmselect/promql/exec.go
@@ -12,7 +12,6 @@ import (
 
 	"github.com/VictoriaMetrics/VictoriaMetrics/app/vmselect/netstorage"
 	"github.com/VictoriaMetrics/VictoriaMetrics/app/vmselect/querystats"
-	"github.com/VictoriaMetrics/VictoriaMetrics/lib/bytesutil"
 	"github.com/VictoriaMetrics/VictoriaMetrics/lib/decimal"
 	"github.com/VictoriaMetrics/VictoriaMetrics/lib/querytracer"
 	"github.com/VictoriaMetrics/VictoriaMetrics/lib/storage"
@@ -129,7 +128,7 @@ func timeseriesToResult(tss []*timeseries, maySort bool) ([]netstorage.Result, e
 	bb := bbPool.Get()
 	for i, ts := range tss {
 		bb.B = marshalMetricNameSorted(bb.B[:0], &ts.MetricName)
-		k := bytesutil.InternBytes(bb.B)
+		k := string(bb.B)
 		if _, ok := m[k]; ok {
 			return nil, fmt.Errorf(`duplicate output timeseries: %s`, stringMetricName(&ts.MetricName))
 		}
diff --git a/app/vmselect/promql/rollup_result_cache.go b/app/vmselect/promql/rollup_result_cache.go
index db36673e2..bf9a45e8b 100644
--- a/app/vmselect/promql/rollup_result_cache.go
+++ b/app/vmselect/promql/rollup_result_cache.go
@@ -442,8 +442,7 @@ func mergeTimeseries(a, b []*timeseries, bStart int64, ec *EvalConfig) []*timese
 	defer bbPool.Put(bb)
 	for _, ts := range a {
 		bb.B = marshalMetricNameSorted(bb.B[:0], &ts.MetricName)
-		k := bytesutil.InternBytes(bb.B)
-		m[k] = ts
+		m[string(bb.B)] = ts
 	}
 
 	rvs := make([]*timeseries, 0, len(a))
@@ -455,7 +454,7 @@ func mergeTimeseries(a, b []*timeseries, bStart int64, ec *EvalConfig) []*timese
 		tmp.MetricName.MoveFrom(&tsB.MetricName)
 
 		bb.B = marshalMetricNameSorted(bb.B[:0], &tmp.MetricName)
-		k := bytesutil.InternBytes(bb.B)
+		k := string(bb.B)
 		tsA := m[k]
 		if tsA == nil {
 			tStart := ec.Start
diff --git a/app/vmselect/promql/transform.go b/app/vmselect/promql/transform.go
index d61acf08b..25ff45fbe 100644
--- a/app/vmselect/promql/transform.go
+++ b/app/vmselect/promql/transform.go
@@ -420,7 +420,7 @@ func transformBucketsLimit(tfa *transformFuncArg) ([]*timeseries, error) {
 		mn.CopyFrom(&ts.MetricName)
 		mn.RemoveTag("le")
 		b = marshalMetricNameSorted(b[:0], &mn)
-		k := bytesutil.InternBytes(b)
+		k := bytesutil.ToUnsafeString(b)
 		m[k] = append(m[k], x{
 			le: le,
 			ts: ts,
@@ -523,7 +523,7 @@ func vmrangeBucketsToLE(tss []*timeseries) []*timeseries {
 		ts.MetricName.RemoveTag("le")
 		ts.MetricName.RemoveTag("vmrange")
 		bb.B = marshalMetricNameSorted(bb.B[:0], &ts.MetricName)
-		k := bytesutil.InternBytes(bb.B)
+		k := string(bb.B)
 		m[k] = append(m[k], x{
 			startStr: startStr,
 			endStr:   endStr,
@@ -1023,7 +1023,7 @@ func groupLeTimeseries(tss []*timeseries) map[string][]leTimeseries {
 		ts.MetricName.ResetMetricGroup()
 		ts.MetricName.RemoveTag("le")
 		bb.B = marshalMetricTagsSorted(bb.B[:0], &ts.MetricName)
-		k := bytesutil.InternBytes(bb.B)
+		k := string(bb.B)
 		m[k] = append(m[k], leTimeseries{
 			le: le,
 			ts: ts,
@@ -1657,7 +1657,7 @@ func transformUnion(tfa *transformFuncArg) ([]*timeseries, error) {
 	for _, arg := range args {
 		for _, ts := range arg {
 			bb.B = marshalMetricNameSorted(bb.B[:0], &ts.MetricName)
-			k := bytesutil.InternBytes(bb.B)
+			k := string(bb.B)
 			if m[k] {
 				continue
 			}
diff --git a/app/vmui/.gitignore b/app/vmui/.gitignore
index 8f007b312..5fa6b0d6e 100644
--- a/app/vmui/.gitignore
+++ b/app/vmui/.gitignore
@@ -105,3 +105,5 @@ dist
 
 # WebStorm etc
 .idea/
+
+MetricsQL.md
diff --git a/app/vmui/Makefile b/app/vmui/Makefile
index 39a65358f..eb3354044 100644
--- a/app/vmui/Makefile
+++ b/app/vmui/Makefile
@@ -1,9 +1,12 @@
 # All these commands must run from repository root.
 
+copy-metricsql-docs:
+	cp docs/MetricsQL.md app/vmui/packages/vmui/src/assets/MetricsQL.md
+
 vmui-package-base-image:
 	docker build -t vmui-builder-image -f app/vmui/Dockerfile-build ./app/vmui
 
-vmui-build: vmui-package-base-image
+vmui-build: copy-metricsql-docs vmui-package-base-image
 	docker run --rm \
 		--user $(shell id -u):$(shell id -g) \
 		--mount type=bind,src="$(shell pwd)/app/vmui",dst=/build \
diff --git a/app/vmui/packages/vmui/package.json b/app/vmui/packages/vmui/package.json
index ff05078f7..ad3e2d91a 100644
--- a/app/vmui/packages/vmui/package.json
+++ b/app/vmui/packages/vmui/package.json
@@ -30,13 +30,15 @@
     "web-vitals": "^3.3.2"
   },
   "scripts": {
+    "prestart": "npm run update-metricsql",
     "start": "react-app-rewired start",
     "start:logs": "cross-env REACT_APP_LOGS=true npm run start",
     "build": "GENERATE_SOURCEMAP=false react-app-rewired build",
     "build:logs": "cross-env REACT_APP_LOGS=true npm run build",
     "lint": "eslint src --ext tsx,ts",
     "lint:fix": "eslint src --ext tsx,ts --fix",
-    "analyze": "source-map-explorer 'build/static/js/*.js'"
+    "analyze": "source-map-explorer 'build/static/js/*.js'",
+    "copy-metricsql-docs": "cp ../../../../docs/MetricsQL.md src/assets/MetricsQL.md || true"
   },
   "eslintConfig": {
     "extends": [
diff --git a/app/vmui/packages/vmui/src/api/query-range.ts b/app/vmui/packages/vmui/src/api/query-range.ts
index 850760fe8..28a3679d6 100644
--- a/app/vmui/packages/vmui/src/api/query-range.ts
+++ b/app/vmui/packages/vmui/src/api/query-range.ts
@@ -5,5 +5,3 @@ export const getQueryRangeUrl = (server: string, query: string, period: TimePara
 
 export const getQueryUrl = (server: string, query: string, period: TimeParams, queryTracing: boolean): string =>
   `${server}/api/v1/query?query=${encodeURIComponent(query)}&time=${period.end}${queryTracing ? "&trace=1" : ""}`;
-
-export const getQueryOptions = (server: string) => `${server}/api/v1/label/__name__/values`;
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 78e3053f0..4b3bb8b72 100644
--- a/app/vmui/packages/vmui/src/components/Configurators/QueryEditor/QueryEditor.tsx
+++ b/app/vmui/packages/vmui/src/components/Configurators/QueryEditor/QueryEditor.tsx
@@ -2,10 +2,11 @@ import React, { FC, useRef, useState } from "preact/compat";
 import { KeyboardEvent } from "react";
 import { ErrorTypes } from "../../../types";
 import TextField from "../../Main/TextField/TextField";
-import Autocomplete from "../../Main/Autocomplete/Autocomplete";
+import QueryEditorAutocomplete from "./QueryEditorAutocomplete";
 import "./style.scss";
 import { QueryStats } from "../../../api/types";
 import { partialWarning, seriesFetchedWarning } from "./warningText";
+import { AutocompleteOptions } from "../../Main/Autocomplete/Autocomplete";
 
 export interface QueryEditorProps {
   onChange: (query: string) => void;
@@ -17,7 +18,6 @@ export interface QueryEditorProps {
   autocomplete: boolean;
   error?: ErrorTypes | string;
   stats?: QueryStats;
-  options: string[];
   label: string;
   disabled?: boolean
 }
@@ -31,13 +31,13 @@ const QueryEditor: FC<QueryEditorProps> = ({
   autocomplete,
   error,
   stats,
-  options,
   label,
   disabled = false
 }) => {
 
   const [openAutocomplete, setOpenAutocomplete] = useState(false);
-  const autocompleteAnchorEl = useRef<HTMLDivElement>(null);
+  const [caretPosition, setCaretPosition] = useState([0, 0]);
+  const autocompleteAnchorEl = useRef<HTMLInputElement>(null);
 
   const warning = [
     {
@@ -88,37 +88,43 @@ const QueryEditor: FC<QueryEditorProps> = ({
     }
   };
 
-  const handleChangeFoundOptions = (val: string[]) => {
+  const handleChangeFoundOptions = (val: AutocompleteOptions[]) => {
     setOpenAutocomplete(!!val.length);
   };
 
-  return <div
-    className="vm-query-editor"
-    ref={autocompleteAnchorEl}
-  >
-    <TextField
-      value={value}
-      label={label}
-      type={"textarea"}
-      autofocus={!!value}
-      error={error}
-      warning={warning}
-      onKeyDown={handleKeyDown}
-      onChange={onChange}
-      disabled={disabled}
-      inputmode={"search"}
-    />
-    {autocomplete && (
-      <Autocomplete
-        disabledFullScreen
+  const handleChangeCaret = (val: number[]) => {
+    setCaretPosition(val);
+  };
+
+  return (
+    <div
+      className="vm-query-editor"
+      ref={autocompleteAnchorEl}
+    >
+      <TextField
         value={value}
-        options={options}
-        anchor={autocompleteAnchorEl}
-        onSelect={handleSelect}
-        onFoundOptions={handleChangeFoundOptions}
+        label={label}
+        type={"textarea"}
+        autofocus={!!value}
+        error={error}
+        warning={warning}
+        onKeyDown={handleKeyDown}
+        onChange={onChange}
+        onChangeCaret={handleChangeCaret}
+        disabled={disabled}
+        inputmode={"search"}
       />
-    )}
-  </div>;
+      {autocomplete && (
+        <QueryEditorAutocomplete
+          value={value}
+          anchorEl={autocompleteAnchorEl}
+          caretPosition={caretPosition}
+          onSelect={handleSelect}
+          onFoundOptions={handleChangeFoundOptions}
+        />
+      )}
+    </div>
+  );
 };
 
 export default QueryEditor;
diff --git a/app/vmui/packages/vmui/src/components/Configurators/QueryEditor/QueryEditorAutocomplete.tsx b/app/vmui/packages/vmui/src/components/Configurators/QueryEditor/QueryEditorAutocomplete.tsx
new file mode 100644
index 000000000..0bc30519a
--- /dev/null
+++ b/app/vmui/packages/vmui/src/components/Configurators/QueryEditor/QueryEditorAutocomplete.tsx
@@ -0,0 +1,129 @@
+import React, { FC, Ref, useState, useEffect, useMemo } from "preact/compat";
+import Autocomplete, { AutocompleteOptions } from "../../Main/Autocomplete/Autocomplete";
+import { useFetchQueryOptions } from "../../../hooks/useFetchQueryOptions";
+import { getTextWidth } from "../../../utils/uplot";
+import { escapeRegExp } from "../../../utils/regexp";
+import useGetMetricsQL from "../../../hooks/useGetMetricsQL";
+
+enum ContextType {
+  empty = "empty",
+  metricsql = "metricsql",
+  label = "label",
+  value = "value",
+}
+
+interface QueryEditorAutocompleteProps {
+  value: string;
+  anchorEl: Ref<HTMLInputElement>;
+  caretPosition: number[];
+  onSelect: (val: string) => void;
+  onFoundOptions: (val: AutocompleteOptions[]) => void;
+}
+
+const QueryEditorAutocomplete: FC<QueryEditorAutocompleteProps> = ({
+  value,
+  anchorEl,
+  caretPosition,
+  onSelect,
+  onFoundOptions
+}) => {
+  const [leftOffset, setLeftOffset] = useState(0);
+  const metricsqlFunctions = useGetMetricsQL();
+
+  const metric = useMemo(() => {
+    const regexp = /\b[^{}(),\s]+(?={|$)/g;
+    const match = value.match(regexp);
+    return match ? match[0] : "";
+  }, [value]);
+
+  const label = useMemo(() => {
+    const regexp = /[a-z_]\w*(?=\s*(=|!=|=~|!~))/g;
+    const match = value.match(regexp);
+    return match ? match[match.length - 1] : "";
+  }, [value]);
+
+
+  const metricRegexp = new RegExp(`\\(?(${escapeRegExp(metric)})$`, "g");
+  const labelRegexp = /[{.,].?(\w+)$/gm;
+  const valueRegexp = new RegExp(`(${escapeRegExp(metric)})?{?.+${escapeRegExp(label)}="?([^"]*)$`, "g");
+
+  const context = useMemo(() => {
+    [metricRegexp, labelRegexp, valueRegexp].forEach(regexp => regexp.lastIndex = 0);
+    switch (true) {
+      case valueRegexp.test(value):
+        return ContextType.value;
+      case labelRegexp.test(value):
+        return ContextType.label;
+      case metricRegexp.test(value):
+        return ContextType.metricsql;
+      default:
+        return ContextType.empty;
+    }
+  }, [value, valueRegexp, labelRegexp, metricRegexp]);
+
+  const { metrics, labels, values } = useFetchQueryOptions({ metric, label });
+
+  const options = useMemo(() => {
+    switch (context) {
+      case ContextType.metricsql:
+        return [...metrics, ...metricsqlFunctions];
+      case ContextType.label:
+        return labels;
+      case ContextType.value:
+        return values;
+      default:
+        return [];
+    }
+  }, [context, metrics, labels, values]);
+
+  const valueByContext = useMemo(() => {
+    if (value.length !== caretPosition[1]) return value;
+
+    const wordMatch = value.match(/([\w_]+)$/) || [];
+    return wordMatch[1] || "";
+  }, [context, caretPosition, value]);
+
+  const handleSelect = (insert: string) => {
+    const wordMatch = value.match(/([\w_]+)$/);
+    const wordMatchIndex = wordMatch?.index !== undefined ? wordMatch.index : value.length;
+    const beforeInsert = value.substring(0, wordMatchIndex);
+    const afterInsert = value.substring(wordMatchIndex + (wordMatch?.[1].length || 0));
+
+    if (context === ContextType.value) {
+      const quote = "\"";
+      const needsQuote = beforeInsert[beforeInsert.length - 1] !== quote;
+      insert = `${needsQuote ? quote : ""}${insert}${quote}`;
+    }
+
+    const newVal = `${beforeInsert}${insert}${afterInsert}`;
+    onSelect(newVal);
+  };
+
+  useEffect(() => {
+    if (!anchorEl.current) {
+      setLeftOffset(0);
+      return;
+    }
+
+    const style = window.getComputedStyle(anchorEl.current);
+    const fontSize = `${style.getPropertyValue("font-size")}`;
+    const fontFamily = `${style.getPropertyValue("font-family")}`;
+    const offset = getTextWidth(value, `${fontSize} ${fontFamily}`);
+    setLeftOffset(offset);
+  }, [anchorEl, caretPosition]);
+
+  return (
+    <Autocomplete
+      disabledFullScreen
+      value={valueByContext}
+      options={options}
+      anchor={anchorEl}
+      minLength={context === ContextType.metricsql ? 2 : 0}
+      offset={{ top: 0, left: leftOffset }}
+      onSelect={handleSelect}
+      onFoundOptions={onFoundOptions}
+    />
+  );
+};
+
+export default QueryEditorAutocomplete;
diff --git a/app/vmui/packages/vmui/src/components/Main/Autocomplete/Autocomplete.tsx b/app/vmui/packages/vmui/src/components/Main/Autocomplete/Autocomplete.tsx
index 5f9a7d45f..827340b50 100644
--- a/app/vmui/packages/vmui/src/components/Main/Autocomplete/Autocomplete.tsx
+++ b/app/vmui/packages/vmui/src/components/Main/Autocomplete/Autocomplete.tsx
@@ -1,4 +1,4 @@
-import React, { FC, Ref, useCallback, useEffect, useMemo, useRef, useState } from "preact/compat";
+import React, { FC, Ref, useCallback, useEffect, useMemo, useRef, useState, JSX } from "preact/compat";
 import classNames from "classnames";
 import Popper from "../Popper/Popper";
 import "./style.scss";
@@ -7,21 +7,33 @@ import useDeviceDetect from "../../../hooks/useDeviceDetect";
 import useBoolean from "../../../hooks/useBoolean";
 import useEventListener from "../../../hooks/useEventListener";
 
+export interface AutocompleteOptions {
+  value: string;
+  description?: string;
+  type?: string;
+  icon?: JSX.Element
+}
+
 interface AutocompleteProps {
   value: string
-  options: string[]
+  options: AutocompleteOptions[]
   anchor: Ref<HTMLElement>
   disabled?: boolean
-  maxWords?: number
   minLength?: number
   fullWidth?: boolean
   noOptionsText?: string
   selected?: string[]
   label?: string
   disabledFullScreen?: boolean
+  offset?: {top: number, left: number}
   onSelect: (val: string) => void
   onOpenAutocomplete?: (val: boolean) => void
-  onFoundOptions?: (val: string[]) => void
+  onFoundOptions?: (val: AutocompleteOptions[]) => void
+}
+
+enum FocusType {
+  mouse,
+  keyboard
 }
 
 const Autocomplete: FC<AutocompleteProps> = ({
@@ -29,13 +41,13 @@ const Autocomplete: FC<AutocompleteProps> = ({
   options,
   anchor,
   disabled,
-  maxWords = 1,
   minLength = 2,
   fullWidth,
   selected,
   noOptionsText,
   label,
   disabledFullScreen,
+  offset,
   onSelect,
   onOpenAutocomplete,
   onFoundOptions
@@ -43,7 +55,7 @@ const Autocomplete: FC<AutocompleteProps> = ({
   const { isMobile } = useDeviceDetect();
   const wrapperEl = useRef<HTMLDivElement>(null);
 
-  const [focusOption, setFocusOption] = useState(-1);
+  const [focusOption, setFocusOption] = useState<{index: number, type?: FocusType}>({ index: -1 });
 
   const {
     value: openAutocomplete,
@@ -54,9 +66,9 @@ const Autocomplete: FC<AutocompleteProps> = ({
   const foundOptions = useMemo(() => {
     if (!openAutocomplete) return [];
     try {
-      const regexp = new RegExp(String(value), "i");
-      const found = options.filter((item) => regexp.test(item) && (item !== value));
-      return found.sort((a,b) => (a.match(regexp)?.index || 0) - (b.match(regexp)?.index || 0));
+      const regexp = new RegExp(String(value.trim()), "i");
+      const found = options.filter((item) => regexp.test(item.value));
+      return found.sort((a,b) => (a.value.match(regexp)?.index || 0) - (b.value.match(regexp)?.index || 0));
     } catch (e) {
       return [];
     }
@@ -72,9 +84,17 @@ const Autocomplete: FC<AutocompleteProps> = ({
     if (!selected) handleCloseAutocomplete();
   };
 
+  const createHandlerMouseEnter = (index: number) => () => {
+    setFocusOption({ index, type: FocusType.mouse });
+  };
+
+  const handlerMouseLeave = () => {
+    setFocusOption({ index: -1 });
+  };
+
   const scrollToValue = () => {
-    if (!wrapperEl.current) return;
-    const target = wrapperEl.current.childNodes[focusOption] as HTMLElement;
+    if (!wrapperEl.current || focusOption.type === FocusType.mouse) return;
+    const target = wrapperEl.current.childNodes[focusOption.index] as HTMLElement;
     if (target?.scrollIntoView) target.scrollIntoView({ block: "center" });
   };
 
@@ -85,18 +105,24 @@ const Autocomplete: FC<AutocompleteProps> = ({
 
     if (key === "ArrowUp" && !modifiers && hasOptions) {
       e.preventDefault();
-      setFocusOption((prev) => prev <= 0 ? 0 : prev - 1);
+      setFocusOption(({ index }) => ({
+        index:  index <= 0 ? 0 : index - 1,
+        type: FocusType.keyboard
+      }));
     }
 
     if (key === "ArrowDown" && !modifiers && hasOptions) {
       e.preventDefault();
       const lastIndex = foundOptions.length - 1;
-      setFocusOption((prev) => prev >= lastIndex ? lastIndex : prev + 1);
+      setFocusOption(({ index }) => ({
+        index: index >= lastIndex ? lastIndex : index + 1,
+        type: FocusType.keyboard
+      }));
     }
 
     if (key === "Enter") {
-      const value = foundOptions[focusOption];
-      value && onSelect(value);
+      const item = foundOptions[focusOption.index];
+      item && onSelect(item.value);
       if (!selected) handleCloseAutocomplete();
     }
 
@@ -106,8 +132,7 @@ const Autocomplete: FC<AutocompleteProps> = ({
   }, [focusOption, foundOptions, handleCloseAutocomplete, onSelect, selected]);
 
   useEffect(() => {
-    const words = (value.match(/[a-zA-Z_:.][a-zA-Z0-9_:.]*/gm) || []).length;
-    setOpenAutocomplete(value.length > minLength && words <= maxWords);
+    setOpenAutocomplete(value.length >= minLength);
   }, [value]);
 
   useEventListener("keydown", handleKeyDown);
@@ -115,7 +140,7 @@ const Autocomplete: FC<AutocompleteProps> = ({
   useEffect(scrollToValue, [focusOption, foundOptions]);
 
   useEffect(() => {
-    setFocusOption(-1);
+    setFocusOption({ index: -1 });
   }, [foundOptions]);
 
   useEffect(() => {
@@ -135,6 +160,7 @@ const Autocomplete: FC<AutocompleteProps> = ({
       fullWidth={fullWidth}
       title={isMobile ? label : undefined}
       disabledFullScreen={disabledFullScreen}
+      offset={offset}
     >
       <div
         className={classNames({
@@ -149,19 +175,34 @@ const Autocomplete: FC<AutocompleteProps> = ({
             className={classNames({
               "vm-list-item": true,
               "vm-list-item_mobile": isMobile,
-              "vm-list-item_active": i === focusOption,
+              "vm-list-item_active": i === focusOption.index,
               "vm-list-item_multiselect": selected,
-              "vm-list-item_multiselect_selected": selected?.includes(option)
+              "vm-list-item_multiselect_selected": selected?.includes(option.value),
+              "vm-list-item_with-icon":  option.icon,
             })}
-            id={`$autocomplete$${option}`}
-            key={option}
-            onClick={createHandlerSelect(option)}
+            id={`$autocomplete$${option.value}`}
+            key={`${i}${option.value}`}
+            onClick={createHandlerSelect(option.value)}
+            onMouseEnter={createHandlerMouseEnter(i)}
+            onMouseLeave={handlerMouseLeave}
           >
-            {selected?.includes(option) && <DoneIcon/>}
-            <span>{option}</span>
+            {selected?.includes(option.value) && <DoneIcon/>}
+            <>{option.icon}</>
+            <span>{option.value}</span>
           </div>
         )}
       </div>
+      {foundOptions[focusOption.index]?.description && (
+        <div className="vm-autocomplete-info">
+          <div className="vm-autocomplete-info__type">
+            {foundOptions[focusOption.index].type}
+          </div>
+          <div
+            className="vm-autocomplete-info__description"
+            dangerouslySetInnerHTML={{ __html: foundOptions[focusOption.index].description || "" }}
+          />
+        </div>
+      )}
     </Popper>
   );
 };
diff --git a/app/vmui/packages/vmui/src/components/Main/Autocomplete/style.scss b/app/vmui/packages/vmui/src/components/Main/Autocomplete/style.scss
index a1905058a..d5d3f360e 100644
--- a/app/vmui/packages/vmui/src/components/Main/Autocomplete/style.scss
+++ b/app/vmui/packages/vmui/src/components/Main/Autocomplete/style.scss
@@ -1,6 +1,7 @@
 @use "src/styles/variables" as *;
 
 .vm-autocomplete {
+  position: relative;
   max-height: 300px;
   overflow: auto;
   overscroll-behavior: none;
@@ -14,4 +15,34 @@
     text-align: center;
     color: $color-text-disabled;
   }
+
+  &-info {
+    position: absolute;
+    top: calc(100% + 1px);
+    left: 0;
+    right: 0;
+    min-width: 450px;
+    padding: $padding-global;
+    background-color: $color-background-block;
+    box-shadow: $box-shadow-popper;
+    border-radius: $border-radius-small;
+    overflow-wrap: anywhere;
+
+    &__type {
+      color: $color-text-secondary;
+      margin-bottom: $padding-small;
+    }
+
+    &__description {
+      line-height: 130%;
+
+      p {
+        margin: $padding-global 0;
+
+        &:last-child {
+          margin: 0;
+        }
+      }
+    }
+  }
 }
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 4831ba7ec..a3af70c69 100644
--- a/app/vmui/packages/vmui/src/components/Main/Icons/index.tsx
+++ b/app/vmui/packages/vmui/src/components/Main/Icons/index.tsx
@@ -1,4 +1,5 @@
 import React from "react";
+import { getCssVariable } from "../../../utils/theme";
 
 export const LogoIcon = () => (
   <svg
@@ -450,3 +451,53 @@ export const StarIcon = () => (
     <path d="M12 17.27 18.18 21l-1.64-7.03L22 9.24l-7.19-.61L12 2 9.19 8.63 2 9.24l5.46 4.73L5.82 21z"></path>
   </svg>
 );
+
+export const MetricIcon = () => (
+  <svg
+    viewBox="0 0 16 16"
+    fill={getCssVariable("color-error")}
+  >
+    <path
+      d="M13.5095 4L8.50952 1H7.50952L2.50952 4L2.01953 4.85999V10.86L2.50952 11.71L7.50952 14.71H8.50952L13.5095 11.71L13.9995 10.86V4.85999L13.5095 4ZM7.50952 13.5601L3.00952 10.86V5.69995L7.50952 8.15002V13.5601ZM3.26953 4.69995L8.00952 1.85999L12.7495 4.69995L8.00952 7.29004L3.26953 4.69995ZM13.0095 10.86L8.50952 13.5601V8.15002L13.0095 5.69995V10.86Z"
+    />
+  </svg>
+);
+
+export const FunctionIcon = () => (
+  <svg
+    viewBox="0 0 16 16"
+    fill={getCssVariable("color-primary")}
+  >
+    <path
+      fillRule="evenodd"
+      clipRule="evenodd"
+      d="M2 5H4V4H1.5L1 4.5V12.5L1.5 13H4V12H2V5ZM14.5 4H12V5H14V12H12V13H14.5L15 12.5V4.5L14.5 4ZM11.76 6.56995L12 7V9.51001L11.7 9.95996L7.19995 11.96H6.73999L4.23999 10.46L4 10.03V7.53003L4.30005 7.06995L8.80005 5.06995H9.26001L11.76 6.56995ZM5 9.70996L6.5 10.61V9.28003L5 8.38V9.70996ZM5.57996 7.56006L7.03003 8.43005L10.42 6.93005L8.96997 6.06006L5.57996 7.56006ZM7.53003 10.73L11.03 9.17004V7.77002L7.53003 9.31995V10.73Z"
+    />
+  </svg>
+);
+
+export const LabelIcon = () => (
+  <svg
+    viewBox="0 0 16 16"
+    fill={getCssVariable("color-warning")}
+  >
+    <path
+      fillRule="evenodd"
+      clipRule="evenodd"
+      d="M14 2H8L7 3V6H8V3H14V8H10V9H14L15 8V3L14 2ZM9 6H13V7H9.41L9 6.59V6ZM7 7H2L1 8V13L2 14H8L9 13V8L8 7H7ZM8 13H2V8H8V9V13ZM3 9H7V10H3V9ZM3 11H7V12H3V11ZM9 4H13V5H9V4Z"
+    />
+  </svg>
+);
+
+export const ValueIcon = () => (
+  <svg
+    viewBox="0 0 16 16"
+    fill={getCssVariable("color-primary")}
+  >
+    <path
+      fillRule="evenodd"
+      clipRule="evenodd"
+      d="M7 3L8 2H14L15 3V8L14 9H10V8H14V3H8V6H7V3ZM9 9V8L8 7H7H2L1 8V13L2 14H8L9 13V9ZM8 8V9V13H2V8H7H8ZM9.41421 7L9 6.58579V6H13V7H9.41421ZM9 4H13V5H9V4ZM7 10H3V11H7V10Z"
+    />
+  </svg>
+);
diff --git a/app/vmui/packages/vmui/src/components/Main/Select/Select.tsx b/app/vmui/packages/vmui/src/components/Main/Select/Select.tsx
index 906df1a03..4d93eddaa 100644
--- a/app/vmui/packages/vmui/src/components/Main/Select/Select.tsx
+++ b/app/vmui/packages/vmui/src/components/Main/Select/Select.tsx
@@ -160,11 +160,10 @@ const Select: FC<SelectProps> = ({
       <Autocomplete
         label={label}
         value={autocompleteValue}
-        options={list}
+        options={list.map(el => ({ value: el }))}
         anchor={autocompleteAnchorEl}
         selected={selectedValues}
-        maxWords={10}
-        minLength={0}
+        minLength={1}
         fullWidth
         noOptionsText={noOptionsText}
         onSelect={handleSelected}
diff --git a/app/vmui/packages/vmui/src/components/Main/TextField/TextField.tsx b/app/vmui/packages/vmui/src/components/Main/TextField/TextField.tsx
index 7e6211e3b..ce1b21caa 100644
--- a/app/vmui/packages/vmui/src/components/Main/TextField/TextField.tsx
+++ b/app/vmui/packages/vmui/src/components/Main/TextField/TextField.tsx
@@ -1,6 +1,15 @@
-import React, { FC, KeyboardEvent, useEffect, useRef, HTMLInputTypeAttribute, ReactNode } from "react";
+import React, {
+  FC,
+  useEffect,
+  useRef,
+  useMemo,
+  FormEvent,
+  KeyboardEvent,
+  MouseEvent,
+  HTMLInputTypeAttribute,
+  ReactNode
+} from "react";
 import classNames from "classnames";
-import { useMemo } from "preact/compat";
 import { useAppState } from "../../../state/common/StateContext";
 import useDeviceDetect from "../../../hooks/useDeviceDetect";
 import TextFieldMessage from "./TextFieldMessage";
@@ -24,6 +33,7 @@ interface TextFieldProps {
   onKeyDown?: (e: KeyboardEvent) => void
   onFocus?: () => void
   onBlur?: () => void
+  onChangeCaret?: (position: number[]) => void
 }
 
 const TextField: FC<TextFieldProps> = ({
@@ -43,7 +53,8 @@ const TextField: FC<TextFieldProps> = ({
   onEnter,
   onKeyDown,
   onFocus,
-  onBlur
+  onBlur,
+  onChangeCaret,
 }) => {
   const { isDarkTheme } = useAppState();
   const { isMobile } = useDeviceDetect();
@@ -61,9 +72,18 @@ const TextField: FC<TextFieldProps> = ({
     "vm-text-field__input_textarea": type === "textarea",
   });
 
+  const updateCaretPosition = (target: HTMLInputElement | HTMLTextAreaElement) => {
+    const { selectionStart, selectionEnd } = target;
+    onChangeCaret && onChangeCaret([selectionStart || 0, selectionEnd || 0]);
+  };
+
+  const handleMouseUp = (e: MouseEvent<HTMLInputElement | HTMLTextAreaElement>) => {
+    updateCaretPosition(e.currentTarget);
+  };
+
   const handleKeyDown = (e: KeyboardEvent<HTMLInputElement | HTMLTextAreaElement>) => {
     onKeyDown && onKeyDown(e);
-
+    updateCaretPosition(e.currentTarget);
     const { key, ctrlKey, metaKey } = e;
     const isEnter = key === "Enter";
     const runByEnter = type !== "textarea" ? isEnter : isEnter && (metaKey || ctrlKey);
@@ -73,9 +93,10 @@ const TextField: FC<TextFieldProps> = ({
     }
   };
 
-  const handleChange = (e: React.FormEvent) => {
+  const handleChange = (e: FormEvent<HTMLInputElement | HTMLTextAreaElement>) => {
     if (disabled) return;
-    onChange && onChange((e.target as HTMLInputElement).value);
+    onChange && onChange(e.currentTarget.value);
+    updateCaretPosition(e.currentTarget);
   };
 
   useEffect(() => {
@@ -116,6 +137,7 @@ const TextField: FC<TextFieldProps> = ({
           onKeyDown={handleKeyDown}
           onFocus={handleFocus}
           onBlur={handleBlur}
+          onMouseUp={handleMouseUp}
         />
       )
       : (
@@ -132,6 +154,7 @@ const TextField: FC<TextFieldProps> = ({
           onKeyDown={handleKeyDown}
           onFocus={handleFocus}
           onBlur={handleBlur}
+          onMouseUp={handleMouseUp}
         />
       )
     }
diff --git a/app/vmui/packages/vmui/src/hooks/useFetchQueryOptions.ts b/app/vmui/packages/vmui/src/hooks/useFetchQueryOptions.ts
deleted file mode 100644
index 456ae367c..000000000
--- a/app/vmui/packages/vmui/src/hooks/useFetchQueryOptions.ts
+++ /dev/null
@@ -1,32 +0,0 @@
-import { useEffect, useState } from "preact/compat";
-import { getQueryOptions } from "../api/query-range";
-import { useAppState } from "../state/common/StateContext";
-
-export const useFetchQueryOptions = (): {
-  queryOptions: string[],
-} => {
-  const { serverUrl } = useAppState();
-
-  const [queryOptions, setQueryOptions] = useState([]);
-
-  const fetchOptions = async () => {
-    if (!serverUrl) return;
-    const url = getQueryOptions(serverUrl);
-
-    try {
-      const response = await fetch(url);
-      const resp = await response.json();
-      if (response.ok) {
-        setQueryOptions(resp.data);
-      }
-    } catch (e) {
-      console.error(e);
-    }
-  };
-
-  useEffect(() => {
-    fetchOptions();
-  }, [serverUrl]);
-
-  return { queryOptions };
-};
diff --git a/app/vmui/packages/vmui/src/hooks/useFetchQueryOptions.tsx b/app/vmui/packages/vmui/src/hooks/useFetchQueryOptions.tsx
new file mode 100644
index 000000000..1cd028058
--- /dev/null
+++ b/app/vmui/packages/vmui/src/hooks/useFetchQueryOptions.tsx
@@ -0,0 +1,94 @@
+import React, { StateUpdater, useEffect, useState } from "preact/compat";
+import { useAppState } from "../state/common/StateContext";
+import { AutocompleteOptions } from "../components/Main/Autocomplete/Autocomplete";
+import { LabelIcon, MetricIcon, ValueIcon } from "../components/Main/Icons";
+
+enum TypeData {
+  metric,
+  label,
+  value
+}
+
+type FetchDataArgs = {
+  url: string;
+  setter: StateUpdater<AutocompleteOptions[]>;
+  type: TypeData;
+}
+
+const icons = {
+  [TypeData.metric]: <MetricIcon />,
+  [TypeData.label]: <LabelIcon />,
+  [TypeData.value]: <ValueIcon />,
+};
+
+export const useFetchQueryOptions = ({ metric, label }: { metric: string; label: string }) => {
+  const { serverUrl } = useAppState();
+
+  const [metrics, setMetrics] = useState<AutocompleteOptions[]>([]);
+  const [labels, setLabels] = useState<AutocompleteOptions[]>([]);
+  const [values, setValues] = useState<AutocompleteOptions[]>([]);
+
+  const fetchData = async ({ url, setter, type, }: FetchDataArgs) => {
+    try {
+      const response = await fetch(url);
+      if (response.ok) {
+        const { data } = await response.json() as { data: string[] };
+        setter(data.map(l => ({
+          value: l,
+          type: `${type}`,
+          icon: icons[type]
+        })));
+      }
+    } catch (e) {
+      console.error(e);
+    }
+  };
+
+  useEffect(() => {
+    if (!serverUrl) {
+      setMetrics([]);
+      return;
+    }
+
+    fetchData({
+      url: `${serverUrl}/api/v1/label/__name__/values`,
+      setter: setMetrics,
+      type: TypeData.metric
+    });
+  }, [serverUrl]);
+
+  useEffect(() => {
+    const notFoundMetric = !metrics.find(m => m.value === metric);
+    if (!serverUrl || notFoundMetric) {
+      setLabels([]);
+      return;
+    }
+
+    fetchData({
+      url: `${serverUrl}/api/v1/labels?match[]=${metric}`,
+      setter: setLabels,
+      type: TypeData.label
+    });
+  }, [serverUrl, metric]);
+
+  useEffect(() => {
+    const notFoundMetric = !metrics.find(m => m.value === metric);
+    const notFoundLabel = !labels.find(l => l.value === label);
+    if (!serverUrl || notFoundMetric || notFoundLabel) {
+      setValues([]);
+      return;
+    }
+
+    fetchData({
+      url: `${serverUrl}/api/v1/label/${label}/values?match[]=${metric}`,
+      setter: setValues,
+      type: TypeData.value
+    });
+  }, [serverUrl, metric, label]);
+
+  return {
+    metrics,
+    labels,
+    values,
+  };
+};
diff --git a/app/vmui/packages/vmui/src/hooks/useGetMetricsQL.tsx b/app/vmui/packages/vmui/src/hooks/useGetMetricsQL.tsx
new file mode 100644
index 000000000..fbe3960f4
--- /dev/null
+++ b/app/vmui/packages/vmui/src/hooks/useGetMetricsQL.tsx
@@ -0,0 +1,78 @@
+import React, { useEffect, useState } from "preact/compat";
+import { FunctionIcon } from "../components/Main/Icons";
+import { AutocompleteOptions } from "../components/Main/Autocomplete/Autocomplete";
+import { marked } from "marked";
+import MetricsQL from "../assets/MetricsQL.md";
+
+const CATEGORY_TAG = "h3";
+const FUNCTION_TAG = "h4";
+const DESCRIPTION_TAG = "p";
+
+const docsUrl = "https://docs.victoriametrics.com/MetricsQL.html";
+const classLink = "vm-link vm-link_colored";
+
+const prepareDescription = (text: string): string => {
+  const replaceValue = `$1 target="_blank" class="${classLink}" $2${docsUrl}#`;
+  return text.replace(/(<a) (href=")#/gm, replaceValue);
+};
+
+const getParagraph = (el: Element): Element[] => {
+  const paragraphs: Element[] = [];
+  let nextEl = el.nextElementSibling;
+  while (nextEl && nextEl.tagName.toLowerCase() === DESCRIPTION_TAG) {
+    if (nextEl) paragraphs.push(nextEl);
+    nextEl = nextEl.nextElementSibling;
+  }
+  return paragraphs;
+};
+
+const createAutocompleteOption = (type: string, group: Element): AutocompleteOptions => {
+  const value = group.textContent ?? "";
+  const paragraphs = getParagraph(group);
+  const description = paragraphs.map(p => p.outerHTML ?? "").join("\n");
+  return {
+    type,
+    value,
+    description: prepareDescription(description),
+    icon: <FunctionIcon />,
+  };
+};
+
+const processGroups = (groups: NodeListOf<Element>): AutocompleteOptions[] => {
+  let type = "";
+  return Array.from(groups).map(group => {
+    const isCategory = group.tagName.toLowerCase() === CATEGORY_TAG;
+    type = isCategory ? group.textContent ?? "" : type;
+    return isCategory ? null : createAutocompleteOption(type, group);
+  }).filter(Boolean) as AutocompleteOptions[];
+};
+
+const useGetMetricsQL = () => {
+  const [metricsQLFunctions, setMetricsQLFunctions] = useState<AutocompleteOptions[]>([]);
+
+  const processMarkdown = (text: string) => {
+    const div = document.createElement("div");
+    div.innerHTML = marked(text);
+    const groups = div.querySelectorAll(`${CATEGORY_TAG}, ${FUNCTION_TAG}`);
+    const result = processGroups(groups);
+    setMetricsQLFunctions(result);
+  };
+
+  useEffect(() => {
+    const fetchMarkdown = async () => {
+      try {
+        const resp = await fetch(MetricsQL);
+        const text = await resp.text();
+        processMarkdown(text);
+      } catch (e) {
+        console.error("Error fetching or processing the MetricsQL.md file:", e);
+      }
+    };
+
+    fetchMarkdown();
+  }, []);
+
+  return metricsQLFunctions;
+};
+
+export default useGetMetricsQL;
diff --git a/app/vmui/packages/vmui/src/pages/CustomPanel/QueryConfigurator/QueryConfigurator.tsx b/app/vmui/packages/vmui/src/pages/CustomPanel/QueryConfigurator/QueryConfigurator.tsx
index 7648ffc0b..312fe4ec3 100644
--- a/app/vmui/packages/vmui/src/pages/CustomPanel/QueryConfigurator/QueryConfigurator.tsx
+++ b/app/vmui/packages/vmui/src/pages/CustomPanel/QueryConfigurator/QueryConfigurator.tsx
@@ -29,7 +29,6 @@ export interface QueryConfiguratorProps {
   setQueryErrors: StateUpdater<string[]>;
   setHideError: StateUpdater<boolean>;
   stats: QueryStats[];
-  queryOptions: string[]
   onHideQuery: (queries: number[]) => void
   onRunQuery: () => void
 }
@@ -39,7 +38,6 @@ const QueryConfigurator: FC<QueryConfiguratorProps> = ({
   setQueryErrors,
   setHideError,
   stats,
-  queryOptions,
   onHideQuery,
   onRunQuery
 }) => {
@@ -189,7 +187,6 @@ const QueryConfigurator: FC<QueryConfiguratorProps> = ({
           <QueryEditor
             value={stateQuery[i]}
             autocomplete={autocomplete}
-            options={queryOptions}
             error={queryErrors[i]}
             stats={stats[i]}
             onArrowUp={createHandlerArrow(-1, i)}
diff --git a/app/vmui/packages/vmui/src/pages/CustomPanel/index.tsx b/app/vmui/packages/vmui/src/pages/CustomPanel/index.tsx
index fb170f9bd..795ef78e6 100644
--- a/app/vmui/packages/vmui/src/pages/CustomPanel/index.tsx
+++ b/app/vmui/packages/vmui/src/pages/CustomPanel/index.tsx
@@ -8,7 +8,6 @@ import GraphSettings from "../../components/Configurators/GraphSettings/GraphSet
 import { useGraphDispatch, useGraphState } from "../../state/graph/GraphStateContext";
 import { AxisRange } from "../../state/graph/reducer";
 import Spinner from "../../components/Main/Spinner/Spinner";
-import { useFetchQueryOptions } from "../../hooks/useFetchQueryOptions";
 import TracingsView from "../../components/TraceQuery/TracingsView";
 import Trace from "../../components/TraceQuery/Trace";
 import TableSettings from "../../components/Table/TableSettings/TableSettings";
@@ -50,7 +49,6 @@ const CustomPanel: FC = () => {
   const { customStep, yaxis } = useGraphState();
   const graphDispatch = useGraphDispatch();
 
-  const { queryOptions } = useFetchQueryOptions();
   const {
     isLoading,
     liveData,
@@ -133,7 +131,6 @@ const CustomPanel: FC = () => {
         setQueryErrors={setQueryErrors}
         setHideError={setHideError}
         stats={queryStats}
-        queryOptions={queryOptions}
         onHideQuery={handleHideQuery}
         onRunQuery={handleRunQuery}
       />
diff --git a/app/vmui/packages/vmui/src/pages/ExploreLogs/ExploreLogsHeader/ExploreLogsHeader.tsx b/app/vmui/packages/vmui/src/pages/ExploreLogs/ExploreLogsHeader/ExploreLogsHeader.tsx
index 92f7480aa..0d51f1224 100644
--- a/app/vmui/packages/vmui/src/pages/ExploreLogs/ExploreLogsHeader/ExploreLogsHeader.tsx
+++ b/app/vmui/packages/vmui/src/pages/ExploreLogs/ExploreLogsHeader/ExploreLogsHeader.tsx
@@ -27,7 +27,6 @@ const ExploreLogsHeader: FC<ExploreLogHeaderProps> = ({ query, onChange, onRun }
         <QueryEditor
           value={query}
           autocomplete={false}
-          options={[]}
           onArrowUp={() => null}
           onArrowDown={() => null}
           onEnter={onRun}
diff --git a/app/vmui/packages/vmui/src/styles/components/list.scss b/app/vmui/packages/vmui/src/styles/components/list.scss
index 8dd60bb5f..9fc9f5849 100644
--- a/app/vmui/packages/vmui/src/styles/components/list.scss
+++ b/app/vmui/packages/vmui/src/styles/components/list.scss
@@ -35,5 +35,13 @@
         color: $color-primary;
       }
     }
+
+    &_with-icon {
+      display: grid;
+      grid-template-columns: 14px 1fr;
+      gap: calc($padding-small/2);
+      align-items: center;
+      justify-content: flex-start;
+    }
   }
 }
diff --git a/app/vmui/packages/vmui/src/types/markdown.d.ts b/app/vmui/packages/vmui/src/types/markdown.d.ts
new file mode 100644
index 000000000..d3f4b12bc
--- /dev/null
+++ b/app/vmui/packages/vmui/src/types/markdown.d.ts
@@ -0,0 +1,4 @@
+declare module "*.md" {
+  const value: string;
+  export default value;
+}
diff --git a/app/vmui/packages/vmui/src/utils/regexp.ts b/app/vmui/packages/vmui/src/utils/regexp.ts
new file mode 100644
index 000000000..96e6f859c
--- /dev/null
+++ b/app/vmui/packages/vmui/src/utils/regexp.ts
@@ -0,0 +1,3 @@
+export const escapeRegExp = (str: string) => {
+  return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); // $& means the whole matched string
+};
diff --git a/docs/Articles.md b/docs/Articles.md
index c6c1f6e28..11df52803 100644
--- a/docs/Articles.md
+++ b/docs/Articles.md
@@ -137,5 +137,5 @@ See also [case studies](https://docs.victoriametrics.com/CaseStudies.html).
 * [VictoriaMetrics Meetup December 2022](https://www.youtube.com/watch?v=Mesc6JBFNhQ). See also [slides for "VictoriaMetrics 2022: new features" talk](https://docs.google.com/presentation/d/1jI7XZoodmuzLymdu4MToG9onAKQjzCNwMO2NDupyUkQ/edit?usp=sharing).
 * [Comparing Thanos to VictoriaMetrics cluster](https://faun.pub/comparing-thanos-to-victoriametrics-cluster-b193bea1683)
 * [Evaluation performance and correctness: VictoriaMetrics response](https://valyala.medium.com/evaluating-performance-and-correctness-victoriametrics-response-e27315627e87)
-* [How to reduce expenses on monitoring slides](https://www.slideshare.net/RomanKhavronenko/how-to-reduce-expenses-on-monitoringpdf)
+* [How to reduce expenses on monitoring slides](https://www.slideshare.net/RomanKhavronenko/how-to-reduce-expenses-on-monitoringpdf) and [video](https://www.youtube.com/watch?v=lnVnF79XdoE)
 * [Writing a TSDB from Scratch: Performance Optimization](https://www.youtube.com/watch?v=NdjuW98ep_w)
diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md
index dfbfc72dc..b07737344 100644
--- a/docs/CHANGELOG.md
+++ b/docs/CHANGELOG.md
@@ -28,9 +28,19 @@ The sandbox cluster installation is running under the constant load generated by
 
 ## tip
 
+**vmalert's cmd-line flag `datasource.queryTimeAlignment` was deprecated and will have no effect anymore. It will be completely removed in next releases. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/5049) and more detailed changes below.**
+
+* FEATURE: [vmalert](https://docs.victoriametrics.com/vmalert.html): add `eval_alignment` attribute for [Groups](https://docs.victoriametrics.com/vmalert.html#groups), it will align group query requests timestamp with interval like `datasource.queryTimeAlignment` did.
+  This also means that `datasource.queryTimeAlignment` command-line flag becomes deprecated now and will have no effect if configured. If `datasource.queryTimeAlignment` was set to `false` before, then `eval_alignment` has to be set to `false` explicitly under group.
+  See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/5049).
 * FEATURE: [vmagent](https://docs.victoriametrics.com/vmagent.html): support data ingestion from [NewRelic infrastructure agent](https://docs.newrelic.com/docs/infrastructure/install-infrastructure-agent). See [these docs](https://docs.victoriametrics.com/Single-server-VictoriaMetrics.html#how-to-send-data-from-newrelic-agent), [this feature request](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/3520) and [this pull request](https://github.com/VictoriaMetrics/VictoriaMetrics/pull/4712).
 * FEATURE: [vmbackup](https://docs.victoriametrics.com/vmbackup.html): add `-filestream.disableFadvise` command-line flag, which can be used for disabling `fadvise` syscall during backup upload to the remote storage. By default `vmbackup` uses `fadvise` syscall in order to prevent from eviction of recently accessed data from the [OS page cache](https://en.wikipedia.org/wiki/Page_cache) when backing up large files. Sometimes the `fadvise` syscall may take significant amounts of CPU when the backup is performed with large value of `-concurrency` command-line flag on systems with big number of CPU cores. In this case it is better to manually disable `fadvise` syscall by passing `-filestream.disableFadvise` command-line flag to `vmbackup`. See [this pull request](https://github.com/VictoriaMetrics/VictoriaMetrics/pull/5120) for details.
 * FEATURE: [Alerting rules for VictoriaMetrics](https://github.com/VictoriaMetrics/VictoriaMetrics/tree/master/deployment/docker#alerts): account for `vmauth` component for alerts `ServiceDown` and `TooManyRestarts`.
+* FEATURE: [vmui](https://docs.victoriametrics.com/#vmui): add support for functions, labels, values in autocomplete. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/3006).
+
+* BUGFIX: [vmalert](https://docs.victoriametrics.com/vmalert.html): strip sensitive information such as auth headers or passwords from datasource, remote-read, remote-write or notifier URLs in log messages or UI. This behavior is by default and is controlled via `-datasource.showURL`, `-remoteRead.showURL`, `remoteWrite.showURL` or `-notifier.showURL` cmd-line flags. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/5044).
+
+* BUGFIX: [vmselect](https://docs.victoriametrics.com/Cluster-VictoriaMetrics.html): improve performance and memory usage during query processing on machines with big number of CPU cores. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/5087) for details.
 
 ## [v1.94.0](https://github.com/VictoriaMetrics/VictoriaMetrics/releases/tag/v1.94.0)
 
diff --git a/docs/Cluster-VictoriaMetrics.md b/docs/Cluster-VictoriaMetrics.md
index 2d768dbce..2bf2522cb 100644
--- a/docs/Cluster-VictoriaMetrics.md
+++ b/docs/Cluster-VictoriaMetrics.md
@@ -278,7 +278,7 @@ When `vmselect` runs with `-clusternativeListenAddr` command-line option, then i
 
 See [these docs](https://gist.github.com/f41gh7/76ed8e5fb1ebb9737fe746bae9175ee6) on how to set up mTLS in VictoriaMetrics cluster.
 
-[Enterprise version of VictoriaMetrics](https://docs.victoriametrics.com/enterprise.html) can be downloaded and evaluated for free from [the releases page](https://github.com/VictoriaMetrics/VictoriaMetrics/releases).
+[Enterprise version of VictoriaMetrics](https://docs.victoriametrics.com/enterprise.html) can be downloaded and evaluated for free from [the releases page](https://github.com/VictoriaMetrics/VictoriaMetrics/releases). You need to request a [free trial license](https://victoriametrics.com/products/enterprise/trial/) for evaluation.
 
 ## Monitoring
 
@@ -731,13 +731,13 @@ For example, the following config sets retention to 5 days for time series with
 
 See also [these docs](https://docs.victoriametrics.com/#retention-filters) for additional details on retention filters.
 
-Enterprise binaries can be downloaded and evaluated for free from [the releases page](https://github.com/VictoriaMetrics/VictoriaMetrics/releases).
+Enterprise binaries can be downloaded and evaluated for free from [the releases page](https://github.com/VictoriaMetrics/VictoriaMetrics/releases). . You need to request a [free trial license](https://victoriametrics.com/products/enterprise/trial/) for evaluation.
 
 ## Downsampling
 
 Downsampling is available in [enterprise version of VictoriaMetrics](https://docs.victoriametrics.com/enterprise.html). It is configured with `-downsampling.period` command-line flag. The same flag value must be passed to both `vmstorage` and `vmselect` nodes. See [these docs](https://docs.victoriametrics.com/#downsampling) for details.
 
-Enterprise binaries can be downloaded and evaluated for free from [the releases page](https://github.com/VictoriaMetrics/VictoriaMetrics/releases).
+Enterprise binaries can be downloaded and evaluated for free from [the releases page](https://github.com/VictoriaMetrics/VictoriaMetrics/releases). . You need to request a [free trial license](https://victoriametrics.com/products/enterprise/trial/) for evaluation.
 
 ## Profiling
 
@@ -915,11 +915,11 @@ Below is the output for `/path/to/vminsert -help`:
   -internStringMaxLen int
      The maximum length for strings to intern. A lower limit may save memory at the cost of higher CPU usage. See https://en.wikipedia.org/wiki/String_interning . See also -internStringDisableCache and -internStringCacheExpireDuration (default 500)
   -license string
-     See https://victoriametrics.com/products/enterprise/ for trial license. This flag is available only in VictoriaMetrics enterprise. See https://docs.victoriametrics.com/enterprise.html
+     enterprise license key. This flag is available only in VictoriaMetrics enterprise. Documentation - https://docs.victoriametrics.com/enterprise.html, for more information, visit  https://victoriametrics.com/products/enterprise/ . To request a trial license, go to https://victoriametrics.com/products/enterprise/trial/
   -license.forceOffline
-     See https://victoriametrics.com/products/enterprise/ for trial license. This flag is available only in VictoriaMetrics enterprise. See https://docs.victoriametrics.com/enterprise.html
+     enables offline license verification. License keys issued must support this feature. Contact our support team for license keys with offline check support.
   -licenseFile string
-     See https://victoriametrics.com/products/enterprise/ for trial license. This flag is available only in VictoriaMetrics enterprise. See https://docs.victoriametrics.com/enterprise.html
+     path to file with enterprise license key. This flag is available only in VictoriaMetrics enterprise. Documentation - https://docs.victoriametrics.com/enterprise.html, for more information, visit  https://victoriametrics.com/products/enterprise/ . To request a trial license, go to https://victoriametrics.com/products/enterprise/trial/
   -loggerDisableTimestamps
      Whether to disable writing timestamps in logs
   -loggerErrorsPerSecondLimit int
@@ -1107,11 +1107,11 @@ Below is the output for `/path/to/vmselect -help`:
   -internStringMaxLen int
      The maximum length for strings to intern. A lower limit may save memory at the cost of higher CPU usage. See https://en.wikipedia.org/wiki/String_interning . See also -internStringDisableCache and -internStringCacheExpireDuration (default 500)
   -license string
-     See https://victoriametrics.com/products/enterprise/ for trial license. This flag is available only in VictoriaMetrics enterprise. See https://docs.victoriametrics.com/enterprise.html
+     enterprise license key. This flag is available only in VictoriaMetrics enterprise. Documentation - https://docs.victoriametrics.com/enterprise.html, for more information, visit  https://victoriametrics.com/products/enterprise/ . To request a trial license, go to https://victoriametrics.com/products/enterprise/trial/
   -license.forceOffline
-     See https://victoriametrics.com/products/enterprise/ for trial license. This flag is available only in VictoriaMetrics enterprise. See https://docs.victoriametrics.com/enterprise.html
+     enables offline license verification. License keys issued must support this feature. Contact our support team for license keys with offline check support.
   -licenseFile string
-     See https://victoriametrics.com/products/enterprise/ for trial license. This flag is available only in VictoriaMetrics enterprise. See https://docs.victoriametrics.com/enterprise.html
+     path to file with enterprise license key. This flag is available only in VictoriaMetrics enterprise. Documentation - https://docs.victoriametrics.com/enterprise.html, for more information, visit  https://victoriametrics.com/products/enterprise/ . To request a trial license, go to https://victoriametrics.com/products/enterprise/trial/
   -loggerDisableTimestamps
      Whether to disable writing timestamps in logs
   -loggerErrorsPerSecondLimit int
@@ -1345,11 +1345,11 @@ Below is the output for `/path/to/vmstorage -help`:
   -internStringMaxLen int
      The maximum length for strings to intern. A lower limit may save memory at the cost of higher CPU usage. See https://en.wikipedia.org/wiki/String_interning . See also -internStringDisableCache and -internStringCacheExpireDuration (default 500)
   -license string
-     See https://victoriametrics.com/products/enterprise/ for trial license. This flag is available only in VictoriaMetrics enterprise. See https://docs.victoriametrics.com/enterprise.html
+     enterprise license key. This flag is available only in VictoriaMetrics enterprise. Documentation - https://docs.victoriametrics.com/enterprise.html, for more information, visit  https://victoriametrics.com/products/enterprise/ . To request a trial license, go to https://victoriametrics.com/products/enterprise/trial/
   -license.forceOffline
-     See https://victoriametrics.com/products/enterprise/ for trial license. This flag is available only in VictoriaMetrics enterprise. See https://docs.victoriametrics.com/enterprise.html
+     enables offline license verification. License keys issued must support this feature. Contact our support team for license keys with offline check support.
   -licenseFile string
-     See https://victoriametrics.com/products/enterprise/ for trial license. This flag is available only in VictoriaMetrics enterprise. See https://docs.victoriametrics.com/enterprise.html
+     path to file with enterprise license key. This flag is available only in VictoriaMetrics enterprise. Documentation - https://docs.victoriametrics.com/enterprise.html, for more information, visit  https://victoriametrics.com/products/enterprise/ . To request a trial license, go to https://victoriametrics.com/products/enterprise/trial/
   -logNewSeries
      Whether to log new series. This option is for debug purposes only. It can lead to performance issues when big number of new series are ingested into VictoriaMetrics
   -loggerDisableTimestamps
diff --git a/docs/PerTenantStatistic.md b/docs/PerTenantStatistic.md
index 4bac224b6..9ad033ec6 100644
--- a/docs/PerTenantStatistic.md
+++ b/docs/PerTenantStatistic.md
@@ -12,7 +12,7 @@ aliases:
 
 # VictoriaMetrics Cluster Per Tenant Statistic
 
-***The per-tenant statistic is a part of [enterprise package](https://docs.victoriametrics.com/enterprise.html). It is available for download and evaluation at [releases page](https://github.com/VictoriaMetrics/VictoriaMetrics/releases)***
+***The per-tenant statistic is a part of [enterprise package](https://docs.victoriametrics.com/enterprise.html). It is available for download and evaluation at [releases page](https://github.com/VictoriaMetrics/VictoriaMetrics/releases). You need to request a [free trial license](https://victoriametrics.com/products/enterprise/trial/) for evaluation.***
 
 <img alt="cluster-per-tenant-stat" src="PerTenantStatistic-stats.jpg">
 
diff --git a/docs/README.md b/docs/README.md
index 7b740e68e..3ebe2de37 100644
--- a/docs/README.md
+++ b/docs/README.md
@@ -33,6 +33,7 @@ If you have questions about VictoriaMetrics, then feel free asking them at [Vict
 See [features available in enterprise package](https://docs.victoriametrics.com/enterprise.html).
 Enterprise binaries can be downloaded and evaluated for free 
 from [the releases page](https://github.com/VictoriaMetrics/VictoriaMetrics/releases).
+See how to request a free trial license [here](https://victoriametrics.com/products/enterprise/trial/).
 
 VictoriaMetrics is developed at a fast pace, so it is recommended periodically checking the [CHANGELOG](https://docs.victoriametrics.com/CHANGELOG.html) and performing [regular upgrades](#how-to-upgrade-victoriametrics).
 
@@ -2570,11 +2571,11 @@ Pass `-help` to VictoriaMetrics in order to see the list of supported command-li
   -internStringMaxLen int
      The maximum length for strings to intern. A lower limit may save memory at the cost of higher CPU usage. See https://en.wikipedia.org/wiki/String_interning . See also -internStringDisableCache and -internStringCacheExpireDuration (default 500)
   -license string
-     See https://victoriametrics.com/products/enterprise/ for trial license. This flag is available only in VictoriaMetrics enterprise. See https://docs.victoriametrics.com/enterprise.html
+     enterprise license key. This flag is available only in VictoriaMetrics enterprise. Documentation - https://docs.victoriametrics.com/enterprise.html, for more information, visit  https://victoriametrics.com/products/enterprise/ . To request a trial license, go to https://victoriametrics.com/products/enterprise/trial/
   -license.forceOffline
-     See https://victoriametrics.com/products/enterprise/ for trial license. This flag is available only in VictoriaMetrics enterprise. See https://docs.victoriametrics.com/enterprise.html
+     enables offline license verification. License keys issued must support this feature. Contact our support team for license keys with offline check support.
   -licenseFile string
-     See https://victoriametrics.com/products/enterprise/ for trial license. This flag is available only in VictoriaMetrics enterprise. See https://docs.victoriametrics.com/enterprise.html
+     path to file with enterprise license key. This flag is available only in VictoriaMetrics enterprise. Documentation - https://docs.victoriametrics.com/enterprise.html, for more information, visit  https://victoriametrics.com/products/enterprise/ . To request a trial license, go to https://victoriametrics.com/products/enterprise/trial/
   -logNewSeries
      Whether to log new series. This option is for debug purposes only. It can lead to performance issues when big number of new series are ingested into VictoriaMetrics
   -loggerDisableTimestamps
diff --git a/docs/Single-server-VictoriaMetrics.md b/docs/Single-server-VictoriaMetrics.md
index d0f8da9ae..496d3886c 100644
--- a/docs/Single-server-VictoriaMetrics.md
+++ b/docs/Single-server-VictoriaMetrics.md
@@ -41,6 +41,7 @@ If you have questions about VictoriaMetrics, then feel free asking them at [Vict
 See [features available in enterprise package](https://docs.victoriametrics.com/enterprise.html).
 Enterprise binaries can be downloaded and evaluated for free 
 from [the releases page](https://github.com/VictoriaMetrics/VictoriaMetrics/releases).
+See how to request a free trial license [here](https://victoriametrics.com/products/enterprise/trial/).
 
 VictoriaMetrics is developed at a fast pace, so it is recommended periodically checking the [CHANGELOG](https://docs.victoriametrics.com/CHANGELOG.html) and performing [regular upgrades](#how-to-upgrade-victoriametrics).
 
@@ -2578,11 +2579,11 @@ Pass `-help` to VictoriaMetrics in order to see the list of supported command-li
   -internStringMaxLen int
      The maximum length for strings to intern. A lower limit may save memory at the cost of higher CPU usage. See https://en.wikipedia.org/wiki/String_interning . See also -internStringDisableCache and -internStringCacheExpireDuration (default 500)
   -license string
-     See https://victoriametrics.com/products/enterprise/ for trial license. This flag is available only in VictoriaMetrics enterprise. See https://docs.victoriametrics.com/enterprise.html
+     enterprise license key. This flag is available only in VictoriaMetrics enterprise. Documentation - https://docs.victoriametrics.com/enterprise.html, for more information, visit  https://victoriametrics.com/products/enterprise/ . To request a trial license, go to https://victoriametrics.com/products/enterprise/trial/
   -license.forceOffline
-     See https://victoriametrics.com/products/enterprise/ for trial license. This flag is available only in VictoriaMetrics enterprise. See https://docs.victoriametrics.com/enterprise.html
+     enables offline license verification. License keys issued must support this feature. Contact our support team for license keys with offline check support.
   -licenseFile string
-     See https://victoriametrics.com/products/enterprise/ for trial license. This flag is available only in VictoriaMetrics enterprise. See https://docs.victoriametrics.com/enterprise.html
+     path to file with enterprise license key. This flag is available only in VictoriaMetrics enterprise. Documentation - https://docs.victoriametrics.com/enterprise.html, for more information, visit  https://victoriametrics.com/products/enterprise/ . To request a trial license, go to https://victoriametrics.com/products/enterprise/trial/
   -logNewSeries
      Whether to log new series. This option is for debug purposes only. It can lead to performance issues when big number of new series are ingested into VictoriaMetrics
   -loggerDisableTimestamps
diff --git a/docs/enterprise.md b/docs/enterprise.md
index 401c3cacd..07fb1af69 100644
--- a/docs/enterprise.md
+++ b/docs/enterprise.md
@@ -85,11 +85,11 @@ This flag acknowledges that your usage fits one of the cases listed above.
 After v1.94.0 either `-eula` flag or the following flags are used:
 ```console
   -license string
-        See https://victoriametrics.com/products/enterprise/ for trial license
-  -license-file string
-        See https://victoriametrics.com/products/enterprise/ for trial license
+     enterprise license key. This flag is available only in VictoriaMetrics enterprise. Documentation - https://docs.victoriametrics.com/enterprise.html, for more information, visit  https://victoriametrics.com/products/enterprise/ . To request a trial license, go to https://victoriametrics.com/products/enterprise/trial/
   -license.forceOffline
-        Force offline verification of license code. License is verified online by default. This flag runs license verification offline.
+     enables offline license verification. License keys issued must support this feature. Contact our support team for license keys with offline check support.
+  -licenseFile string
+     path to file with enterprise license key. This flag is available only in VictoriaMetrics enterprise. Documentation - https://docs.victoriametrics.com/enterprise.html, for more information, visit  https://victoriametrics.com/products/enterprise/ . To request a trial license, go to https://victoriametrics.com/products/enterprise/trial/
 ```
 
 For example, the following command runs `victoria-metrics-enterprise` binary with the specified license:
@@ -258,6 +258,7 @@ Please, refer to monitoring section of each component for details on how to scra
 `vm_license_expires_in_seconds` is the amount of seconds until the license expires.
 
 Example alerts for [vmalert](https://docs.victoriametrics.com/vmalert.html):
+{% raw %}
 ```yaml
 groups:
   - name: vm-license
@@ -281,3 +282,4 @@ groups:
           description: "{{ $labels.instance }} of job {{ $labels.job }} license expires in {{ $value | humanizeDuration }}. 
             Please make sure to update the license before it expires."
 ```
+{% endraw %}
diff --git a/docs/managed-victoriametrics/how-to-monitor-k8s.md b/docs/managed-victoriametrics/how-to-monitor-k8s.md
index 252338ef3..dc0a70067 100644
--- a/docs/managed-victoriametrics/how-to-monitor-k8s.md
+++ b/docs/managed-victoriametrics/how-to-monitor-k8s.md
@@ -58,6 +58,7 @@ Install the Helm chart in a custom namespace
    </div>
 1. Create a YAML file of Helm values called dbaas.yaml with following content
    <div class="with-copy" markdown="1">
+
    ```yaml
    externalVM:
      read:
diff --git a/docs/vmagent.md b/docs/vmagent.md
index 0ab5d9514..cb9404b45 100644
--- a/docs/vmagent.md
+++ b/docs/vmagent.md
@@ -1038,6 +1038,7 @@ See also [troubleshooting docs](https://docs.victoriametrics.com/Troubleshooting
 
 The enterprise version of vmagent is available for evaluation at [releases](https://github.com/VictoriaMetrics/VictoriaMetrics/releases) page
 in `vmutils-...-enterprise.tar.gz` archives and in [docker images](https://hub.docker.com/r/victoriametrics/vmagent/tags) with tags containing `enterprise` suffix.
+See how to request a free trial license [here](https://victoriametrics.com/products/enterprise/trial/).
 
 ### Reading metrics from Kafka
 
@@ -1348,11 +1349,11 @@ See the docs at https://docs.victoriametrics.com/vmagent.html .
      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.
   -license string
-     See https://victoriametrics.com/products/enterprise/ for trial license. This flag is available only in VictoriaMetrics enterprise. See https://docs.victoriametrics.com/enterprise.html
+     enterprise license key. This flag is available only in VictoriaMetrics enterprise. Documentation - https://docs.victoriametrics.com/enterprise.html, for more information, visit  https://victoriametrics.com/products/enterprise/ . To request a trial license, go to https://victoriametrics.com/products/enterprise/trial/
   -license.forceOffline
-     See https://victoriametrics.com/products/enterprise/ for trial license. This flag is available only in VictoriaMetrics enterprise. See https://docs.victoriametrics.com/enterprise.html
+     enables offline license verification. License keys issued must support this feature. Contact our support team for license keys with offline check support.
   -licenseFile string
-     See https://victoriametrics.com/products/enterprise/ for trial license. This flag is available only in VictoriaMetrics enterprise. See https://docs.victoriametrics.com/enterprise.html
+     path to file with enterprise license key. This flag is available only in VictoriaMetrics enterprise. Documentation - https://docs.victoriametrics.com/enterprise.html, for more information, visit  https://victoriametrics.com/products/enterprise/ . To request a trial license, go to https://victoriametrics.com/products/enterprise/trial/
   -loggerDisableTimestamps
      Whether to disable writing timestamps in logs
   -loggerErrorsPerSecondLimit int
diff --git a/docs/vmalert.md b/docs/vmalert.md
index b8a3ac431..2ee63301a 100644
--- a/docs/vmalert.md
+++ b/docs/vmalert.md
@@ -142,6 +142,15 @@ name: <string>
 # By default, "prometheus" type is used.
 [ type: <string> ]
 
+# Optional
+# The evaluation timestamp will be aligned with group's interval, 
+# instead of using the actual timestamp that evaluation happens at.
+# By default, it's enabled to get more predictable results 
+# and to visually align with results plotted via Grafana or vmui.
+# See https://github.com/VictoriaMetrics/VictoriaMetrics/issues/5049 
+# Available starting from v1.95
+[ eval_alignment: <bool> | default true]
+
 # Optional list of HTTP URL parameters
 # applied for all rules requests within a group
 # For example:
@@ -538,10 +547,6 @@ Alertmanagers.
 To avoid recording rules results and alerts state duplication in VictoriaMetrics server
 don't forget to configure [deduplication](https://docs.victoriametrics.com/Single-server-VictoriaMetrics.html#deduplication).
 The recommended value for `-dedup.minScrapeInterval` must be multiple of vmalert's `-evaluationInterval`.
-If you observe inconsistent or "jumping" values in series produced by vmalert, try disabling `-datasource.queryTimeAlignment`
-command line flag. Because of alignment, two or more vmalert HA pairs will produce results with the same timestamps.
-But due of backfilling (data delivered to the datasource with some delay) values of such results may differ,
-which would affect deduplication logic and result into "jumping" datapoints.
 
 Alertmanager will automatically deduplicate alerts with identical labels, so ensure that
 all `vmalert`s are having the same config.
@@ -831,7 +836,8 @@ and check the `Last updates` section:
 Rows in the section represent ordered rule evaluations and their results. The column `curl` contains an example of
 HTTP request sent by vmalert to the `-datasource.url` during evaluation. If specific state shows that there were
 no samples returned and curl command returns data - then it is very likely there was no data in datasource on the
-moment when rule was evaluated.
+moment when rule was evaluated. Sensitive info is stripped from the `curl` examples - see [security](#security) section
+for more details.
 
 ### Debug mode
 
@@ -847,6 +853,8 @@ Just set `debug: true` in rule's configuration and vmalert will start printing a
 2022-09-15T13:36:56.153Z  DEBUG rule "TestGroup":"Conns" (2601299393013563564) at 2022-09-15T15:36:56+02:00: alert 10705778000901301787 {alertgroup="TestGroup",alertname="Conns",cluster="east-1",instance="localhost:8429",replica="a"} PENDING => FIRING: 1m0s since becoming active at 2022-09-15 15:35:56.126006 +0200 CEST m=+39.384575417
 ```
 
+Sensitive info is stripped from the `curl` examples - see [security](#security) section for more details.
+
 ### Never-firing alerts
 
 vmalert can detect if alert's expression doesn't match any time series in runtime 
@@ -891,6 +899,20 @@ The same issue can be caused by collision of configured `labels` on [Group](#gro
 To fix it one should avoid collisions by carefully picking label overrides in configuration.
 
 
+## Security
+
+See general recommendations regarding security [here](https://docs.victoriametrics.com/Single-server-VictoriaMetrics.html#security).
+
+vmalert [web UI](#web) exposes configuration details such as list of [Groups](#groups), active alerts, 
+[alerts state](#alerts-state), [notifiers](#notifier-configuration-file). Notifier addresses (sanitized) are attached
+as labels to metrics `vmalert_alerts_sent_.*` on `http://<vmalert>/metrics` page. Consider limiting user's access 
+to the web UI or `/metrics` page if this information is sensitive.
+
+[Alerts state](#alerts-state) page or [debug mode](#debug-mode) could emit additional information about configured
+datasource URL, GET params and headers. Sensitive information such as passwords or auth tokens is stripped by default.
+To disable stripping of such info pass `-datasource.showURL` cmd-line flag to vmalert.
+
+
 ## Profiling
 
 `vmalert` provides handlers for collecting the following [Go profiles](https://blog.golang.org/profiling-go-programs):
@@ -969,11 +991,13 @@ The shortlist of configuration flags is the following:
   -datasource.queryStep duration
      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
+     Flag is deprecated and will be removed in next releases, please use `eval_alignment` in rule group instead.
      Whether to align "time" parameter with evaluation interval.Alignment supposed to produce deterministic results despite 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
      Adds "round_digits" GET param to datasource requests. In VM "round_digits" limits the number of digits after the decimal point in response values.
   -datasource.showURL
-     Whether to show -datasource.url in the exported metrics. It is hidden by default, since it can contain sensitive info such as auth key
+     Whether to avoid stripping sensitive information such as auth headers or passwords from URLs in log messages or UI and exported metrics.
+     It is hidden by default, since it can contain sensitive info such as auth key.
   -datasource.tlsCAFile string
      Optional path to TLS CA file to use for verifying connections to -datasource.url. By default, system CA is used
   -datasource.tlsCertFile string
@@ -993,7 +1017,7 @@ The shortlist of configuration flags is the following:
   -disableAlertgroupLabel
      Whether to disable adding group's Name as label to generated alerts and time series.
   -dryRun
-     Whether to check only config files without running vmalert. The rules file are validated. The -rule flag must be specified.
+     Whether to check only config files without running vmalert. The rules file are validated. The -rule flag must be specified.   
   -enableTCP6
      Whether to enable IPv6 for listening and dialing. By default, only IPv4 TCP and UDP are used
   -envflag.enable
@@ -1042,11 +1066,11 @@ The shortlist of configuration flags is the following:
   -internStringMaxLen int
      The maximum length for strings to intern. A lower limit may save memory at the cost of higher CPU usage. See https://en.wikipedia.org/wiki/String_interning . See also -internStringDisableCache and -internStringCacheExpireDuration (default 500)
   -license string
-     See https://victoriametrics.com/products/enterprise/ for trial license. This flag is available only in VictoriaMetrics enterprise. See https://docs.victoriametrics.com/enterprise.html
+     enterprise license key. This flag is available only in VictoriaMetrics enterprise. Documentation - https://docs.victoriametrics.com/enterprise.html, for more information, visit  https://victoriametrics.com/products/enterprise/ . To request a trial license, go to https://victoriametrics.com/products/enterprise/trial/
   -license.forceOffline
-     See https://victoriametrics.com/products/enterprise/ for trial license. This flag is available only in VictoriaMetrics enterprise. See https://docs.victoriametrics.com/enterprise.html
+     enables offline license verification. License keys issued must support this feature. Contact our support team for license keys with offline check support.
   -licenseFile string
-     See https://victoriametrics.com/products/enterprise/ for trial license. This flag is available only in VictoriaMetrics enterprise. See https://docs.victoriametrics.com/enterprise.html
+     path to file with enterprise license key. This flag is available only in VictoriaMetrics enterprise. Documentation - https://docs.victoriametrics.com/enterprise.html, for more information, visit  https://victoriametrics.com/products/enterprise/ . To request a trial license, go to https://victoriametrics.com/products/enterprise/trial/
   -loggerDisableTimestamps
      Whether to disable writing timestamps in logs
   -loggerErrorsPerSecondLimit int
@@ -1122,6 +1146,9 @@ The shortlist of configuration flags is the following:
   -notifier.url array
      Prometheus Alertmanager URL, e.g. http://127.0.0.1:9093. List all Alertmanager URLs if it runs in the cluster mode to ensure high availability.
      Supports an array of values separated by comma or specified via multiple flags.
+  -notifier.showURL bool
+     Whether to avoid stripping sensitive information such as passwords from URLs in log messages or UI for -notifier.url.
+     It is hidden by default, since it can contain sensitive info such as auth key.
   -notifier.blackhole bool
      Whether to blackhole alerting notifications. Enable this flag if you want vmalert to evaluate alerting rules without sending any notifications to external receivers (eg. alertmanager). `-notifier.url`, `-notifier.config` and `-notifier.blackhole` are mutually exclusive.
   -pprofAuthKey string
diff --git a/docs/vmanomaly.md b/docs/vmanomaly.md
index 701aebbe4..f0f71b42d 100644
--- a/docs/vmanomaly.md
+++ b/docs/vmanomaly.md
@@ -12,7 +12,7 @@ aliases:
 
 # vmanomaly
 
-**_vmanomaly is a part of [enterprise package](https://docs.victoriametrics.com/enterprise.html).
+**_vmanomaly is a part of [enterprise package](https://docs.victoriametrics.com/enterprise.html). You need to request a [free trial license](https://victoriametrics.com/products/enterprise/trial/) for evaluation.
 Please [contact us](https://victoriametrics.com/contact-us/) to find out more._**
 
 ## About
@@ -206,6 +206,7 @@ vm_license_expires_in_seconds 4.886608e+06
 ```
 
 Example alerts for [vmalert](https://docs.victoriametrics.com/vmalert.html):
+{% raw %}
 ```yaml
 groups:
   - name: vm-license
@@ -229,3 +230,4 @@ groups:
           description: "{{ $labels.instance }} of job {{ $labels.job }} license expires in {{ $value | humanizeDuration }}. 
             Please make sure to update the license before it expires."
 ```
+{% endraw %}
diff --git a/docs/vmauth.md b/docs/vmauth.md
index 65e8d929c..32fb98b5e 100644
--- a/docs/vmauth.md
+++ b/docs/vmauth.md
@@ -440,11 +440,11 @@ See the docs at https://docs.victoriametrics.com/vmauth.html .
   -internStringMaxLen int
      The maximum length for strings to intern. A lower limit may save memory at the cost of higher CPU usage. See https://en.wikipedia.org/wiki/String_interning . See also -internStringDisableCache and -internStringCacheExpireDuration (default 500)
   -license string
-     See https://victoriametrics.com/products/enterprise/ for trial license. This flag is available only in VictoriaMetrics enterprise. See https://docs.victoriametrics.com/enterprise.html
+     enterprise license key. This flag is available only in VictoriaMetrics enterprise. Documentation - https://docs.victoriametrics.com/enterprise.html, for more information, visit  https://victoriametrics.com/products/enterprise/ . To request a trial license, go to https://victoriametrics.com/products/enterprise/trial/
   -license.forceOffline
-     See https://victoriametrics.com/products/enterprise/ for trial license. This flag is available only in VictoriaMetrics enterprise. See https://docs.victoriametrics.com/enterprise.html
+     enables offline license verification. License keys issued must support this feature. Contact our support team for license keys with offline check support.
   -licenseFile string
-     See https://victoriametrics.com/products/enterprise/ for trial license. This flag is available only in VictoriaMetrics enterprise. See https://docs.victoriametrics.com/enterprise.html
+     path to file with enterprise license key. This flag is available only in VictoriaMetrics enterprise. Documentation - https://docs.victoriametrics.com/enterprise.html, for more information, visit  https://victoriametrics.com/products/enterprise/ . To request a trial license, go to https://victoriametrics.com/products/enterprise/trial/
   -logInvalidAuthTokens
      Whether to log requests with invalid auth tokens. Such requests are always counted at vmauth_http_request_errors_total{reason="invalid_auth_token"} metric, which is exposed at /metrics page
   -loggerDisableTimestamps
diff --git a/docs/vmbackup.md b/docs/vmbackup.md
index bab4c7f06..9489a3d32 100644
--- a/docs/vmbackup.md
+++ b/docs/vmbackup.md
@@ -335,11 +335,11 @@ Run `vmbackup -help` in order to see all the available options:
   -internStringMaxLen int
      The maximum length for strings to intern. A lower limit may save memory at the cost of higher CPU usage. See https://en.wikipedia.org/wiki/String_interning . See also -internStringDisableCache and -internStringCacheExpireDuration (default 500)
   -license string
-     See https://victoriametrics.com/products/enterprise/ for trial license. This flag is available only in VictoriaMetrics enterprise. See https://docs.victoriametrics.com/enterprise.html
+     enterprise license key. This flag is available only in VictoriaMetrics enterprise. Documentation - https://docs.victoriametrics.com/enterprise.html, for more information, visit  https://victoriametrics.com/products/enterprise/ . To request a trial license, go to https://victoriametrics.com/products/enterprise/trial/
   -license.forceOffline
-     See https://victoriametrics.com/products/enterprise/ for trial license. This flag is available only in VictoriaMetrics enterprise. See https://docs.victoriametrics.com/enterprise.html
+     enables offline license verification. License keys issued must support this feature. Contact our support team for license keys with offline check support.
   -licenseFile string
-     See https://victoriametrics.com/products/enterprise/ for trial license. This flag is available only in VictoriaMetrics enterprise. See https://docs.victoriametrics.com/enterprise.html
+     path to file with enterprise license key. This flag is available only in VictoriaMetrics enterprise. Documentation - https://docs.victoriametrics.com/enterprise.html, for more information, visit  https://victoriametrics.com/products/enterprise/ . To request a trial license, go to https://victoriametrics.com/products/enterprise/trial/
   -loggerDisableTimestamps
      Whether to disable writing timestamps in logs
   -loggerErrorsPerSecondLimit int
diff --git a/docs/vmbackupmanager.md b/docs/vmbackupmanager.md
index 79bf14c90..90ac90359 100644
--- a/docs/vmbackupmanager.md
+++ b/docs/vmbackupmanager.md
@@ -11,7 +11,9 @@ aliases:
 ---
 # vmbackupmanager
 
-***vmbackupmanager is a part of [enterprise package](https://docs.victoriametrics.com/enterprise.html). It is available for download and evaluation at [releases page](https://github.com/VictoriaMetrics/VictoriaMetrics/releases)***
+***vmbackupmanager is a part of [enterprise package](https://docs.victoriametrics.com/enterprise.html). 
+It is available for download and evaluation at [releases page](https://github.com/VictoriaMetrics/VictoriaMetrics/releases).
+See how to request a free trial license [here](https://victoriametrics.com/products/enterprise/trial/).***
 
 The VictoriaMetrics backup manager automates regular backup procedures. It supports the following backup intervals: **hourly**, **daily**, **weekly** and **monthly**.
 Multiple backup intervals may be configured simultaneously. I.e. the backup manager creates hourly backups every hour, while it creates daily backups every day, etc.
@@ -482,11 +484,11 @@ command-line flags:
   -keepLastWeekly int
      Keep last N weekly backups. If 0 is specified next retention cycle removes all backups for given time period. (default -1)
   -license string
-     See https://victoriametrics.com/products/enterprise/ for trial license. This flag is available only in VictoriaMetrics enterprise. See https://docs.victoriametrics.com/enterprise.html
+     enterprise license key. This flag is available only in VictoriaMetrics enterprise. Documentation - https://docs.victoriametrics.com/enterprise.html, for more information, visit  https://victoriametrics.com/products/enterprise/ . To request a trial license, go to https://victoriametrics.com/products/enterprise/trial/
   -license.forceOffline
-     See https://victoriametrics.com/products/enterprise/ for trial license. This flag is available only in VictoriaMetrics enterprise. See https://docs.victoriametrics.com/enterprise.html
+     enables offline license verification. License keys issued must support this feature. Contact our support team for license keys with offline check support.
   -licenseFile string
-     See https://victoriametrics.com/products/enterprise/ for trial license. This flag is available only in VictoriaMetrics enterprise. See https://docs.victoriametrics.com/enterprise.html
+     path to file with enterprise license key. This flag is available only in VictoriaMetrics enterprise. Documentation - https://docs.victoriametrics.com/enterprise.html, for more information, visit  https://victoriametrics.com/products/enterprise/ . To request a trial license, go to https://victoriametrics.com/products/enterprise/trial/
   -loggerDisableTimestamps
      Whether to disable writing timestamps in logs
   -loggerErrorsPerSecondLimit int
diff --git a/docs/vmgateway.md b/docs/vmgateway.md
index c1a8ba5a1..cdfde225c 100644
--- a/docs/vmgateway.md
+++ b/docs/vmgateway.md
@@ -11,7 +11,9 @@ aliases:
 ---
 # vmgateway
 
-***vmgateway is a part of [enterprise package](https://docs.victoriametrics.com/enterprise.html). It is available for download and evaluation at [releases page](https://github.com/VictoriaMetrics/VictoriaMetrics/releases)***
+***vmgateway is a part of [enterprise package](https://docs.victoriametrics.com/enterprise.html). 
+It is available for download and evaluation at [releases page](https://github.com/VictoriaMetrics/VictoriaMetrics/releases).
+See how to request a free trial license [here](https://victoriametrics.com/products/enterprise/trial/).***
 
 <img alt="vmgateway" src="vmgateway-overview.jpeg">
 
@@ -381,11 +383,11 @@ The shortlist of configuration flags include the following:
   -internStringMaxLen int
      The maximum length for strings to intern. A lower limit may save memory at the cost of higher CPU usage. See https://en.wikipedia.org/wiki/String_interning . See also -internStringDisableCache and -internStringCacheExpireDuration (default 500)
   -license string
-     See https://victoriametrics.com/products/enterprise/ for trial license. This flag is available only in VictoriaMetrics enterprise. See https://docs.victoriametrics.com/enterprise.html
+     enterprise license key. This flag is available only in VictoriaMetrics enterprise. Documentation - https://docs.victoriametrics.com/enterprise.html, for more information, visit  https://victoriametrics.com/products/enterprise/ . To request a trial license, go to https://victoriametrics.com/products/enterprise/trial/
   -license.forceOffline
-     See https://victoriametrics.com/products/enterprise/ for trial license. This flag is available only in VictoriaMetrics enterprise. See https://docs.victoriametrics.com/enterprise.html
+     enables offline license verification. License keys issued must support this feature. Contact our support team for license keys with offline check support.
   -licenseFile string
-     See https://victoriametrics.com/products/enterprise/ for trial license. This flag is available only in VictoriaMetrics enterprise. See https://docs.victoriametrics.com/enterprise.html
+     path to file with enterprise license key. This flag is available only in VictoriaMetrics enterprise. Documentation - https://docs.victoriametrics.com/enterprise.html, for more information, visit  https://victoriametrics.com/products/enterprise/ . To request a trial license, go to https://victoriametrics.com/products/enterprise/trial/
   -loggerDisableTimestamps
      Whether to disable writing timestamps in logs
   -loggerErrorsPerSecondLimit int
diff --git a/docs/vmrestore.md b/docs/vmrestore.md
index 786f3f1d0..83541a118 100644
--- a/docs/vmrestore.md
+++ b/docs/vmrestore.md
@@ -141,11 +141,11 @@ i.e. the end result would be similar to [rsync --delete](https://askubuntu.com/q
   -internStringMaxLen int
      The maximum length for strings to intern. A lower limit may save memory at the cost of higher CPU usage. See https://en.wikipedia.org/wiki/String_interning . See also -internStringDisableCache and -internStringCacheExpireDuration (default 500)
   -license string
-     See https://victoriametrics.com/products/enterprise/ for trial license. This flag is available only in VictoriaMetrics enterprise. See https://docs.victoriametrics.com/enterprise.html
+     enterprise license key. This flag is available only in VictoriaMetrics enterprise. Documentation - https://docs.victoriametrics.com/enterprise.html, for more information, visit  https://victoriametrics.com/products/enterprise/ . To request a trial license, go to https://victoriametrics.com/products/enterprise/trial/
   -license.forceOffline
-     See https://victoriametrics.com/products/enterprise/ for trial license. This flag is available only in VictoriaMetrics enterprise. See https://docs.victoriametrics.com/enterprise.html
+     enables offline license verification. License keys issued must support this feature. Contact our support team for license keys with offline check support.
   -licenseFile string
-     See https://victoriametrics.com/products/enterprise/ for trial license. This flag is available only in VictoriaMetrics enterprise. See https://docs.victoriametrics.com/enterprise.html
+     path to file with enterprise license key. This flag is available only in VictoriaMetrics enterprise. Documentation - https://docs.victoriametrics.com/enterprise.html, for more information, visit  https://victoriametrics.com/products/enterprise/ . To request a trial license, go to https://victoriametrics.com/products/enterprise/trial/
   -loggerDisableTimestamps
      Whether to disable writing timestamps in logs
   -loggerErrorsPerSecondLimit int


Test patch:
diff --git a/app/vmalert/datasource/vm_prom_api_test.go b/app/vmalert/datasource/vm_prom_api_test.go
index 668e4418d..0a0105810 100644
--- a/app/vmalert/datasource/vm_prom_api_test.go
+++ b/app/vmalert/datasource/vm_prom_api_test.go
@@ -3,7 +3,6 @@ package datasource
 import (
 	"encoding/json"
 	"testing"
-	"time"
 )
 
 func BenchmarkMetrics(b *testing.B) {
@@ -19,74 +18,3 @@ func BenchmarkMetrics(b *testing.B) {
 		}
 	})
 }
-
-func TestGetPrometheusReqTimestamp(t *testing.T) {
-	offset := 30 * time.Minute
-	testCases := []struct {
-		name               string
-		s                  *VMStorage
-		queryTimeAlignment bool
-		originTS, expTS    string
-	}{
-		{
-			"with eval_offset, find previous offset point",
-			&VMStorage{
-				evaluationOffset:   &offset,
-				evaluationInterval: time.Hour,
-				lookBack:           1 * time.Minute,
-			},
-			false,
-			"2023-08-28T11:11:00+00:00",
-			"2023-08-28T10:30:00+00:00",
-		},
-		{
-			"with eval_offset",
-			&VMStorage{
-				evaluationOffset:   &offset,
-				evaluationInterval: time.Hour,
-			},
-			true,
-			"2023-08-28T11:41:00+00:00",
-			"2023-08-28T11:30:00+00:00",
-		},
-		{
-			"with query align",
-			&VMStorage{
-				evaluationInterval: time.Hour,
-			},
-			true,
-			"2023-08-28T11:11:00+00:00",
-			"2023-08-28T11:00:00+00:00",
-		},
-		{
-			"with query align and lookback",
-			&VMStorage{
-				evaluationInterval: time.Hour,
-				lookBack:           1 * time.Minute,
-			},
-			true,
-			"2023-08-28T11:11:00+00:00",
-			"2023-08-28T10:59:00+00:00",
-		},
-		{
-			"without query align",
-			&VMStorage{
-				evaluationInterval: time.Hour,
-			},
-			false,
-			"2023-08-28T11:11:00+00:00",
-			"2023-08-28T11:11:00+00:00",
-		},
-	}
-	for _, tc := range testCases {
-		oldAlignPara := *queryTimeAlignment
-		*queryTimeAlignment = tc.queryTimeAlignment
-		originT, _ := time.Parse(time.RFC3339, tc.originTS)
-		expT, _ := time.Parse(time.RFC3339, tc.expTS)
-		gotTS := tc.s.adjustReqTimestamp(originT)
-		if !gotTS.Equal(expT) {
-			t.Fatalf("get wrong prometheus request timestamp, expect %s, got %s", expT, gotTS)
-		}
-		*queryTimeAlignment = oldAlignPara
-	}
-}
diff --git a/app/vmalert/datasource/vm_test.go b/app/vmalert/datasource/vm_test.go
index aa2e79598..757b012b7 100644
--- a/app/vmalert/datasource/vm_test.go
+++ b/app/vmalert/datasource/vm_test.go
@@ -506,8 +506,7 @@ func TestRequestParams(t *testing.T) {
 			},
 			func(t *testing.T, r *http.Request) {
 				evalInterval := 15 * time.Second
-				tt := timestamp.Truncate(evalInterval)
-				exp := url.Values{"query": {query}, "step": {evalInterval.String()}, "time": {tt.Format(time.RFC3339)}}
+				exp := url.Values{"query": {query}, "step": {evalInterval.String()}, "time": {timestamp.Format(time.RFC3339)}}
 				checkEqualString(t, exp.Encode(), r.URL.RawQuery)
 			},
 		},
@@ -521,7 +520,6 @@ func TestRequestParams(t *testing.T) {
 			func(t *testing.T, r *http.Request) {
 				evalInterval := 15 * time.Second
 				tt := timestamp.Add(-time.Minute)
-				tt = tt.Truncate(evalInterval)
 				exp := url.Values{"query": {query}, "step": {evalInterval.String()}, "time": {tt.Format(time.RFC3339)}}
 				checkEqualString(t, exp.Encode(), r.URL.RawQuery)
 			},
@@ -549,8 +547,7 @@ func TestRequestParams(t *testing.T) {
 			},
 			func(t *testing.T, r *http.Request) {
 				evalInterval := 3 * time.Hour
-				tt := timestamp.Truncate(evalInterval)
-				exp := url.Values{"query": {query}, "step": {fmt.Sprintf("%ds", int(evalInterval.Seconds()))}, "time": {tt.Format(time.RFC3339)}}
+				exp := url.Values{"query": {query}, "step": {fmt.Sprintf("%ds", int(evalInterval.Seconds()))}, "time": {timestamp.Format(time.RFC3339)}}
 				checkEqualString(t, exp.Encode(), r.URL.RawQuery)
 			},
 		},
diff --git a/app/vmalert/group_test.go b/app/vmalert/group_test.go
index 258df230f..4b687d205 100644
--- a/app/vmalert/group_test.go
+++ b/app/vmalert/group_test.go
@@ -533,11 +533,11 @@ func TestGroupStartDelay(t *testing.T) {
 
 	f := func(atS, expS string) {
 		t.Helper()
-		at, err := time.Parse(time.DateTime, atS)
+		at, err := time.Parse(time.RFC3339Nano, atS)
 		if err != nil {
 			t.Fatal(err)
 		}
-		expTS, err := time.Parse(time.DateTime, expS)
+		expTS, err := time.Parse(time.RFC3339Nano, expS)
 		if err != nil {
 			t.Fatal(err)
 		}
@@ -549,37 +549,91 @@ func TestGroupStartDelay(t *testing.T) {
 	}
 
 	// test group without offset
-	f("2023-01-01 00:00:00", "2023-01-01 00:00:30")
-	f("2023-01-01 00:00:29", "2023-01-01 00:00:30")
-	f("2023-01-01 00:00:31", "2023-01-01 00:05:30")
+	f("2023-01-01T00:00:00.000+00:00", "2023-01-01T00:00:30.000+00:00")
+	f("2023-01-01T00:00:00.999+00:00", "2023-01-01T00:00:30.000+00:00")
+	f("2023-01-01T00:00:29.000+00:00", "2023-01-01T00:00:30.000+00:00")
+	f("2023-01-01T00:00:31.000+00:00", "2023-01-01T00:05:30.000+00:00")
 
 	// test group with offset smaller than above fixed randSleep,
 	// this way randSleep will always be enough
 	offset := 20 * time.Second
 	g.EvalOffset = &offset
 
-	f("2023-01-01 00:00:00", "2023-01-01 00:00:30")
-	f("2023-01-01 00:00:29", "2023-01-01 00:00:30")
-	f("2023-01-01 00:00:31", "2023-01-01 00:05:30")
+	f("2023-01-01T00:00:00.000+00:00", "2023-01-01T00:00:30.000+00:00")
+	f("2023-01-01T00:00:29.000+00:00", "2023-01-01T00:00:30.000+00:00")
+	f("2023-01-01T00:00:31.000+00:00", "2023-01-01T00:05:30.000+00:00")
 
 	// test group with offset bigger than above fixed randSleep,
 	// this way offset will be added to delay
 	offset = 3 * time.Minute
 	g.EvalOffset = &offset
 
-	f("2023-01-01 00:00:00", "2023-01-01 00:03:30")
-	f("2023-01-01 00:00:29", "2023-01-01 00:03:30")
-	f("2023-01-01 00:01:00", "2023-01-01 00:08:30")
-	f("2023-01-01 00:03:30", "2023-01-01 00:08:30")
-	f("2023-01-01 00:07:30", "2023-01-01 00:13:30")
+	f("2023-01-01T00:00:00.000+00:00", "2023-01-01T00:03:30.000+00:00")
+	f("2023-01-01T00:00:29.000+00:00", "2023-01-01T00:03:30.000+00:00")
+	f("2023-01-01T00:01:00.000+00:00", "2023-01-01T00:08:30.000+00:00")
+	f("2023-01-01T00:03:30.000+00:00", "2023-01-01T00:08:30.000+00:00")
+	f("2023-01-01T00:07:30.000+00:00", "2023-01-01T00:13:30.000+00:00")
 
 	offset = 10 * time.Minute
 	g.EvalOffset = &offset
 	// interval of 1h and key generate a static delay of 6m
 	g.Interval = time.Hour
 
-	f("2023-01-01 00:00:00", "2023-01-01 00:16:00")
-	f("2023-01-01 00:05:00", "2023-01-01 00:16:00")
-	f("2023-01-01 00:30:00", "2023-01-01 01:16:00")
+	f("2023-01-01T00:00:00.000+00:00", "2023-01-01T00:16:00.000+00:00")
+	f("2023-01-01T00:05:00.000+00:00", "2023-01-01T00:16:00.000+00:00")
+	f("2023-01-01T00:30:00.000+00:00", "2023-01-01T01:16:00.000+00:00")
+}
 
+func TestGetPrometheusReqTimestamp(t *testing.T) {
+	offset := 30 * time.Minute
+	disableAlign := false
+	testCases := []struct {
+		name            string
+		g               *Group
+		originTS, expTS string
+	}{
+		{
+			"with query align",
+			&Group{
+				Interval: time.Hour,
+			},
+			"2023-08-28T11:11:00+00:00",
+			"2023-08-28T11:00:00+00:00",
+		},
+		{
+			"without query align",
+			&Group{
+				Interval:      time.Hour,
+				evalAlignment: &disableAlign,
+			},
+			"2023-08-28T11:11:00+00:00",
+			"2023-08-28T11:11:00+00:00",
+		},
+		{
+			"with eval_offset, find previous offset point",
+			&Group{
+				EvalOffset: &offset,
+				Interval:   time.Hour,
+			},
+			"2023-08-28T11:11:00+00:00",
+			"2023-08-28T10:30:00+00:00",
+		},
+		{
+			"with eval_offset",
+			&Group{
+				EvalOffset: &offset,
+				Interval:   time.Hour,
+			},
+			"2023-08-28T11:41:00+00:00",
+			"2023-08-28T11:30:00+00:00",
+		},
+	}
+	for _, tc := range testCases {
+		originT, _ := time.Parse(time.RFC3339, tc.originTS)
+		expT, _ := time.Parse(time.RFC3339, tc.expTS)
+		gotTS := tc.g.adjustReqTimestamp(originT)
+		if !gotTS.Equal(expT) {
+			t.Fatalf("get wrong prometheus request timestamp, expect %s, got %s", expT, gotTS)
+		}
+	}
 }
diff --git a/app/vmalert/utils_test.go b/app/vmalert/utils_test.go
index 048d08cb6..5bee17ca6 100644
--- a/app/vmalert/utils_test.go
+++ b/app/vmalert/utils_test.go
@@ -7,41 +7,69 @@ import (
 
 func TestRequestToCurl(t *testing.T) {
 	f := func(req *http.Request, exp string) {
+		t.Helper()
 		got := requestToCurl(req)
 		if got != exp {
 			t.Fatalf("expected to have %q; got %q instead", exp, got)
 		}
 	}
 
-	req, _ := http.NewRequest(http.MethodPost, "foo.com", nil)
-	f(req, "curl -X POST 'http://foo.com'")
+	newReq := func(url string, queryParams ...string) *http.Request {
+		t.Helper()
+		r, err := http.NewRequest(http.MethodPost, url, nil)
+		if err != nil {
+			t.Fatal(err)
+		}
+		params := r.URL.Query()
+		for i := 0; i < len(queryParams); i += 2 {
+			params.Add(queryParams[i], queryParams[i+1])
+		}
+		r.URL.RawQuery = params.Encode()
 
-	req, _ = http.NewRequest(http.MethodGet, "https://foo.com", nil)
-	f(req, "curl -k -X GET 'https://foo.com'")
+		return r
+	}
 
-	req, _ = http.NewRequest(http.MethodPost, "foo.com", nil)
+	req := newReq("foo.com")
+	f(req, "curl -X POST 'http://foo.com'")
+
+	req = newReq("foo.com")
 	req.Header.Set("foo", "bar")
 	req.Header.Set("baz", "qux")
 	f(req, "curl -X POST -H 'Baz: qux' -H 'Foo: bar' 'http://foo.com'")
 
-	req, _ = http.NewRequest(http.MethodPost, "foo.com", nil)
-	params := req.URL.Query()
-	params.Add("query", "up")
-	params.Add("step", "10")
-	req.URL.RawQuery = params.Encode()
+	req = newReq("foo.com", "query", "up", "step", "10")
 	f(req, "curl -X POST 'http://foo.com?query=up&step=10'")
 
-	req, _ = http.NewRequest(http.MethodPost, "http://foo.com", nil)
-	params = req.URL.Query()
-	params.Add("query", "up")
-	params.Add("step", "10")
-	req.URL.RawQuery = params.Encode()
+	req = newReq("http://foo.com", "query", "up", "step", "10")
 	f(req, "curl -X POST 'http://foo.com?query=up&step=10'")
 
-	req, _ = http.NewRequest(http.MethodPost, "https://foo.com", nil)
-	params = req.URL.Query()
-	params.Add("query", "up")
-	params.Add("step", "10")
-	req.URL.RawQuery = params.Encode()
+	req = newReq("https://foo.com", "query", "up", "step", "10")
 	f(req, "curl -k -X POST 'https://foo.com?query=up&step=10'")
+
+	req = newReq("https://user:pass@foo.com", "query", "up", "step", "10")
+	f(req, "curl -k -X POST 'https://user:xxxxx@foo.com?query=up&step=10'")
+
+	req = newReq("https://user:pass@foo.com")
+	req.Header.Set("Authorisation", "Bearer 123456")
+	f(req, "curl -k -X POST -H 'Authorisation: <secret>' 'https://user:xxxxx@foo.com'")
+
+	req = newReq("https://user:pass@foo.com")
+	req.Header.Set("Authorisation", "Basic 123456")
+	f(req, "curl -k -X POST -H 'Authorisation: <secret>' 'https://user:xxxxx@foo.com'")
+
+	req = newReq("https://foo.com")
+	req.Header.Set("My-Password", "mypassword")
+	f(req, "curl -k -X POST -H 'My-Password: <secret>' 'https://foo.com'")
+
+	req = newReq("https://foo.com")
+	req.Header.Set("key-for", "my-new-key")
+	f(req, "curl -k -X POST -H 'Key-For: <secret>' 'https://foo.com'")
+
+	req = newReq("https://foo.com")
+	req.Header.Set("My-Secret-Org", "secret-organisation")
+	f(req, "curl -k -X POST -H 'My-Secret-Org: <secret>' 'https://foo.com'")
+
+	req = newReq("https://foo.com")
+	req.Header.Set("Token", "secret-token")
+	f(req, "curl -k -X POST -H 'Token: <secret>' 'https://foo.com'")
 }