Repository: VictoriaMetrics/VictoriaMetrics
Pull request #1892 (2021-12-02 07:16:26)

vmalert: introduce additional HTTP URL params per-group configuration
The new group field `params` allows to configure custom HTTP URL params
per each group. These params will be applied to every request before
executing rule's expression. Hot config reload is also supported.

Field `extra_filter_labels` was deprecated in favour of `params` field.
vmalert will print deprecation log message if config file contains
the deprecated field.

`params` fields are supported by both Prometheus and Graphite datasource types.

Signed-off-by: hagen1778 <roman@victoriametrics.com>

codecov[bot]: # [Codecov](https://codecov.io/gh/VictoriaMetrics/VictoriaMetrics/pull/1892?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=VictoriaMetrics) Report
> Merging [#1892](https://codecov.io/gh/VictoriaMetrics/VictoriaMetrics/pull/1892?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=VictoriaMetrics) (b090b74) into [master](https://codecov.io/gh/VictoriaMetrics/VictoriaMetrics/commit/ed54b27b8588ffa0b7b0c5e037749ba115527086?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=VictoriaMetrics) (ed54b27) will **increase** coverage by `0.12%`.
> The diff coverage is `68.18%`.

[![Impacted file tree graph](https://codecov.io/gh/VictoriaMetrics/VictoriaMetrics/pull/1892/graphs/tree.svg?width=650&height=150&src=pr&token=YND8dYVcXn&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=VictoriaMetrics)](https://codecov.io/gh/VictoriaMetrics/VictoriaMetrics/pull/1892?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=VictoriaMetrics)

```diff
@@            Coverage Diff             @@
##           master    #1892      +/-   ##
==========================================
+ Coverage   60.66%   60.79%   +0.12%     
==========================================
  Files         237      237              
  Lines       39612    39642      +30     
==========================================
+ Hits        24032    24100      +68     
+ Misses      13987    13946      -41     
- Partials     1593     1596       +3     
```


| [Impacted Files](https://codecov.io/gh/VictoriaMetrics/VictoriaMetrics/pull/1892?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=VictoriaMetrics) | Coverage Δ | |
|---|---|---|
| [app/vmalert/datasource/datasource.go](https://codecov.io/gh/VictoriaMetrics/VictoriaMetrics/pull/1892/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=VictoriaMetrics#diff-YXBwL3ZtYWxlcnQvZGF0YXNvdXJjZS9kYXRhc291cmNlLmdv) | `100.00% <ø> (ø)` | |
| [app/vmalert/datasource/init.go](https://codecov.io/gh/VictoriaMetrics/VictoriaMetrics/pull/1892/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=VictoriaMetrics#diff-YXBwL3ZtYWxlcnQvZGF0YXNvdXJjZS9pbml0Lmdv) | `0.00% <0.00%> (ø)` | |
| [app/vmalert/main.go](https://codecov.io/gh/VictoriaMetrics/VictoriaMetrics/pull/1892/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=VictoriaMetrics#diff-YXBwL3ZtYWxlcnQvbWFpbi5nbw==) | `35.00% <0.00%> (+0.17%)` | :arrow_up: |
| [app/vmalert/web.qtpl.go](https://codecov.io/gh/VictoriaMetrics/VictoriaMetrics/pull/1892/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=VictoriaMetrics#diff-YXBwL3ZtYWxlcnQvd2ViLnF0cGwuZ28=) | `4.31% <0.00%> (ø)` | |
| [app/vmalert/manager.go](https://codecov.io/gh/VictoriaMetrics/VictoriaMetrics/pull/1892/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=VictoriaMetrics#diff-YXBwL3ZtYWxlcnQvbWFuYWdlci5nbw==) | `76.81% <45.83%> (-7.49%)` | :arrow_down: |
| [app/vmalert/alerting.go](https://codecov.io/gh/VictoriaMetrics/VictoriaMetrics/pull/1892/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=VictoriaMetrics#diff-YXBwL3ZtYWxlcnQvYWxlcnRpbmcuZ28=) | `76.53% <100.00%> (ø)` | |
| [app/vmalert/config/config.go](https://codecov.io/gh/VictoriaMetrics/VictoriaMetrics/pull/1892/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=VictoriaMetrics#diff-YXBwL3ZtYWxlcnQvY29uZmlnL2NvbmZpZy5nbw==) | `78.78% <100.00%> (+1.96%)` | :arrow_up: |
| [app/vmalert/datasource/vm.go](https://codecov.io/gh/VictoriaMetrics/VictoriaMetrics/pull/1892/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=VictoriaMetrics#diff-YXBwL3ZtYWxlcnQvZGF0YXNvdXJjZS92bS5nbw==) | `86.13% <100.00%> (+2.64%)` | :arrow_up: |
| [app/vmalert/datasource/vm\_graphite\_api.go](https://codecov.io/gh/VictoriaMetrics/VictoriaMetrics/pull/1892/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=VictoriaMetrics#diff-YXBwL3ZtYWxlcnQvZGF0YXNvdXJjZS92bV9ncmFwaGl0ZV9hcGkuZ28=) | `87.80% <100.00%> (+1.31%)` | :arrow_up: |
| [app/vmalert/datasource/vm\_prom\_api.go](https://codecov.io/gh/VictoriaMetrics/VictoriaMetrics/pull/1892/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=VictoriaMetrics#diff-YXBwL3ZtYWxlcnQvZGF0YXNvdXJjZS92bV9wcm9tX2FwaS5nbw==) | `86.91% <100.00%> (-0.25%)` | :arrow_down: |
| ... and [8 more](https://codecov.io/gh/VictoriaMetrics/VictoriaMetrics/pull/1892/diff?src=pr&el=tree-more&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=VictoriaMetrics) | |

------

[Continue to review full report at Codecov](https://codecov.io/gh/VictoriaMetrics/VictoriaMetrics/pull/1892?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=VictoriaMetrics).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=VictoriaMetrics)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/VictoriaMetrics/VictoriaMetrics/pull/1892?src=pr&el=footer&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=VictoriaMetrics). Last update [2c41f25...b090b74](https://codecov.io/gh/VictoriaMetrics/VictoriaMetrics/pull/1892?src=pr&el=lastupdated&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=VictoriaMetrics). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=VictoriaMetrics).


Patch:
diff --git a/.github/workflows/check-licenses.yml b/.github/workflows/check-licenses.yml
index c591ebf24..d9aa35630 100644
--- a/.github/workflows/check-licenses.yml
+++ b/.github/workflows/check-licenses.yml
@@ -14,7 +14,7 @@ jobs:
       - name: Setup Go
         uses: actions/setup-go@main
         with:
-          go-version: 1.16
+          go-version: 1.17
         id: go
       - name: Code checkout
         uses: actions/checkout@master
diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index 1c679ba15..2160cbe25 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -16,7 +16,7 @@ jobs:
       - name: Setup Go
         uses: actions/setup-go@main
         with:
-          go-version: 1.16
+          go-version: 1.17
         id: go
       - name: Code checkout
         uses: actions/checkout@master
diff --git a/app/victoria-metrics/main.go b/app/victoria-metrics/main.go
index 8d3f251e8..060529447 100644
--- a/app/victoria-metrics/main.go
+++ b/app/victoria-metrics/main.go
@@ -90,15 +90,15 @@ func requestHandler(w http.ResponseWriter, r *http.Request) bool {
 		fmt.Fprintf(w, "See docs at <a href='https://docs.victoriametrics.com/'>https://docs.victoriametrics.com/</a></br>")
 		fmt.Fprintf(w, "Useful endpoints:</br>")
 		httpserver.WriteAPIHelp(w, [][2]string{
-			{"/vmui", "Web UI"},
-			{"/targets", "discovered targets list"},
-			{"/api/v1/targets", "advanced information about discovered targets in JSON format"},
-			{"/config", "-promscrape.config contents"},
-			{"/metrics", "available service metrics"},
-			{"/flags", "command-line flags"},
-			{"/api/v1/status/tsdb", "tsdb status page"},
-			{"/api/v1/status/top_queries", "top queries"},
-			{"/api/v1/status/active_queries", "active queries"},
+			{"vmui", "Web UI"},
+			{"targets", "discovered targets list"},
+			{"api/v1/targets", "advanced information about discovered targets in JSON format"},
+			{"config", "-promscrape.config contents"},
+			{"metrics", "available service metrics"},
+			{"flags", "command-line flags"},
+			{"api/v1/status/tsdb", "tsdb status page"},
+			{"api/v1/status/top_queries", "top queries"},
+			{"api/v1/status/active_queries", "active queries"},
 		})
 		return true
 	}
diff --git a/app/vmagent/main.go b/app/vmagent/main.go
index 7079c6b08..866dce329 100644
--- a/app/vmagent/main.go
+++ b/app/vmagent/main.go
@@ -158,12 +158,12 @@ func requestHandler(w http.ResponseWriter, r *http.Request) bool {
 		fmt.Fprintf(w, "See docs at <a href='https://docs.victoriametrics.com/vmagent.html'>https://docs.victoriametrics.com/vmagent.html</a></br>")
 		fmt.Fprintf(w, "Useful endpoints:</br>")
 		httpserver.WriteAPIHelp(w, [][2]string{
-			{"/targets", "discovered targets list"},
-			{"/api/v1/targets", "advanced information about discovered targets in JSON format"},
-			{"/config", "-promscrape.config contents"},
-			{"/metrics", "available service metrics"},
-			{"/flags", "command-line flags"},
-			{"/-/reload", "reload configuration"},
+			{"targets", "discovered targets list"},
+			{"api/v1/targets", "advanced information about discovered targets in JSON format"},
+			{"config", "-promscrape.config contents"},
+			{"metrics", "available service metrics"},
+			{"flags", "command-line flags"},
+			{"-/reload", "reload configuration"},
 		})
 		return true
 	}
diff --git a/app/vmalert/README.md b/app/vmalert/README.md
index b6fecdc74..38f73f7bf 100644
--- a/app/vmalert/README.md
+++ b/app/vmalert/README.md
@@ -99,12 +99,24 @@ name: <string>
 # By default "prometheus" type is used.
 [ type: <string> ]
 
-# Optional list of label filters applied to every rule's
-# request withing a group. Is compatible only with VM datasource.
-# See more details at https://docs.victoriametrics.com#prometheus-querying-api-enhancements
+# Warning: DEPRECATED
+# Please use `params` instead:
+#   params:
+#     extra_label: ["job=nodeexporter", "env=prod"]
 extra_filter_labels:
   [ <labelname>: <labelvalue> ... ]
 
+# Optional list of HTTP URL parameters
+# applied for all rules requests within a group
+# For example:
+#  params:
+#    nocache: ["1"]                # disable caching for vmselect
+#    denyPartialResponse: ["true"] # fail if one or more vmstorage nodes returned an error
+#    extra_label: ["env=dev"]      # apply additional label filter "env=dev" for all requests 
+# see more details at https://docs.victoriametrics.com#prometheus-querying-api-enhancements
+params:
+  [ <string>: [<string>, ...]]
+
 # Optional list of labels added to every rule within a group.
 # It has priority over the external labels.
 # Labels are commonly used for adding environment
@@ -256,7 +268,8 @@ you have recording rules or want to store [alerts state](#alerts-state-on-restar
 
 #### Single-node VictoriaMetrics
 
-<img alt="vmalert single" src="vmalert_single.png">
+The simplest configuration where one single-node VM server is used for
+rules execution, storing recording rules results and alerts state.
 
 `vmalert` configuration flags:
 ```
@@ -267,12 +280,16 @@ you have recording rules or want to store [alerts state](#alerts-state-on-restar
     -notifier.url=http://alertmanager:9093          # AlertManager addr to send alerts when they trigger
 ```
 
-The simplest configuration where one single-node VM server is used for
-rules execution, storing recording rules results and alerts state.
+<img alt="vmalert single" width="500" src="vmalert_single.png">
+
 
 #### Cluster VictoriaMetrics
 
-<img alt="vmalert cluster" src="vmalert_cluster.png">
+In [cluster mode](https://docs.victoriametrics.com/Cluster-VictoriaMetrics.html)
+VictoriaMetrics has separate components for writing and reading path:
+`vminsert` and `vmselect` components respectively. `vmselect` is used for executing rules expressions
+and `vminsert` is used to persist recording rules results and alerts state.
+Cluster mode could have multiple `vminsert` and `vmselect` components. 
 
 `vmalert` configuration flags:
 ```
@@ -283,18 +300,18 @@ rules execution, storing recording rules results and alerts state.
     -notifier.url=http://alertmanager:9093                      # AlertManager addr to send alerts when they trigger
 ```
 
-In [cluster mode](https://docs.victoriametrics.com/Cluster-VictoriaMetrics.html)
-VictoriaMetrics has separate components for writing and reading path:
-`vminsert` and `vmselect` components respectively. `vmselect` is used for executing rules expressions
-and `vminsert` is used to persist recording rules results and alerts state.
-Cluster mode could have multiple `vminsert` and `vmselect` components. In case when you want
-to spread the load on these components - add balancers before them and configure 
+<img alt="vmalert cluster" src="vmalert_cluster.png">
+
+In case when you want to spread the load on these components - add balancers before them and configure
 `vmalert` with balancer's addresses. Please, see more about VM's cluster architecture
 [here](https://docs.victoriametrics.com/Cluster-VictoriaMetrics.html#architecture-overview).
 
-#### vmalert high availability
+#### HA vmalert
 
-<img alt="vmalert ha" src="vmalert_ha.png">
+For HA user can run multiple identically configured `vmalert` instances.
+It means all of them will execute the same rules, write state and results to
+the same destinations, and send alert notifications to multiple configured
+Alertmanagers.
 
 `vmalert` configuration flags:
 ```
@@ -306,10 +323,7 @@ to spread the load on these components - add balancers before them and configure
     -notifier.url=http://alertmanagerN:9093         # The same alert will be sent to all configured notifiers
 ```
 
-For HA user can run multiple identically configured `vmalert` instances.
-It means all of them will execute the same rules, write state and results to
-the same destinations, and send alert notifications to multiple configured
-Alertmanagers.
+<img alt="vmalert ha" width="800px" src="vmalert_ha.png">
 
 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).
@@ -323,9 +337,15 @@ for Alertmanagers for better reliability.
 This example uses single-node VM server for the sake of simplicity. 
 Check how to replace it with [cluster VictoriaMetrics](#cluster-victoriametrics) if needed. 
 
+
 #### Downsampling and aggregation via vmalert
 
-<img alt="vmalert multi cluster" src="vmalert_multicluster.png">
+Example shows how to build a topology where `vmalert` will process data from one cluster
+and write results into another. Such clusters may be called as "hot" (low retention,
+high-speed disks, used for operative monitoring) and "cold" (long term retention,
+slower/cheaper disks, low resolution data). With help of `vmalert`, user can setup
+recording rules to process raw data from "hot" cluster (by applying additional transformations
+or reducing resolution) and push results to "cold" cluster.
 
 `vmalert` configuration flags:
 ```
@@ -334,17 +354,13 @@ Check how to replace it with [cluster VictoriaMetrics](#cluster-victoriametrics)
     -remoteWrite.url=http://aggregated-cluster-vminsert:8480/insert/0/prometheuss   # vminsert addr to persist recording rules results
 ```
 
-Example shows how to build a topology where `vmalert` will process data from one cluster
-and write results into another. Such clusters may be called as "hot" (low retention, 
-high-speed disks, used for operative monitoring) and "cold" (long term retention, 
-slower/cheaper disks, low resolution data). With help of `vmalert`, user can setup 
-recording rules to process raw data from "hot" cluster (by applying additional transformations 
-or reducing resolution) and push results to "cold" cluster. 
+<img alt="vmalert multi cluster" src="vmalert_multicluster.png">
 
 Please note, [replay](#rules-backfilling) feature may be used for transforming historical data.
 
 Flags `-remoteRead.url` and `-notifier.url` are omitted since we assume only recording rules are used.
 
+
 ### Web
 
 `vmalert` runs a web-server (`-httpListenAddr`) for serving metrics and alerts endpoints:
@@ -468,6 +484,8 @@ a review to the dashboard.
 
 ## Configuration
 
+### Flags
+
 Pass `-help` to `vmalert` in order to see the full list of supported
 command-line flags with their descriptions.
 
@@ -689,12 +707,32 @@ The shortlist of configuration flags is the following:
     	Show VictoriaMetrics version
 ```
 
+### Hot config reload
 `vmalert` supports "hot" config reload via the following methods:
 * send SIGHUP signal to `vmalert` process;
 * send GET request to `/-/reload` endpoint;
 * configure `-rule.configCheckInterval` flag for periodic reload
 on config change.
 
+### URL params
+
+To set additional URL params for `datasource.url`, `remoteWrite.url` or `remoteRead.url`
+just add them in address: `-datasource.url=http://localhost:8428?nocache=1`.
+
+To set additional URL params for specific [group of rules](#Groups) modify
+the `params` group:
+```yaml
+groups:
+  - name: TestGroup
+    params:
+      denyPartialResponse: ["true"]
+      extra_label: ["env=dev"]
+```
+Please note, `params` are used only for executing rules expressions (requests to `datasource.url`).
+If there would be a conflict between URL params set in `datasource.url` flag and params in group definition
+the latter will have higher priority.
+
+
 ## Contributing
 
 `vmalert` is mostly designed and built by VictoriaMetrics community.
@@ -710,7 +748,7 @@ It is recommended using
 
 ### Development build
 
-1. [Install Go](https://golang.org/doc/install). The minimum supported version is Go 1.16.
+1. [Install Go](https://golang.org/doc/install). The minimum supported version is Go 1.17.
 2. Run `make vmalert` from the root folder of [the repository](https://github.com/VictoriaMetrics/VictoriaMetrics).
    It builds `vmalert` binary and puts it into the `bin` folder.
 
@@ -727,7 +765,7 @@ ARM build may run on Raspberry Pi or on [energy-efficient ARM servers](https://b
 
 ### Development ARM build
 
-1. [Install Go](https://golang.org/doc/install). The minimum supported version is Go 1.16.
+1. [Install Go](https://golang.org/doc/install). The minimum supported version is Go 1.17.
 2. Run `make vmalert-arm` or `make vmalert-arm64` from the root folder of [the repository](https://github.com/VictoriaMetrics/VictoriaMetrics).
    It builds `vmalert-arm` or `vmalert-arm64` binary respectively and puts it into the `bin` folder.
 
diff --git a/app/vmalert/alerting.go b/app/vmalert/alerting.go
index 9342ebe0f..67259c792 100644
--- a/app/vmalert/alerting.go
+++ b/app/vmalert/alerting.go
@@ -71,7 +71,7 @@ func newAlertingRule(qb datasource.QuerierBuilder, group *Group, cfg config.Rule
 		q: qb.BuildWithParams(datasource.QuerierParams{
 			DataSourceType:     &group.Type,
 			EvaluationInterval: group.Interval,
-			ExtraLabels:        group.ExtraFilterLabels,
+			QueryParams:        group.Params,
 		}),
 		alerts:  make(map[uint64]*notifier.Alert),
 		metrics: &alertingRuleMetrics{},
diff --git a/app/vmalert/config/config.go b/app/vmalert/config/config.go
index a63706259..4f0dec609 100644
--- a/app/vmalert/config/config.go
+++ b/app/vmalert/config/config.go
@@ -5,17 +5,18 @@ import (
 	"fmt"
 	"hash/fnv"
 	"io/ioutil"
+	"net/url"
 	"path/filepath"
 	"sort"
 	"strings"
 
-	"github.com/VictoriaMetrics/VictoriaMetrics/app/vmalert/datasource"
+	"gopkg.in/yaml.v2"
 
+	"github.com/VictoriaMetrics/VictoriaMetrics/app/vmalert/datasource"
 	"github.com/VictoriaMetrics/VictoriaMetrics/app/vmalert/notifier"
 	"github.com/VictoriaMetrics/VictoriaMetrics/app/vmalert/utils"
 	"github.com/VictoriaMetrics/VictoriaMetrics/lib/envtemplate"
 	"github.com/VictoriaMetrics/VictoriaMetrics/lib/logger"
-	"gopkg.in/yaml.v2"
 )
 
 // Group contains list of Rules grouped into
@@ -30,6 +31,7 @@ type Group struct {
 	// ExtraFilterLabels is a list label filters applied to every rule
 	// request withing a group. Is compatible only with VM datasources.
 	// See https://docs.victoriametrics.com#prometheus-querying-api-enhancements
+	// DEPRECATED: use Params field instead
 	ExtraFilterLabels map[string]string `yaml:"extra_filter_labels"`
 	// Labels is a set of label value pairs, that will be added to every rule.
 	// It has priority over the external labels.
@@ -37,11 +39,15 @@ type Group struct {
 	// Checksum stores the hash of yaml definition for this group.
 	// May be used to detect any changes like rules re-ordering etc.
 	Checksum string
+	// Optional HTTP URL parameters added to each rule request
+	Params url.Values `yaml:"params"`
 
 	// Catches all undefined fields and must be empty after parsing.
 	XXX map[string]interface{} `yaml:",inline"`
 }
 
+const extraLabelParam = "extra_label"
+
 // UnmarshalYAML implements the yaml.Unmarshaler interface.
 func (g *Group) UnmarshalYAML(unmarshal func(interface{}) error) error {
 	type group Group
@@ -57,6 +63,16 @@ func (g *Group) UnmarshalYAML(unmarshal func(interface{}) error) error {
 		g.Type.Set(datasource.NewPrometheusType())
 	}
 
+	// backward compatibility with deprecated `ExtraFilterLabels` param
+	if len(g.ExtraFilterLabels) > 0 {
+		if g.Params == nil {
+			g.Params = url.Values{}
+		}
+		for k, v := range g.ExtraFilterLabels {
+			g.Params.Add(extraLabelParam, fmt.Sprintf("%s=%s", k, v))
+		}
+	}
+
 	h := md5.New()
 	h.Write(b)
 	g.Checksum = fmt.Sprintf("%x", h.Sum(nil))
@@ -178,6 +194,7 @@ func Parse(pathPatterns []string, validateAnnotations, validateExpressions bool)
 		fp = append(fp, matches...)
 	}
 	errGroup := new(utils.ErrGroup)
+	var isExtraFilterLabelsUsed bool
 	var groups []Group
 	for _, file := range fp {
 		uniqueGroups := map[string]struct{}{}
@@ -197,6 +214,9 @@ func Parse(pathPatterns []string, validateAnnotations, validateExpressions bool)
 			}
 			uniqueGroups[g.Name] = struct{}{}
 			g.File = file
+			if len(g.ExtraFilterLabels) > 0 {
+				isExtraFilterLabelsUsed = true
+			}
 			groups = append(groups, g)
 		}
 	}
@@ -206,6 +226,9 @@ func Parse(pathPatterns []string, validateAnnotations, validateExpressions bool)
 	if len(groups) < 1 {
 		logger.Warnf("no groups found in %s", strings.Join(pathPatterns, ";"))
 	}
+	if isExtraFilterLabelsUsed {
+		logger.Warnf("field `extra_filter_labels` is deprecated - use `params` instead")
+	}
 	return groups, nil
 }
 
diff --git a/app/vmalert/datasource/datasource.go b/app/vmalert/datasource/datasource.go
index 8dcff5e5d..e74f37314 100644
--- a/app/vmalert/datasource/datasource.go
+++ b/app/vmalert/datasource/datasource.go
@@ -2,6 +2,7 @@ package datasource
 
 import (
 	"context"
+	"net/url"
 	"time"
 )
 
@@ -20,8 +21,7 @@ type QuerierBuilder interface {
 type QuerierParams struct {
 	DataSourceType     *Type
 	EvaluationInterval time.Duration
-	// see https://docs.victoriametrics.com/#prometheus-querying-api-enhancements
-	ExtraLabels map[string]string
+	QueryParams        url.Values
 }
 
 // Metric is the basic entity which should be return by datasource
diff --git a/app/vmalert/datasource/init.go b/app/vmalert/datasource/init.go
index 72cfddfc9..7efd40693 100644
--- a/app/vmalert/datasource/init.go
+++ b/app/vmalert/datasource/init.go
@@ -4,6 +4,7 @@ import (
 	"flag"
 	"fmt"
 	"net/http"
+	"net/url"
 	"strings"
 
 	"github.com/VictoriaMetrics/VictoriaMetrics/app/vmalert/utils"
@@ -40,9 +41,9 @@ type Param struct {
 }
 
 // Init creates a Querier from provided flag values.
-// Provided extraParams will be added as GET params to
+// Provided extraParams will be added as GET params for
 // each request.
-func Init(extraParams []Param) (QuerierBuilder, error) {
+func Init(extraParams url.Values) (QuerierBuilder, error) {
 	if *addr == "" {
 		return nil, fmt.Errorf("datasource.url is empty")
 	}
@@ -56,11 +57,11 @@ func Init(extraParams []Param) (QuerierBuilder, error) {
 		tr.MaxIdleConns = tr.MaxIdleConnsPerHost
 	}
 
+	if extraParams == nil {
+		extraParams = url.Values{}
+	}
 	if *roundDigits > 0 {
-		extraParams = append(extraParams, Param{
-			Key:   "round_digits",
-			Value: fmt.Sprintf("%d", *roundDigits),
-		})
+		extraParams.Set("round_digits", fmt.Sprintf("%d", *roundDigits))
 	}
 
 	authCfg, err := utils.AuthConfig(*basicAuthUsername, *basicAuthPassword, *basicAuthPasswordFile, *bearerToken, *bearerTokenFile)
diff --git a/app/vmalert/datasource/vm.go b/app/vmalert/datasource/vm.go
index c900ed2f6..c30eed93a 100644
--- a/app/vmalert/datasource/vm.go
+++ b/app/vmalert/datasource/vm.go
@@ -5,6 +5,7 @@ import (
 	"fmt"
 	"io/ioutil"
 	"net/http"
+	"net/url"
 	"strings"
 	"time"
 
@@ -22,8 +23,7 @@ type VMStorage struct {
 
 	dataSourceType     Type
 	evaluationInterval time.Duration
-	extraLabels        []string
-	extraParams        []Param
+	extraParams        url.Values
 	disablePathAppend  bool
 }
 
@@ -47,9 +47,7 @@ func (s *VMStorage) ApplyParams(params QuerierParams) *VMStorage {
 		s.dataSourceType = *params.DataSourceType
 	}
 	s.evaluationInterval = params.EvaluationInterval
-	for k, v := range params.ExtraLabels {
-		s.extraLabels = append(s.extraLabels, fmt.Sprintf("%s=%s", k, v))
-	}
+	s.extraParams = params.QueryParams
 	return s
 }
 
diff --git a/app/vmalert/datasource/vm_graphite_api.go b/app/vmalert/datasource/vm_graphite_api.go
index 36b89e187..e4576f7a4 100644
--- a/app/vmalert/datasource/vm_graphite_api.go
+++ b/app/vmalert/datasource/vm_graphite_api.go
@@ -54,6 +54,14 @@ func (s *VMStorage) setGraphiteReqParams(r *http.Request, query string, timestam
 	}
 	r.URL.Path += graphitePath
 	q := r.URL.Query()
+	for k, vs := range s.extraParams {
+		if q.Has(k) { // extraParams are prior to params in URL
+			q.Del(k)
+		}
+		for _, v := range vs {
+			q.Add(k, v)
+		}
+	}
 	q.Set("format", "json")
 	q.Set("target", query)
 	from := "-5min"
diff --git a/app/vmalert/datasource/vm_prom_api.go b/app/vmalert/datasource/vm_prom_api.go
index 2faba4d27..47a34e9e6 100644
--- a/app/vmalert/datasource/vm_prom_api.go
+++ b/app/vmalert/datasource/vm_prom_api.go
@@ -150,6 +150,14 @@ func (s *VMStorage) setPrometheusRangeReqParams(r *http.Request, query string, s
 
 func (s *VMStorage) setPrometheusReqParams(r *http.Request, query string) {
 	q := r.URL.Query()
+	for k, vs := range s.extraParams {
+		if q.Has(k) { // extraParams are prior to params in URL
+			q.Del(k)
+		}
+		for _, v := range vs {
+			q.Add(k, v)
+		}
+	}
 	q.Set("query", query)
 	if s.evaluationInterval > 0 {
 		// set step as evaluationInterval by default
@@ -159,11 +167,5 @@ func (s *VMStorage) setPrometheusReqParams(r *http.Request, query string) {
 		// override step with user-specified value
 		q.Set("step", s.queryStep.String())
 	}
-	for _, l := range s.extraLabels {
-		q.Add("extra_label", l)
-	}
-	for _, p := range s.extraParams {
-		q.Add(p.Key, p.Value)
-	}
 	r.URL.RawQuery = q.Encode()
 }
diff --git a/app/vmalert/group.go b/app/vmalert/group.go
index d77598eae..45a10f075 100644
--- a/app/vmalert/group.go
+++ b/app/vmalert/group.go
@@ -4,6 +4,7 @@ import (
 	"context"
 	"fmt"
 	"hash/fnv"
+	"net/url"
 	"sync"
 	"time"
 
@@ -27,8 +28,8 @@ type Group struct {
 	Concurrency int
 	Checksum    string
 
-	ExtraFilterLabels map[string]string
-	Labels            map[string]string
+	Labels map[string]string
+	Params url.Values
 
 	doneCh     chan struct{}
 	finishedCh chan struct{}
@@ -71,14 +72,14 @@ func mergeLabels(groupName, ruleName string, set1, set2 map[string]string) map[s
 
 func newGroup(cfg config.Group, qb datasource.QuerierBuilder, defaultInterval time.Duration, labels map[string]string) *Group {
 	g := &Group{
-		Type:              cfg.Type,
-		Name:              cfg.Name,
-		File:              cfg.File,
-		Interval:          cfg.Interval.Duration(),
-		Concurrency:       cfg.Concurrency,
-		Checksum:          cfg.Checksum,
-		ExtraFilterLabels: cfg.ExtraFilterLabels,
-		Labels:            cfg.Labels,
+		Type:        cfg.Type,
+		Name:        cfg.Name,
+		File:        cfg.File,
+		Interval:    cfg.Interval.Duration(),
+		Concurrency: cfg.Concurrency,
+		Checksum:    cfg.Checksum,
+		Params:      cfg.Params,
+		Labels:      cfg.Labels,
 
 		doneCh:     make(chan struct{}),
 		finishedCh: make(chan struct{}),
@@ -198,7 +199,7 @@ func (g *Group) updateWith(newGroup *Group) error {
 	// group.Start function
 	g.Type = newGroup.Type
 	g.Concurrency = newGroup.Concurrency
-	g.ExtraFilterLabels = newGroup.ExtraFilterLabels
+	g.Params = newGroup.Params
 	g.Labels = newGroup.Labels
 	g.Checksum = newGroup.Checksum
 	g.Rules = newRules
diff --git a/app/vmalert/main.go b/app/vmalert/main.go
index e0ed4ce2d..540ff27ff 100644
--- a/app/vmalert/main.go
+++ b/app/vmalert/main.go
@@ -104,8 +104,7 @@ func main() {
 		}
 		// prevent queries from caching and boundaries aligning
 		// when querying VictoriaMetrics datasource.
-		noCache := datasource.Param{Key: "nocache", Value: "1"}
-		q, err := datasource.Init([]datasource.Param{noCache})
+		q, err := datasource.Init(url.Values{"nocache": {"1"}})
 		if err != nil {
 			logger.Fatalf("failed to init datasource: %s", err)
 		}
diff --git a/app/vmalert/manager.go b/app/vmalert/manager.go
index dff4a5550..9c2823cb7 100644
--- a/app/vmalert/manager.go
+++ b/app/vmalert/manager.go
@@ -3,6 +3,8 @@ package main
 import (
 	"context"
 	"fmt"
+	"net/url"
+	"sort"
 	"sync"
 
 	"github.com/VictoriaMetrics/VictoriaMetrics/app/vmalert/config"
@@ -161,13 +163,13 @@ func (g *Group) toAPI() APIGroup {
 		// encode as string to avoid rounding
 		ID: fmt.Sprintf("%d", g.ID()),
 
-		Name:              g.Name,
-		Type:              g.Type.String(),
-		File:              g.File,
-		Interval:          g.Interval.String(),
-		Concurrency:       g.Concurrency,
-		ExtraFilterLabels: g.ExtraFilterLabels,
-		Labels:            g.Labels,
+		Name:        g.Name,
+		Type:        g.Type.String(),
+		File:        g.File,
+		Interval:    g.Interval.String(),
+		Concurrency: g.Concurrency,
+		Params:      urlValuesToStrings(g.Params),
+		Labels:      g.Labels,
 	}
 	for _, r := range g.Rules {
 		switch v := r.(type) {
@@ -179,3 +181,24 @@ func (g *Group) toAPI() APIGroup {
 	}
 	return ag
 }
+
+func urlValuesToStrings(values url.Values) []string {
+	if len(values) < 1 {
+		return nil
+	}
+
+	keys := make([]string, 0, len(values))
+	for k := range values {
+		keys = append(keys, k)
+	}
+	sort.Strings(keys)
+
+	var res []string
+	for _, k := range keys {
+		params := values[k]
+		for _, v := range params {
+			res = append(res, fmt.Sprintf("%s=%s", k, v))
+		}
+	}
+	return res
+}
diff --git a/app/vmalert/recording.go b/app/vmalert/recording.go
index 32924d075..94f7f241f 100644
--- a/app/vmalert/recording.go
+++ b/app/vmalert/recording.go
@@ -70,7 +70,7 @@ func newRecordingRule(qb datasource.QuerierBuilder, group *Group, cfg config.Rul
 		q: qb.BuildWithParams(datasource.QuerierParams{
 			DataSourceType:     &group.Type,
 			EvaluationInterval: group.Interval,
-			ExtraLabels:        group.ExtraFilterLabels,
+			QueryParams:        group.Params,
 		}),
 	}
 
diff --git a/app/vmalert/web.qtpl b/app/vmalert/web.qtpl
index c15fa9de8..98e33c05f 100644
--- a/app/vmalert/web.qtpl
+++ b/app/vmalert/web.qtpl
@@ -54,10 +54,10 @@
                  {% if rNotOk[g.Name] > 0 %}<span class="badge bg-danger" title="Number of rules with status Error">{%d rNotOk[g.Name] %}</span> {% endif %}
                 <span class="badge bg-success" title="Number of rules withs status Ok">{%d rOk[g.Name] %}</span>
                 <p class="fs-6 fw-lighter">{%s g.File %}</p>
-                {% if len(g.ExtraFilterLabels) > 0 %}
-                    <div class="fs-6 fw-lighter">Extra filter labels
-                    {% for k, v := range g.ExtraFilterLabels %}
-                            <span class="float-left badge bg-primary">{%s k %}={%s v %}</span>
+                {% if len(g.Params) > 0 %}
+                    <div class="fs-6 fw-lighter">Extra params
+                    {% for _, param := range g.Params %}
+                            <span class="float-left badge bg-primary">{%s param %}</span>
                     {% endfor %}
                     </div>
                 {% endif %}
diff --git a/app/vmalert/web.qtpl.go b/app/vmalert/web.qtpl.go
index b642add0a..27c829378 100644
--- a/app/vmalert/web.qtpl.go
+++ b/app/vmalert/web.qtpl.go
@@ -211,22 +211,18 @@ func StreamListGroups(qw422016 *qt422016.Writer, groups []APIGroup) {
 			qw422016.N().S(`</p>
                 `)
 //line app/vmalert/web.qtpl:57
-			if len(g.ExtraFilterLabels) > 0 {
+			if len(g.Params) > 0 {
 //line app/vmalert/web.qtpl:57
 				qw422016.N().S(`
-                    <div class="fs-6 fw-lighter">Extra filter labels
+                    <div class="fs-6 fw-lighter">Extra params
                     `)
 //line app/vmalert/web.qtpl:59
-				for k, v := range g.ExtraFilterLabels {
+				for _, param := range g.Params {
 //line app/vmalert/web.qtpl:59
 					qw422016.N().S(`
                             <span class="float-left badge bg-primary">`)
 //line app/vmalert/web.qtpl:60
-					qw422016.E().S(k)
-//line app/vmalert/web.qtpl:60
-					qw422016.N().S(`=`)
-//line app/vmalert/web.qtpl:60
-					qw422016.E().S(v)
+					qw422016.E().S(param)
 //line app/vmalert/web.qtpl:60
 					qw422016.N().S(`</span>
                     `)
diff --git a/app/vmalert/web_types.go b/app/vmalert/web_types.go
index cb13fb23f..c49c81b65 100644
--- a/app/vmalert/web_types.go
+++ b/app/vmalert/web_types.go
@@ -23,16 +23,16 @@ type APIAlert struct {
 
 // APIGroup represents Group for WEB view
 type APIGroup struct {
-	Name              string             `json:"name"`
-	Type              string             `json:"type"`
-	ID                string             `json:"id"`
-	File              string             `json:"file"`
-	Interval          string             `json:"interval"`
-	Concurrency       int                `json:"concurrency"`
-	ExtraFilterLabels map[string]string  `json:"extra_filter_labels"`
-	Labels            map[string]string  `json:"labels,omitempty"`
-	AlertingRules     []APIAlertingRule  `json:"alerting_rules"`
-	RecordingRules    []APIRecordingRule `json:"recording_rules"`
+	Name           string             `json:"name"`
+	Type           string             `json:"type"`
+	ID             string             `json:"id"`
+	File           string             `json:"file"`
+	Interval       string             `json:"interval"`
+	Concurrency    int                `json:"concurrency"`
+	Params         []string           `json:"params"`
+	Labels         map[string]string  `json:"labels,omitempty"`
+	AlertingRules  []APIAlertingRule  `json:"alerting_rules"`
+	RecordingRules []APIRecordingRule `json:"recording_rules"`
 }
 
 // APIAlertingRule represents AlertingRule for WEB view
diff --git a/app/vmbackup/README.md b/app/vmbackup/README.md
index e9827f14e..d725278e1 100644
--- a/app/vmbackup/README.md
+++ b/app/vmbackup/README.md
@@ -185,12 +185,32 @@ See [this article](https://medium.com/@valyala/speeding-up-backups-for-big-time-
   -dst string
     	Where to put the backup on the remote storage. Example: gs://bucket/path/to/backup/dir, s3://bucket/path/to/backup/dir or fs:///path/to/local/backup/dir
     	-dst can point to the previous backup. In this case incremental backup is performed, i.e. only changed data is uploaded
+  -enableTCP6
+    	Whether to enable IPv6 for listening and dialing. By default only IPv4 TCP and UDP is used
   -envflag.enable
     	Whether to enable reading flags from environment variables additionally to command line. Command line flag values have priority over values from environment vars. Flags are read only from command line if this flag isn't set. See https://docs.victoriametrics.com/#environment-variables for more details
   -envflag.prefix string
     	Prefix for environment variables if -envflag.enable is set
   -fs.disableMmap
     	Whether to use pread() instead of mmap() for reading data files. By default mmap() is used for 64-bit arches and pread() is used for 32-bit arches, since they cannot read data files bigger than 2^32 bytes in memory. mmap() is usually faster for reading small data chunks than pread()
+  -http.connTimeout duration
+    	Incoming http connections are closed after the configured timeout. This may help to spread the incoming load among a cluster of services behind a load balancer. Please note that the real timeout may be bigger by up to 10% as a protection against the thundering herd problem (default 2m0s)
+  -http.disableResponseCompression
+    	Disable compression of HTTP responses to save CPU resources. By default compression is enabled to save network bandwidth
+  -http.idleConnTimeout duration
+    	Timeout for incoming idle http connections (default 1m0s)
+  -http.maxGracefulShutdownDuration duration
+    	The maximum duration for a graceful shutdown of the HTTP server. A highly loaded server may require increased value for a graceful shutdown (default 7s)
+  -http.pathPrefix string
+    	An optional prefix to add to all the paths handled by http server. For example, if '-http.pathPrefix=/foo/bar' is set, then all the http requests will be handled on '/foo/bar/*' paths. This may be useful for proxied requests. See https://www.robustperception.io/using-external-urls-and-proxies-with-prometheus
+  -http.shutdownDelay duration
+    	Optional delay before http server shutdown. During this delay, the server returns non-OK responses from /health page, so load balancers can route new requests to other servers
+  -httpAuth.password string
+    	Password for HTTP Basic Auth. The authentication is disabled if -httpAuth.username is empty
+  -httpAuth.username string
+    	Username for HTTP Basic Auth. The authentication is disabled if empty. See also -httpAuth.password
+  -httpListenAddr string
+    	TCP address for exporting metrics at /metrics page (default ":8420")
   -loggerDisableTimestamps
     	Whether to disable writing timestamps in logs
   -loggerErrorsPerSecondLimit int
@@ -213,8 +233,12 @@ See [this article](https://medium.com/@valyala/speeding-up-backups-for-big-time-
     	Supports the following optional suffixes for size values: KB, MB, GB, KiB, MiB, GiB (default 0)
   -memory.allowedPercent float
     	Allowed percent of system memory VictoriaMetrics caches may occupy. See also -memory.allowedBytes. Too low a value may increase cache miss rate usually resulting in higher CPU and disk IO usage. Too high a value may evict too much data from OS page cache which will result in higher disk IO usage (default 60)
+  -metricsAuthKey string
+    	Auth key for /metrics. It must be passed via authKey query arg. It overrides httpAuth.* settings
   -origin string
     	Optional origin directory on the remote storage with old backup for server-side copying when performing full backup. This speeds up full backups
+  -pprofAuthKey string
+    	Auth key for /debug/pprof. It must be passed via authKey query arg. It overrides httpAuth.* settings
   -s3ForcePathStyle
     	Prefixing endpoint with bucket name when set false, true by default. (default true)
   -snapshot.createURL string
@@ -225,6 +249,12 @@ See [this article](https://medium.com/@valyala/speeding-up-backups-for-big-time-
     	Name for the snapshot to backup. See https://docs.victoriametrics.com/Single-server-VictoriaMetrics.html#how-to-work-with-snapshots. There is no need in setting -snapshotName if -snapshot.createURL is set
   -storageDataPath string
     	Path to VictoriaMetrics data. Must match -storageDataPath from VictoriaMetrics or vmstorage (default "victoria-metrics-data")
+  -tls
+    	Whether to enable TLS (aka HTTPS) for incoming requests. -tlsCertFile and -tlsKeyFile must be set if -tls is set
+  -tlsCertFile string
+    	Path to file with TLS certificate. Used only if -tls is set. Prefer ECDSA certs instead of RSA certs as RSA certs are slower
+  -tlsKeyFile string
+    	Path to file with TLS key. Used only if -tls is set
   -version
     	Show VictoriaMetrics version
 ```
diff --git a/app/vmbackup/main.go b/app/vmbackup/main.go
index c90aeb0a8..6c58f26f2 100644
--- a/app/vmbackup/main.go
+++ b/app/vmbackup/main.go
@@ -5,6 +5,7 @@ import (
 	"fmt"
 	"os"
 	"strings"
+	"time"
 
 	"github.com/VictoriaMetrics/VictoriaMetrics/app/vmbackup/snapshot"
 	"github.com/VictoriaMetrics/VictoriaMetrics/lib/backup/actions"
@@ -14,10 +15,12 @@ import (
 	"github.com/VictoriaMetrics/VictoriaMetrics/lib/buildinfo"
 	"github.com/VictoriaMetrics/VictoriaMetrics/lib/envflag"
 	"github.com/VictoriaMetrics/VictoriaMetrics/lib/flagutil"
+	"github.com/VictoriaMetrics/VictoriaMetrics/lib/httpserver"
 	"github.com/VictoriaMetrics/VictoriaMetrics/lib/logger"
 )
 
 var (
+	httpListenAddr    = flag.String("httpListenAddr", ":8420", "TCP address for exporting metrics at /metrics page")
 	storageDataPath   = flag.String("storageDataPath", "victoria-metrics-data", "Path to VictoriaMetrics data. Must match -storageDataPath from VictoriaMetrics or vmstorage")
 	snapshotName      = flag.String("snapshotName", "", "Name for the snapshot to backup. See https://docs.victoriametrics.com/Single-server-VictoriaMetrics.html#how-to-work-with-snapshots. There is no need in setting -snapshotName if -snapshot.createURL is set")
 	snapshotCreateURL = flag.String("snapshot.createURL", "", "VictoriaMetrics create snapshot url. When this is given a snapshot will automatically be created during backup. "+
@@ -70,6 +73,9 @@ func main() {
 		}()
 	}
 
+	logger.Infof("starting http server for exporting metrics at http://%q/metrics", *httpListenAddr)
+	go httpserver.Serve(*httpListenAddr, nil)
+
 	srcFS, err := newSrcFS()
 	if err != nil {
 		logger.Fatalf("%s", err)
@@ -94,6 +100,13 @@ func main() {
 	srcFS.MustStop()
 	dstFS.MustStop()
 	originFS.MustStop()
+
+	startTime := time.Now()
+	logger.Infof("gracefully shutting down http server for metrics at %q", *httpListenAddr)
+	if err := httpserver.Stop(*httpListenAddr); err != nil {
+		logger.Fatalf("cannot stop http server for metrics: %s", err)
+	}
+	logger.Infof("successfully shut down http server for metrics in %.3f seconds", time.Since(startTime).Seconds())
 }
 
 func usage() {
diff --git a/app/vmrestore/README.md b/app/vmrestore/README.md
index 5a01129e0..7b3486cfd 100644
--- a/app/vmrestore/README.md
+++ b/app/vmrestore/README.md
@@ -85,12 +85,32 @@ i.e. the end result would be similar to [rsync --delete](https://askubuntu.com/q
     	See https://cloud.google.com/iam/docs/creating-managing-service-account-keys and https://docs.aws.amazon.com/general/latest/gr/aws-security-credentials.html
   -customS3Endpoint string
     	Custom S3 endpoint for use with S3-compatible storages (e.g. MinIO). S3 is used if not set
+  -enableTCP6
+    	Whether to enable IPv6 for listening and dialing. By default only IPv4 TCP and UDP is used
   -envflag.enable
     	Whether to enable reading flags from environment variables additionally to command line. Command line flag values have priority over values from environment vars. Flags are read only from command line if this flag isn't set. See https://docs.victoriametrics.com/#environment-variables for more details
   -envflag.prefix string
     	Prefix for environment variables if -envflag.enable is set
   -fs.disableMmap
     	Whether to use pread() instead of mmap() for reading data files. By default mmap() is used for 64-bit arches and pread() is used for 32-bit arches, since they cannot read data files bigger than 2^32 bytes in memory. mmap() is usually faster for reading small data chunks than pread()
+  -http.connTimeout duration
+    	Incoming http connections are closed after the configured timeout. This may help to spread the incoming load among a cluster of services behind a load balancer. Please note that the real timeout may be bigger by up to 10% as a protection against the thundering herd problem (default 2m0s)
+  -http.disableResponseCompression
+    	Disable compression of HTTP responses to save CPU resources. By default compression is enabled to save network bandwidth
+  -http.idleConnTimeout duration
+    	Timeout for incoming idle http connections (default 1m0s)
+  -http.maxGracefulShutdownDuration duration
+    	The maximum duration for a graceful shutdown of the HTTP server. A highly loaded server may require increased value for a graceful shutdown (default 7s)
+  -http.pathPrefix string
+    	An optional prefix to add to all the paths handled by http server. For example, if '-http.pathPrefix=/foo/bar' is set, then all the http requests will be handled on '/foo/bar/*' paths. This may be useful for proxied requests. See https://www.robustperception.io/using-external-urls-and-proxies-with-prometheus
+  -http.shutdownDelay duration
+    	Optional delay before http server shutdown. During this delay, the server returns non-OK responses from /health page, so load balancers can route new requests to other servers
+  -httpAuth.password string
+    	Password for HTTP Basic Auth. The authentication is disabled if -httpAuth.username is empty
+  -httpAuth.username string
+    	Username for HTTP Basic Auth. The authentication is disabled if empty. See also -httpAuth.password
+  -httpListenAddr string
+    	TCP address for exporting metrics at /metrics page (default ":8421")
   -loggerDisableTimestamps
     	Whether to disable writing timestamps in logs
   -loggerErrorsPerSecondLimit int
@@ -113,6 +133,10 @@ i.e. the end result would be similar to [rsync --delete](https://askubuntu.com/q
     	Supports the following optional suffixes for size values: KB, MB, GB, KiB, MiB, GiB (default 0)
   -memory.allowedPercent float
     	Allowed percent of system memory VictoriaMetrics caches may occupy. See also -memory.allowedBytes. Too low a value may increase cache miss rate usually resulting in higher CPU and disk IO usage. Too high a value may evict too much data from OS page cache which will result in higher disk IO usage (default 60)
+  -metricsAuthKey string
+    	Auth key for /metrics. It must be passed via authKey query arg. It overrides httpAuth.* settings
+  -pprofAuthKey string
+    	Auth key for /debug/pprof. It must be passed via authKey query arg. It overrides httpAuth.* settings
   -s3ForcePathStyle
     	Prefixing endpoint with bucket name when set false, true by default. (default true)
   -skipBackupCompleteCheck
@@ -121,6 +145,12 @@ i.e. the end result would be similar to [rsync --delete](https://askubuntu.com/q
     	Source path with backup on the remote storage. Example: gs://bucket/path/to/backup/dir, s3://bucket/path/to/backup/dir or fs:///path/to/local/backup/dir
   -storageDataPath string
     	Destination path where backup must be restored. VictoriaMetrics must be stopped when restoring from backup. -storageDataPath dir can be non-empty. In this case the contents of -storageDataPath dir is synchronized with -src contents, i.e. it works like 'rsync --delete' (default "victoria-metrics-data")
+  -tls
+    	Whether to enable TLS (aka HTTPS) for incoming requests. -tlsCertFile and -tlsKeyFile must be set if -tls is set
+  -tlsCertFile string
+    	Path to file with TLS certificate. Used only if -tls is set. Prefer ECDSA certs instead of RSA certs as RSA certs are slower
+  -tlsKeyFile string
+    	Path to file with TLS key. Used only if -tls is set
   -version
     	Show VictoriaMetrics version
 ```
diff --git a/app/vmrestore/main.go b/app/vmrestore/main.go
index 9db012846..f1713d351 100644
--- a/app/vmrestore/main.go
+++ b/app/vmrestore/main.go
@@ -4,6 +4,7 @@ import (
 	"flag"
 	"fmt"
 	"os"
+	"time"
 
 	"github.com/VictoriaMetrics/VictoriaMetrics/lib/backup/actions"
 	"github.com/VictoriaMetrics/VictoriaMetrics/lib/backup/common"
@@ -11,11 +12,13 @@ import (
 	"github.com/VictoriaMetrics/VictoriaMetrics/lib/buildinfo"
 	"github.com/VictoriaMetrics/VictoriaMetrics/lib/envflag"
 	"github.com/VictoriaMetrics/VictoriaMetrics/lib/flagutil"
+	"github.com/VictoriaMetrics/VictoriaMetrics/lib/httpserver"
 	"github.com/VictoriaMetrics/VictoriaMetrics/lib/logger"
 )
 
 var (
-	src = flag.String("src", "", "Source path with backup on the remote storage. "+
+	httpListenAddr = flag.String("httpListenAddr", ":8421", "TCP address for exporting metrics at /metrics page")
+	src            = flag.String("src", "", "Source path with backup on the remote storage. "+
 		"Example: gs://bucket/path/to/backup/dir, s3://bucket/path/to/backup/dir or fs:///path/to/local/backup/dir")
 	storageDataPath = flag.String("storageDataPath", "victoria-metrics-data", "Destination path where backup must be restored. "+
 		"VictoriaMetrics must be stopped when restoring from backup. -storageDataPath dir can be non-empty. In this case the contents of -storageDataPath dir "+
@@ -33,6 +36,9 @@ func main() {
 	buildinfo.Init()
 	logger.Init()
 
+	logger.Infof("starting http server for exporting metrics at http://%q/metrics", *httpListenAddr)
+	go httpserver.Serve(*httpListenAddr, nil)
+
 	srcFS, err := newSrcFS()
 	if err != nil {
 		logger.Fatalf("%s", err)
@@ -52,6 +58,13 @@ func main() {
 	}
 	srcFS.MustStop()
 	dstFS.MustStop()
+
+	startTime := time.Now()
+	logger.Infof("gracefully shutting down http server for metrics at %q", *httpListenAddr)
+	if err := httpserver.Stop(*httpListenAddr); err != nil {
+		logger.Fatalf("cannot stop http server for metrics: %s", err)
+	}
+	logger.Infof("successfully shut down http server for metrics in %.3f seconds", time.Since(startTime).Seconds())
 }
 
 func usage() {
diff --git a/app/vmstorage/main.go b/app/vmstorage/main.go
index 98aca0127..9209ce7d4 100644
--- a/app/vmstorage/main.go
+++ b/app/vmstorage/main.go
@@ -713,6 +713,31 @@ func registerStorageMetrics() {
 		return float64(m().PrefetchedMetricIDsSizeBytes)
 	})
 
+	metrics.NewGauge(`vm_cache_size_max_bytes{type="storage/tsid"}`, func() float64 {
+		return float64(m().TSIDCacheSizeMaxBytes)
+	})
+	metrics.NewGauge(`vm_cache_size_max_bytes{type="storage/metricIDs"}`, func() float64 {
+		return float64(m().MetricIDCacheSizeMaxBytes)
+	})
+	metrics.NewGauge(`vm_cache_size_max_bytes{type="storage/metricName"}`, func() float64 {
+		return float64(m().MetricNameCacheSizeMaxBytes)
+	})
+	metrics.NewGauge(`vm_cache_size_max_bytes{type="storage/bigIndexBlocks"}`, func() float64 {
+		return float64(tm().BigIndexBlocksCacheSizeMaxBytes)
+	})
+	metrics.NewGauge(`vm_cache_size_max_bytes{type="storage/smallIndexBlocks"}`, func() float64 {
+		return float64(tm().SmallIndexBlocksCacheSizeMaxBytes)
+	})
+	metrics.NewGauge(`vm_cache_size_max_bytes{type="indexdb/dataBlocks"}`, func() float64 {
+		return float64(idbm().DataBlocksCacheSizeMaxBytes)
+	})
+	metrics.NewGauge(`vm_cache_size_max_bytes{type="indexdb/indexBlocks"}`, func() float64 {
+		return float64(idbm().IndexBlocksCacheSizeMaxBytes)
+	})
+	metrics.NewGauge(`vm_cache_size_max_bytes{type="indexdb/tagFilters"}`, func() float64 {
+		return float64(idbm().TagFiltersCacheSizeMaxBytes)
+	})
+
 	metrics.NewGauge(`vm_cache_requests_total{type="storage/tsid"}`, func() float64 {
 		return float64(m().TSIDCacheRequests)
 	})
diff --git a/deployment/docker/alerts.yml b/deployment/docker/alerts.yml
index 6c4b188df..5c5a7f9d4 100644
--- a/deployment/docker/alerts.yml
+++ b/deployment/docker/alerts.yml
@@ -192,7 +192,7 @@ groups:
         labels:
           severity: warning
         annotations:
-          dashboard: "http://localhost:3000/d/oS7Bi_0Wz?viewPanel=74&var-instance={{ $labels.instance }}"
+          dashboard: "http://localhost:3000/d/wNf0q_kZk?viewPanel=74&var-instance={{ $labels.instance }}"
           summary: "Metrics ingested in ({{ $labels.instance }}) are exceeding labels limit"
           description: "VictoriaMetrics limits the number of labels per each metric with `-maxLabelsPerTimeseries` command-line flag.\n
            This prevents from ingesting metrics with too many labels. Please verify that `-maxLabelsPerTimeseries` is configured
diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md
index d13f14413..d7eacd4d3 100644
--- a/docs/CHANGELOG.md
+++ b/docs/CHANGELOG.md
@@ -8,12 +8,17 @@ sort: 15
 
 * FEATURE: add `now()` function to MetricsQL. This function returns the current timestamp in seconds. See [these docs](https://docs.victoriametrics.com/MetricsQL.html#now).
 * FEATURE: vmauth: allow using optional `name` field in configs. This field is then used as `username` label value for `vmauth_user_requests_total` metric. See [this feature request](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/1805).
-* FEATURE: vmagent: export `vm_persistentqueue_read_duration_seconds_total` and `vm_persistentqueue_write_duration_seconds_total` metrics, which can be used for detecting persistent queue saturation with `rate(vm_persistentqueue_write_duration_seconds_total) > 0.9s` alerting rule.
+* FEATURE: vmagent: export `vm_persistentqueue_read_duration_seconds_total` and `vm_persistentqueue_write_duration_seconds_total` metrics, which can be used for detecting persistent queue saturation with `rate(vm_persistentqueue_write_duration_seconds_total) > 0.9` alerting rule.
+* FEATURE: export `vm_filestream_read_duration_seconds_total` and `vm_filestream_write_duration_seconds_total` metrics, which can be used for detecting persistent disk saturation with `rate(vm_filestream_read_duration_seconds_total) > 0.9` alerting rule.
+* FEATURE: export `vm_cache_size_max_bytes` metrics, which show capacity for various caches. These metrics can be used for determining caches reaches its capacity with `vm_cache_size_bytes / vm_cache_size_max_bytes > 0.9` query.
 * FEATURE: [vmbackup](https://docs.victoriametrics.com/vmbackup.html), [vmrestore](https://docs.victoriametrics.com/vmrestore.html): add `-s3ForcePathStyle` command-line flag, which can be used for making backups to [Aliyun OSS](https://www.aliyun.com/product/oss). See [this pull request](https://github.com/VictoriaMetrics/VictoriaMetrics/pull/1802).
 * FEATURE: [vmctl](https://docs.victoriametrics.com/vmctl.html): improve data migration from OpenTSDB. See [this pull request](https://github.com/VictoriaMetrics/VictoriaMetrics/pull/1809). Thanks to @johnseekins .
 * FEATURE: suppress `connection reset by peer` errors when remote client resets TCP connection to VictoriaMetrics / vmagent while ingesting the data via InfluxDB line protocol, Graphite protocol or OpenTSDB protocol. This error is expected, so there is no need in logging it.
 * FEATURE: [vmui](https://docs.victoriametrics.com/#vmui): store the display type in URL, so it isn't lost when copy-pasting the URL. See [this feature request](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/1804).
 * FEATURE: vmalert: make `-notifier.url` command-line flag optional. This flag can be omitted if `vmalert` is used solely for recording rules and doesn't evaluate alerting rules. See [this pull request](https://github.com/VictoriaMetrics/VictoriaMetrics/pull/1870).
+* FEATURE: [vmbackup](https://docs.victoriametrics.com/vmbackup.html), [vmrestore](https://docs.victoriametrics.com/vmrestore.html): export internal metrics at `http://vmbackup:8420/metrics` and `http://vmrestore:8421/metrics` for better visibility of the backup/restore process.
+* FEATURE: allow trailing whitespace after the timestamp when [parsing Graphite plaintext lines](https://docs.victoriametrics.com/#how-to-send-data-from-graphite-compatible-agents-such-as-statsd). See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/1865).
+* FEATURE: expose `/-/healthy` and `/-/ready` endpoints as Prometheus does. This is needed for improving integration with third-party solutions, which rely on these endpoints. See [tis issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/1833).
 
 * BUGFIX: vmagent: prevent from scraping duplicate targets if `-promscrape.dropOriginalLabels` command-line flag is set. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/1830). Thanks to @guidao for the fix.
 * BUGFIX: vmstorage [enterprise](https://victoriametrics.com/enterprise.html): added missing `vm_tenant_used_tenant_bytes` metric, which shows the approximate per-tenant disk usage. See [these docs](https://docs.victoriametrics.com/PerTenantStatistic.html) and [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/1605).
diff --git a/docs/FAQ.md b/docs/FAQ.md
index 227ae606f..30873e46e 100644
--- a/docs/FAQ.md
+++ b/docs/FAQ.md
@@ -205,7 +205,7 @@ if a query covers 1000 metrics with 10K values each, then the remote read API ha
 This is slow and expensive.
 Prometheus remote read API isn't intended for querying foreign data aka `global query view`. See [this issue](https://github.com/prometheus/prometheus/issues/4456) for details.
 
-So just query VictoriaMetrics directly via [Prometheus Querying API](https://docs.victoriametrics.com/#prometheus-querying-api-usage)
+So just query VictoriaMetrics directly via [vmui](https://docs.victoriametrics.com/#vmui), [Prometheus Querying API](https://docs.victoriametrics.com/#prometheus-querying-api-usage)
 or via [Prometheus datasource in Grafana](https://docs.victoriametrics.com/#grafana-setup).
 
 
diff --git a/docs/guides/README.md b/docs/guides/README.md
index 054e2e8fe..04134a20b 100644
--- a/docs/guides/README.md
+++ b/docs/guides/README.md
@@ -7,4 +7,5 @@ sort: 21
 1. [K8s monitoring via VM Single](k8s-monitoring-via-vm-single.html)
 2. [K8s monitoring via VM Cluster](k8s-monitoring-via-vm-cluster.html)
 3. [HA monitoring setup in K8s via VM Cluster](k8s-ha-monitoring-via-vm-cluster.html)
-4. [Getting started with VM Operator](getting-started-with-vm-operator.html)
\ No newline at end of file
+4. [Getting started with VM Operator](getting-started-with-vm-operator.html)
+5. [Multi Retention Setup within VictoriaMetrics Cluster](guide-vmcluster-multiple-retention-setup.html)
\ No newline at end of file
diff --git a/docs/vmalert.md b/docs/vmalert.md
index c6e04463c..bfb5d2bed 100644
--- a/docs/vmalert.md
+++ b/docs/vmalert.md
@@ -260,7 +260,8 @@ you have recording rules or want to store [alerts state](#alerts-state-on-restar
 
 #### Single-node VictoriaMetrics
 
-<img alt="vmalert single" src="vmalert_single.png">
+The simplest configuration where one single-node VM server is used for
+rules execution, storing recording rules results and alerts state.
 
 `vmalert` configuration flags:
 ```
@@ -271,12 +272,16 @@ you have recording rules or want to store [alerts state](#alerts-state-on-restar
     -notifier.url=http://alertmanager:9093          # AlertManager addr to send alerts when they trigger
 ```
 
-The simplest configuration where one single-node VM server is used for
-rules execution, storing recording rules results and alerts state.
+<img alt="vmalert single" width="500" src="vmalert_single.png">
+
 
 #### Cluster VictoriaMetrics
 
-<img alt="vmalert cluster" src="vmalert_cluster.png">
+In [cluster mode](https://docs.victoriametrics.com/Cluster-VictoriaMetrics.html)
+VictoriaMetrics has separate components for writing and reading path:
+`vminsert` and `vmselect` components respectively. `vmselect` is used for executing rules expressions
+and `vminsert` is used to persist recording rules results and alerts state.
+Cluster mode could have multiple `vminsert` and `vmselect` components. 
 
 `vmalert` configuration flags:
 ```
@@ -287,18 +292,18 @@ rules execution, storing recording rules results and alerts state.
     -notifier.url=http://alertmanager:9093                      # AlertManager addr to send alerts when they trigger
 ```
 
-In [cluster mode](https://docs.victoriametrics.com/Cluster-VictoriaMetrics.html)
-VictoriaMetrics has separate components for writing and reading path:
-`vminsert` and `vmselect` components respectively. `vmselect` is used for executing rules expressions
-and `vminsert` is used to persist recording rules results and alerts state.
-Cluster mode could have multiple `vminsert` and `vmselect` components. In case when you want
-to spread the load on these components - add balancers before them and configure 
+<img alt="vmalert cluster" src="vmalert_cluster.png">
+
+In case when you want to spread the load on these components - add balancers before them and configure
 `vmalert` with balancer's addresses. Please, see more about VM's cluster architecture
 [here](https://docs.victoriametrics.com/Cluster-VictoriaMetrics.html#architecture-overview).
 
-#### vmalert high availability
+#### HA vmalert
 
-<img alt="vmalert ha" src="vmalert_ha.png">
+For HA user can run multiple identically configured `vmalert` instances.
+It means all of them will execute the same rules, write state and results to
+the same destinations, and send alert notifications to multiple configured
+Alertmanagers.
 
 `vmalert` configuration flags:
 ```
@@ -310,10 +315,7 @@ to spread the load on these components - add balancers before them and configure
     -notifier.url=http://alertmanagerN:9093         # The same alert will be sent to all configured notifiers
 ```
 
-For HA user can run multiple identically configured `vmalert` instances.
-It means all of them will execute the same rules, write state and results to
-the same destinations, and send alert notifications to multiple configured
-Alertmanagers.
+<img alt="vmalert ha" width="800px" src="vmalert_ha.png">
 
 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).
@@ -327,9 +329,15 @@ for Alertmanagers for better reliability.
 This example uses single-node VM server for the sake of simplicity. 
 Check how to replace it with [cluster VictoriaMetrics](#cluster-victoriametrics) if needed. 
 
+
 #### Downsampling and aggregation via vmalert
 
-<img alt="vmalert multi cluster" src="vmalert_multicluster.png">
+Example shows how to build a topology where `vmalert` will process data from one cluster
+and write results into another. Such clusters may be called as "hot" (low retention,
+high-speed disks, used for operative monitoring) and "cold" (long term retention,
+slower/cheaper disks, low resolution data). With help of `vmalert`, user can setup
+recording rules to process raw data from "hot" cluster (by applying additional transformations
+or reducing resolution) and push results to "cold" cluster.
 
 `vmalert` configuration flags:
 ```
@@ -338,17 +346,13 @@ Check how to replace it with [cluster VictoriaMetrics](#cluster-victoriametrics)
     -remoteWrite.url=http://aggregated-cluster-vminsert:8480/insert/0/prometheuss   # vminsert addr to persist recording rules results
 ```
 
-Example shows how to build a topology where `vmalert` will process data from one cluster
-and write results into another. Such clusters may be called as "hot" (low retention, 
-high-speed disks, used for operative monitoring) and "cold" (long term retention, 
-slower/cheaper disks, low resolution data). With help of `vmalert`, user can setup 
-recording rules to process raw data from "hot" cluster (by applying additional transformations 
-or reducing resolution) and push results to "cold" cluster. 
+<img alt="vmalert multi cluster" src="vmalert_multicluster.png">
 
 Please note, [replay](#rules-backfilling) feature may be used for transforming historical data.
 
 Flags `-remoteRead.url` and `-notifier.url` are omitted since we assume only recording rules are used.
 
+
 ### Web
 
 `vmalert` runs a web-server (`-httpListenAddr`) for serving metrics and alerts endpoints:
diff --git a/docs/vmbackup.md b/docs/vmbackup.md
index de6fa03b8..c3a8c5186 100644
--- a/docs/vmbackup.md
+++ b/docs/vmbackup.md
@@ -189,12 +189,32 @@ See [this article](https://medium.com/@valyala/speeding-up-backups-for-big-time-
   -dst string
     	Where to put the backup on the remote storage. Example: gs://bucket/path/to/backup/dir, s3://bucket/path/to/backup/dir or fs:///path/to/local/backup/dir
     	-dst can point to the previous backup. In this case incremental backup is performed, i.e. only changed data is uploaded
+  -enableTCP6
+    	Whether to enable IPv6 for listening and dialing. By default only IPv4 TCP and UDP is used
   -envflag.enable
     	Whether to enable reading flags from environment variables additionally to command line. Command line flag values have priority over values from environment vars. Flags are read only from command line if this flag isn't set. See https://docs.victoriametrics.com/#environment-variables for more details
   -envflag.prefix string
     	Prefix for environment variables if -envflag.enable is set
   -fs.disableMmap
     	Whether to use pread() instead of mmap() for reading data files. By default mmap() is used for 64-bit arches and pread() is used for 32-bit arches, since they cannot read data files bigger than 2^32 bytes in memory. mmap() is usually faster for reading small data chunks than pread()
+  -http.connTimeout duration
+    	Incoming http connections are closed after the configured timeout. This may help to spread the incoming load among a cluster of services behind a load balancer. Please note that the real timeout may be bigger by up to 10% as a protection against the thundering herd problem (default 2m0s)
+  -http.disableResponseCompression
+    	Disable compression of HTTP responses to save CPU resources. By default compression is enabled to save network bandwidth
+  -http.idleConnTimeout duration
+    	Timeout for incoming idle http connections (default 1m0s)
+  -http.maxGracefulShutdownDuration duration
+    	The maximum duration for a graceful shutdown of the HTTP server. A highly loaded server may require increased value for a graceful shutdown (default 7s)
+  -http.pathPrefix string
+    	An optional prefix to add to all the paths handled by http server. For example, if '-http.pathPrefix=/foo/bar' is set, then all the http requests will be handled on '/foo/bar/*' paths. This may be useful for proxied requests. See https://www.robustperception.io/using-external-urls-and-proxies-with-prometheus
+  -http.shutdownDelay duration
+    	Optional delay before http server shutdown. During this delay, the server returns non-OK responses from /health page, so load balancers can route new requests to other servers
+  -httpAuth.password string
+    	Password for HTTP Basic Auth. The authentication is disabled if -httpAuth.username is empty
+  -httpAuth.username string
+    	Username for HTTP Basic Auth. The authentication is disabled if empty. See also -httpAuth.password
+  -httpListenAddr string
+    	TCP address for exporting metrics at /metrics page (default ":8420")
   -loggerDisableTimestamps
     	Whether to disable writing timestamps in logs
   -loggerErrorsPerSecondLimit int
@@ -217,8 +237,12 @@ See [this article](https://medium.com/@valyala/speeding-up-backups-for-big-time-
     	Supports the following optional suffixes for size values: KB, MB, GB, KiB, MiB, GiB (default 0)
   -memory.allowedPercent float
     	Allowed percent of system memory VictoriaMetrics caches may occupy. See also -memory.allowedBytes. Too low a value may increase cache miss rate usually resulting in higher CPU and disk IO usage. Too high a value may evict too much data from OS page cache which will result in higher disk IO usage (default 60)
+  -metricsAuthKey string
+    	Auth key for /metrics. It must be passed via authKey query arg. It overrides httpAuth.* settings
   -origin string
     	Optional origin directory on the remote storage with old backup for server-side copying when performing full backup. This speeds up full backups
+  -pprofAuthKey string
+    	Auth key for /debug/pprof. It must be passed via authKey query arg. It overrides httpAuth.* settings
   -s3ForcePathStyle
     	Prefixing endpoint with bucket name when set false, true by default. (default true)
   -snapshot.createURL string
@@ -229,6 +253,12 @@ See [this article](https://medium.com/@valyala/speeding-up-backups-for-big-time-
     	Name for the snapshot to backup. See https://docs.victoriametrics.com/Single-server-VictoriaMetrics.html#how-to-work-with-snapshots. There is no need in setting -snapshotName if -snapshot.createURL is set
   -storageDataPath string
     	Path to VictoriaMetrics data. Must match -storageDataPath from VictoriaMetrics or vmstorage (default "victoria-metrics-data")
+  -tls
+    	Whether to enable TLS (aka HTTPS) for incoming requests. -tlsCertFile and -tlsKeyFile must be set if -tls is set
+  -tlsCertFile string
+    	Path to file with TLS certificate. Used only if -tls is set. Prefer ECDSA certs instead of RSA certs as RSA certs are slower
+  -tlsKeyFile string
+    	Path to file with TLS key. Used only if -tls is set
   -version
     	Show VictoriaMetrics version
 ```
diff --git a/docs/vmrestore.md b/docs/vmrestore.md
index a86d4662c..bd852996a 100644
--- a/docs/vmrestore.md
+++ b/docs/vmrestore.md
@@ -89,12 +89,32 @@ i.e. the end result would be similar to [rsync --delete](https://askubuntu.com/q
     	See https://cloud.google.com/iam/docs/creating-managing-service-account-keys and https://docs.aws.amazon.com/general/latest/gr/aws-security-credentials.html
   -customS3Endpoint string
     	Custom S3 endpoint for use with S3-compatible storages (e.g. MinIO). S3 is used if not set
+  -enableTCP6
+    	Whether to enable IPv6 for listening and dialing. By default only IPv4 TCP and UDP is used
   -envflag.enable
     	Whether to enable reading flags from environment variables additionally to command line. Command line flag values have priority over values from environment vars. Flags are read only from command line if this flag isn't set. See https://docs.victoriametrics.com/#environment-variables for more details
   -envflag.prefix string
     	Prefix for environment variables if -envflag.enable is set
   -fs.disableMmap
     	Whether to use pread() instead of mmap() for reading data files. By default mmap() is used for 64-bit arches and pread() is used for 32-bit arches, since they cannot read data files bigger than 2^32 bytes in memory. mmap() is usually faster for reading small data chunks than pread()
+  -http.connTimeout duration
+    	Incoming http connections are closed after the configured timeout. This may help to spread the incoming load among a cluster of services behind a load balancer. Please note that the real timeout may be bigger by up to 10% as a protection against the thundering herd problem (default 2m0s)
+  -http.disableResponseCompression
+    	Disable compression of HTTP responses to save CPU resources. By default compression is enabled to save network bandwidth
+  -http.idleConnTimeout duration
+    	Timeout for incoming idle http connections (default 1m0s)
+  -http.maxGracefulShutdownDuration duration
+    	The maximum duration for a graceful shutdown of the HTTP server. A highly loaded server may require increased value for a graceful shutdown (default 7s)
+  -http.pathPrefix string
+    	An optional prefix to add to all the paths handled by http server. For example, if '-http.pathPrefix=/foo/bar' is set, then all the http requests will be handled on '/foo/bar/*' paths. This may be useful for proxied requests. See https://www.robustperception.io/using-external-urls-and-proxies-with-prometheus
+  -http.shutdownDelay duration
+    	Optional delay before http server shutdown. During this delay, the server returns non-OK responses from /health page, so load balancers can route new requests to other servers
+  -httpAuth.password string
+    	Password for HTTP Basic Auth. The authentication is disabled if -httpAuth.username is empty
+  -httpAuth.username string
+    	Username for HTTP Basic Auth. The authentication is disabled if empty. See also -httpAuth.password
+  -httpListenAddr string
+    	TCP address for exporting metrics at /metrics page (default ":8421")
   -loggerDisableTimestamps
     	Whether to disable writing timestamps in logs
   -loggerErrorsPerSecondLimit int
@@ -117,6 +137,10 @@ i.e. the end result would be similar to [rsync --delete](https://askubuntu.com/q
     	Supports the following optional suffixes for size values: KB, MB, GB, KiB, MiB, GiB (default 0)
   -memory.allowedPercent float
     	Allowed percent of system memory VictoriaMetrics caches may occupy. See also -memory.allowedBytes. Too low a value may increase cache miss rate usually resulting in higher CPU and disk IO usage. Too high a value may evict too much data from OS page cache which will result in higher disk IO usage (default 60)
+  -metricsAuthKey string
+    	Auth key for /metrics. It must be passed via authKey query arg. It overrides httpAuth.* settings
+  -pprofAuthKey string
+    	Auth key for /debug/pprof. It must be passed via authKey query arg. It overrides httpAuth.* settings
   -s3ForcePathStyle
     	Prefixing endpoint with bucket name when set false, true by default. (default true)
   -skipBackupCompleteCheck
@@ -125,6 +149,12 @@ i.e. the end result would be similar to [rsync --delete](https://askubuntu.com/q
     	Source path with backup on the remote storage. Example: gs://bucket/path/to/backup/dir, s3://bucket/path/to/backup/dir or fs:///path/to/local/backup/dir
   -storageDataPath string
     	Destination path where backup must be restored. VictoriaMetrics must be stopped when restoring from backup. -storageDataPath dir can be non-empty. In this case the contents of -storageDataPath dir is synchronized with -src contents, i.e. it works like 'rsync --delete' (default "victoria-metrics-data")
+  -tls
+    	Whether to enable TLS (aka HTTPS) for incoming requests. -tlsCertFile and -tlsKeyFile must be set if -tls is set
+  -tlsCertFile string
+    	Path to file with TLS certificate. Used only if -tls is set. Prefer ECDSA certs instead of RSA certs as RSA certs are slower
+  -tlsKeyFile string
+    	Path to file with TLS key. Used only if -tls is set
   -version
     	Show VictoriaMetrics version
 ```
diff --git a/go.mod b/go.mod
index 467361748..b52764366 100644
--- a/go.mod
+++ b/go.mod
@@ -2,7 +2,7 @@ module github.com/VictoriaMetrics/VictoriaMetrics
 
 require (
 	cloud.google.com/go/storage v1.18.2
-	github.com/VictoriaMetrics/fastcache v1.7.0
+	github.com/VictoriaMetrics/fastcache v1.8.0
 
 	// Do not use the original github.com/valyala/fasthttp because of issues
 	// like https://github.com/valyala/fasthttp/commit/996610f021ff45fdc98c2ce7884d5fa4e7f9199b
@@ -10,10 +10,11 @@ require (
 	github.com/VictoriaMetrics/metrics v1.18.1
 	github.com/VictoriaMetrics/metricsql v0.31.0
 	github.com/VividCortex/ewma v1.2.0 // indirect
-	github.com/aws/aws-sdk-go v1.42.14
+	github.com/aws/aws-sdk-go v1.42.17
 	github.com/census-instrumentation/opencensus-proto v0.3.0 // indirect
 	github.com/cespare/xxhash/v2 v2.1.2
 	github.com/cheggaaa/pb/v3 v3.0.8
+	github.com/cncf/xds/go v0.0.0-20211130200136-a8f946100490 // indirect
 	github.com/cpuguy83/go-md2man/v2 v2.0.1 // indirect
 	github.com/envoyproxy/go-control-plane v0.10.1 // indirect
 	github.com/envoyproxy/protoc-gen-validate v0.6.2 // indirect
@@ -32,11 +33,11 @@ require (
 	github.com/valyala/fasttemplate v1.2.1
 	github.com/valyala/gozstd v1.14.2
 	github.com/valyala/quicktemplate v1.7.0
-	golang.org/x/net v0.0.0-20211123203042-d83791d6bcd9
+	golang.org/x/net v0.0.0-20211201190559-0a0e4e1bb54c
 	golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8
 	golang.org/x/sys v0.0.0-20211124211545-fe61309f8881
 	google.golang.org/api v0.60.0
-	google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1 // indirect
+	google.golang.org/genproto v0.0.0-20211129164237-f09f9a12af12 // indirect
 	google.golang.org/grpc v1.42.0 // indirect
 	gopkg.in/yaml.v2 v2.4.0
 )
diff --git a/go.sum b/go.sum
index 0e40e10b9..5d23e7b74 100644
--- a/go.sum
+++ b/go.sum
@@ -101,8 +101,8 @@ github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdko
 github.com/SAP/go-hdb v0.14.1/go.mod h1:7fdQLVC2lER3urZLjZCm0AuMQfApof92n3aylBPEkMo=
 github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
 github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
-github.com/VictoriaMetrics/fastcache v1.7.0 h1:E6GibaGI685TafrI7E/QqZPkMsOzRw+3gpICQx08ISg=
-github.com/VictoriaMetrics/fastcache v1.7.0/go.mod h1:n7Sl+ioh/HlWeYHLSIBIE8TcZFHg/+xgvomWSS5xuEE=
+github.com/VictoriaMetrics/fastcache v1.8.0 h1:ybZqS7kRy8YVzYsI09GLzQhs7iqS6cOEH2avtknD1SU=
+github.com/VictoriaMetrics/fastcache v1.8.0/go.mod h1:n7Sl+ioh/HlWeYHLSIBIE8TcZFHg/+xgvomWSS5xuEE=
 github.com/VictoriaMetrics/fasthttp v1.1.0 h1:3crd4YWHsMwu60GUXRH6OstowiFvqrwS4a/ueoLdLL0=
 github.com/VictoriaMetrics/fasthttp v1.1.0/go.mod h1:/7DMcogqd+aaD3G3Hg5kFgoFwlR2uydjiWvoLp5ZTqQ=
 github.com/VictoriaMetrics/metrics v1.12.2/go.mod h1:Z1tSfPfngDn12bTfZSCqArT3OPY3u88J12hSoOhuiRE=
@@ -154,8 +154,8 @@ github.com/aws/aws-sdk-go v1.30.12/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZve
 github.com/aws/aws-sdk-go v1.34.28/go.mod h1:H7NKnBqNVzoTJpGfLrQkkD+ytBA93eiDYi/+8rV9s48=
 github.com/aws/aws-sdk-go v1.35.31/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro=
 github.com/aws/aws-sdk-go v1.40.45/go.mod h1:585smgzpB/KqRA+K3y/NL/oYRqQvpNJYvLm+LY1U59Q=
-github.com/aws/aws-sdk-go v1.42.14 h1:Eqwjl/cwRY9z0TTU4RGpiElWo9oPzG+Y8r5Thu6Ug5A=
-github.com/aws/aws-sdk-go v1.42.14/go.mod h1:585smgzpB/KqRA+K3y/NL/oYRqQvpNJYvLm+LY1U59Q=
+github.com/aws/aws-sdk-go v1.42.17 h1:NEMRZcLd+YhXhUqdjwqNGtEYthiUZ+3BudGmK4/0yaA=
+github.com/aws/aws-sdk-go v1.42.17/go.mod h1:585smgzpB/KqRA+K3y/NL/oYRqQvpNJYvLm+LY1U59Q=
 github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g=
 github.com/aws/aws-sdk-go-v2 v1.9.1/go.mod h1:cK/D0BBs0b/oWPIcX/Z/obahJK1TT7IPVjy53i/mX/4=
 github.com/aws/aws-sdk-go-v2/service/cloudwatch v1.8.1/go.mod h1:CM+19rL1+4dFWnOQKwDc7H1KwXTz+h61oUSHyhV0b3o=
@@ -207,8 +207,9 @@ github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWH
 github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
 github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
 github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
-github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1 h1:zH8ljVhhq7yC0MIeUL/IviMtY8hx2mK8cN9wEYb8ggw=
 github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
+github.com/cncf/xds/go v0.0.0-20211130200136-a8f946100490 h1:KwaoQzs/WeUxxJqiJsZ4euOly1Az/IgZXXSxlD/UBNk=
+github.com/cncf/xds/go v0.0.0-20211130200136-a8f946100490/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
 github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8=
 github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI=
 github.com/containerd/containerd v1.3.4/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
@@ -1178,8 +1179,8 @@ golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qx
 golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
 golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
 golang.org/x/net v0.0.0-20210917221730-978cfadd31cf/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
-golang.org/x/net v0.0.0-20211123203042-d83791d6bcd9 h1:0qxwC5n+ttVOINCBeRHO0nq9X7uy8SDsPoi5OaCdIEI=
-golang.org/x/net v0.0.0-20211123203042-d83791d6bcd9/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
+golang.org/x/net v0.0.0-20211201190559-0a0e4e1bb54c h1:WtYZ93XtWSO5KlOMgPZu7hXY9WhMZpprvlm5VwvAl8c=
+golang.org/x/net v0.0.0-20211201190559-0a0e4e1bb54c/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
 golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
 golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
 golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@@ -1530,8 +1531,8 @@ google.golang.org/genproto v0.0.0-20210917145530-b395a37504d4/go.mod h1:eFjDcFEc
 google.golang.org/genproto v0.0.0-20210924002016-3dee208752a0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
 google.golang.org/genproto v0.0.0-20211016002631-37fc39342514/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
 google.golang.org/genproto v0.0.0-20211021150943-2b146023228c/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
-google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1 h1:b9mVrqYfq3P4bCdaLg1qtBnPzUYgglsIdjZkL/fQVOE=
-google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
+google.golang.org/genproto v0.0.0-20211129164237-f09f9a12af12 h1:DN5b3HU13J4sMd/QjDx34U6afpaexKTDdop+26pdjdk=
+google.golang.org/genproto v0.0.0-20211129164237-f09f9a12af12/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
 google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
 google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
 google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM=
diff --git a/lib/filestream/filestream.go b/lib/filestream/filestream.go
index 9fbe35872..8af10f5ce 100644
--- a/lib/filestream/filestream.go
+++ b/lib/filestream/filestream.go
@@ -6,6 +6,7 @@ import (
 	"io"
 	"os"
 	"sync"
+	"time"
 
 	"github.com/VictoriaMetrics/VictoriaMetrics/lib/logger"
 	"github.com/VictoriaMetrics/VictoriaMetrics/lib/memory"
@@ -108,6 +109,7 @@ func (r *Reader) MustClose() {
 }
 
 var (
+	readDuration      = metrics.NewFloatCounter(`vm_filestream_read_duration_seconds_total`)
 	readCallsBuffered = metrics.NewCounter(`vm_filestream_buffered_read_calls_total`)
 	readCallsReal     = metrics.NewCounter(`vm_filestream_real_read_calls_total`)
 	readBytesBuffered = metrics.NewCounter(`vm_filestream_buffered_read_bytes_total`)
@@ -117,6 +119,11 @@ var (
 
 // Read reads file contents to p.
 func (r *Reader) Read(p []byte) (int, error) {
+	startTime := time.Now()
+	defer func() {
+		d := time.Since(startTime).Seconds()
+		readDuration.Add(d)
+	}()
 	readCallsBuffered.Inc()
 	n, err := r.br.Read(p)
 	readBytesBuffered.Add(n)
@@ -232,6 +239,7 @@ func (w *Writer) MustClose() {
 }
 
 var (
+	writeDuration        = metrics.NewFloatCounter(`vm_filestream_write_duration_seconds_total`)
 	writeCallsBuffered   = metrics.NewCounter(`vm_filestream_buffered_write_calls_total`)
 	writeCallsReal       = metrics.NewCounter(`vm_filestream_real_write_calls_total`)
 	writtenBytesBuffered = metrics.NewCounter(`vm_filestream_buffered_written_bytes_total`)
@@ -241,6 +249,11 @@ var (
 
 // Write writes p to the underlying file.
 func (w *Writer) Write(p []byte) (int, error) {
+	startTime := time.Now()
+	defer func() {
+		d := time.Since(startTime).Seconds()
+		writeDuration.Add(d)
+	}()
 	writeCallsBuffered.Inc()
 	n, err := w.bw.Write(p)
 	writtenBytesBuffered.Add(n)
@@ -257,6 +270,11 @@ func (w *Writer) Write(p []byte) (int, error) {
 //
 // if isSync is true, then the flushed data is fsynced to the underlying storage.
 func (w *Writer) MustFlush(isSync bool) {
+	startTime := time.Now()
+	defer func() {
+		d := time.Since(startTime).Seconds()
+		writeDuration.Add(d)
+	}()
 	if err := w.bw.Flush(); err != nil {
 		logger.Panicf("FATAL: cannot flush buffered data to file %q: %s", w.f.Name(), err)
 	}
diff --git a/lib/httpserver/httpserver.go b/lib/httpserver/httpserver.go
index 0440a0dc5..4081d851b 100644
--- a/lib/httpserver/httpserver.go
+++ b/lib/httpserver/httpserver.go
@@ -13,7 +13,6 @@ import (
 	"net/http"
 	"net/http/pprof"
 	"os"
-	"path"
 	"runtime"
 	"strconv"
 	"strings"
@@ -68,7 +67,7 @@ type server struct {
 // In such cases the caller must serve the request.
 type RequestHandler func(w http.ResponseWriter, r *http.Request) bool
 
-// Serve starts an http server on the given addr with the given rh.
+// Serve starts an http server on the given addr with the given optional rh.
 //
 // By default all the responses are transparently compressed, since Google
 // charges a lot for the egress traffic. The compression may be disabled
@@ -76,6 +75,11 @@ type RequestHandler func(w http.ResponseWriter, r *http.Request) bool
 //
 // The compression is also disabled if -http.disableResponseCompression flag is set.
 func Serve(addr string, rh RequestHandler) {
+	if rh == nil {
+		rh = func(w http.ResponseWriter, r *http.Request) bool {
+			return false
+		}
+	}
 	scheme := "http"
 	if *tlsEnable {
 		scheme = "https"
@@ -284,6 +288,16 @@ func handlerWrapper(s *server, w http.ResponseWriter, r *http.Request, rh Reques
 		w.Header().Set("Content-Type", "text/plain; charset=utf-8")
 		flagutil.WriteFlags(w)
 		return
+	case "/-/healthy":
+		// This is needed for Prometheus compatibility
+		// See https://github.com/VictoriaMetrics/VictoriaMetrics/issues/1833
+		fmt.Fprintf(w, "VictoriaMetrics is Healthy.\n")
+		return
+	case "/-/ready":
+		// This is needed for Prometheus compatibility
+		// See https://github.com/VictoriaMetrics/VictoriaMetrics/issues/1833
+		fmt.Fprintf(w, "VictoriaMetrics is Ready.\n")
+		return
 	default:
 		if strings.HasPrefix(r.URL.Path, "/debug/pprof/") {
 			pprofRequests.Inc()
@@ -632,7 +646,6 @@ func GetPathPrefix() string {
 func WriteAPIHelp(w io.Writer, pathList [][2]string) {
 	for _, p := range pathList {
 		p, doc := p[0], p[1]
-		p = path.Join(*pathPrefix, p)
 		fmt.Fprintf(w, "<a href=%q>%s</a> - %s<br/>", p, p, doc)
 	}
 }
diff --git a/lib/mergeset/part.go b/lib/mergeset/part.go
index 8aafb6074..79922ee3f 100644
--- a/lib/mergeset/part.go
+++ b/lib/mergeset/part.go
@@ -296,6 +296,15 @@ func (idxbc *indexBlockCache) SizeBytes() uint64 {
 	return uint64(n)
 }
 
+func (idxbc *indexBlockCache) SizeMaxBytes() uint64 {
+	avgBlockSize := float64(64 * 1024)
+	blocksCount := idxbc.Len()
+	if blocksCount > 0 {
+		avgBlockSize = float64(idxbc.SizeBytes()) / float64(blocksCount)
+	}
+	return uint64(avgBlockSize * float64(getMaxCachedIndexBlocksPerPart()))
+}
+
 func (idxbc *indexBlockCache) Requests() uint64 {
 	return atomic.LoadUint64(&idxbc.requests)
 }
@@ -463,6 +472,15 @@ func (ibc *inmemoryBlockCache) SizeBytes() uint64 {
 	return uint64(n)
 }
 
+func (ibc *inmemoryBlockCache) SizeMaxBytes() uint64 {
+	avgBlockSize := float64(128 * 1024)
+	blocksCount := ibc.Len()
+	if blocksCount > 0 {
+		avgBlockSize = float64(ibc.SizeBytes()) / float64(blocksCount)
+	}
+	return uint64(avgBlockSize * float64(getMaxCachedInmemoryBlocksPerPart()))
+}
+
 func (ibc *inmemoryBlockCache) Requests() uint64 {
 	return atomic.LoadUint64(&ibc.requests)
 }
diff --git a/lib/mergeset/table.go b/lib/mergeset/table.go
index 2d3ccfe74..7573e27c2 100644
--- a/lib/mergeset/table.go
+++ b/lib/mergeset/table.go
@@ -410,15 +410,17 @@ type TableMetrics struct {
 	ItemsCount  uint64
 	SizeBytes   uint64
 
-	DataBlocksCacheSize      uint64
-	DataBlocksCacheSizeBytes uint64
-	DataBlocksCacheRequests  uint64
-	DataBlocksCacheMisses    uint64
-
-	IndexBlocksCacheSize      uint64
-	IndexBlocksCacheSizeBytes uint64
-	IndexBlocksCacheRequests  uint64
-	IndexBlocksCacheMisses    uint64
+	DataBlocksCacheSize         uint64
+	DataBlocksCacheSizeBytes    uint64
+	DataBlocksCacheSizeMaxBytes uint64
+	DataBlocksCacheRequests     uint64
+	DataBlocksCacheMisses       uint64
+
+	IndexBlocksCacheSize         uint64
+	IndexBlocksCacheSizeBytes    uint64
+	IndexBlocksCacheSizeMaxBytes uint64
+	IndexBlocksCacheRequests     uint64
+	IndexBlocksCacheMisses       uint64
 
 	PartsRefCount uint64
 }
@@ -443,11 +445,13 @@ func (tb *Table) UpdateMetrics(m *TableMetrics) {
 
 		m.DataBlocksCacheSize += p.ibCache.Len()
 		m.DataBlocksCacheSizeBytes += p.ibCache.SizeBytes()
+		m.DataBlocksCacheSizeMaxBytes += p.ibCache.SizeMaxBytes()
 		m.DataBlocksCacheRequests += p.ibCache.Requests()
 		m.DataBlocksCacheMisses += p.ibCache.Misses()
 
 		m.IndexBlocksCacheSize += p.idxbCache.Len()
 		m.IndexBlocksCacheSizeBytes += p.idxbCache.SizeBytes()
+		m.IndexBlocksCacheSizeMaxBytes += p.idxbCache.SizeMaxBytes()
 		m.IndexBlocksCacheRequests += p.idxbCache.Requests()
 		m.IndexBlocksCacheMisses += p.idxbCache.Misses()
 
diff --git a/lib/protoparser/graphite/parser.go b/lib/protoparser/graphite/parser.go
index c8d08c1cf..5be4cae48 100644
--- a/lib/protoparser/graphite/parser.go
+++ b/lib/protoparser/graphite/parser.go
@@ -93,7 +93,7 @@ func (r *Row) unmarshal(s string, tagsPool []Tag) ([]Tag, error) {
 		return tagsPool, fmt.Errorf("cannot find separator between metric and value in %q", s)
 	}
 	metricAndTags := s[:n]
-	tail := s[n+1:]
+	tail := stripLeadingWhitespace(s[n+1:])
 
 	tagsPool, err := r.UnmarshalMetricAndTags(metricAndTags, tagsPool)
 	if err != nil {
@@ -114,9 +114,11 @@ func (r *Row) unmarshal(s string, tagsPool []Tag) ([]Tag, error) {
 	if err != nil {
 		return tagsPool, fmt.Errorf("cannot unmarshal value from %q: %w", tail[:n], err)
 	}
-	ts, err := fastfloat.Parse(tail[n+1:])
+	tail = stripLeadingWhitespace(tail[n+1:])
+	tail = stripTrailingWhitespace(tail)
+	ts, err := fastfloat.Parse(tail)
 	if err != nil {
-		return tagsPool, fmt.Errorf("cannot unmarshal timestamp from %q: %w", tail[n+1:], err)
+		return tagsPool, fmt.Errorf("cannot unmarshal timestamp from %q: %w", tail, err)
 	}
 	r.Value = v
 	r.Timestamp = int64(ts)
@@ -215,3 +217,30 @@ func (t *Tag) unmarshal(s string) {
 		t.Value = s[n+1:]
 	}
 }
+
+func stripTrailingWhitespace(s string) string {
+	n := len(s)
+	for {
+		n--
+		if n < 0 {
+			return ""
+		}
+		ch := s[n]
+		// graphite text line protocol may use white space or tab as separator
+		// See https://github.com/grobian/carbon-c-relay/commit/f3ffe6cc2b52b07d14acbda649ad3fd6babdd528
+		if ch != ' ' && ch != '\t' {
+			return s[:n+1]
+		}
+	}
+}
+
+func stripLeadingWhitespace(s string) string {
+	for len(s) > 0 {
+		ch := s[0]
+		if ch != ' ' && ch != '\t' {
+			return s
+		}
+		s = s[1:]
+	}
+	return ""
+}
diff --git a/lib/storage/index_db.go b/lib/storage/index_db.go
index 39265b78f..5c9cf9350 100644
--- a/lib/storage/index_db.go
+++ b/lib/storage/index_db.go
@@ -130,10 +130,11 @@ const noDeadline = 1<<64 - 1
 
 // IndexDBMetrics contains essential metrics for indexDB.
 type IndexDBMetrics struct {
-	TagFiltersCacheSize      uint64
-	TagFiltersCacheSizeBytes uint64
-	TagFiltersCacheRequests  uint64
-	TagFiltersCacheMisses    uint64
+	TagFiltersCacheSize         uint64
+	TagFiltersCacheSizeBytes    uint64
+	TagFiltersCacheSizeMaxBytes uint64
+	TagFiltersCacheRequests     uint64
+	TagFiltersCacheMisses       uint64
 
 	DeletedMetricsCount uint64
 
@@ -173,6 +174,7 @@ func (db *indexDB) UpdateMetrics(m *IndexDBMetrics) {
 	db.tagFiltersCache.UpdateStats(&cs)
 	m.TagFiltersCacheSize += cs.EntriesCount
 	m.TagFiltersCacheSizeBytes += cs.BytesSize
+	m.TagFiltersCacheSizeMaxBytes += cs.MaxBytesSize
 	m.TagFiltersCacheRequests += cs.GetCalls
 	m.TagFiltersCacheMisses += cs.Misses
 
diff --git a/lib/storage/part.go b/lib/storage/part.go
index d7a68ea18..78146b9da 100644
--- a/lib/storage/part.go
+++ b/lib/storage/part.go
@@ -280,3 +280,12 @@ func (ibc *indexBlockCache) SizeBytes() uint64 {
 	ibc.mu.Unlock()
 	return uint64(n)
 }
+
+func (ibc *indexBlockCache) SizeMaxBytes() uint64 {
+	avgBlockSize := float64(64 * 1024)
+	blocksCount := ibc.Len()
+	if blocksCount > 0 {
+		avgBlockSize = float64(ibc.SizeBytes()) / float64(blocksCount)
+	}
+	return uint64(avgBlockSize * float64(getMaxCachedIndexBlocksPerPart()))
+}
diff --git a/lib/storage/partition.go b/lib/storage/partition.go
index dbe5920e1..ac6f7af98 100644
--- a/lib/storage/partition.go
+++ b/lib/storage/partition.go
@@ -306,15 +306,17 @@ func newPartition(name, smallPartsPath, bigPartsPath string, getDeletedMetricIDs
 type partitionMetrics struct {
 	PendingRows uint64
 
-	BigIndexBlocksCacheSize      uint64
-	BigIndexBlocksCacheSizeBytes uint64
-	BigIndexBlocksCacheRequests  uint64
-	BigIndexBlocksCacheMisses    uint64
-
-	SmallIndexBlocksCacheSize      uint64
-	SmallIndexBlocksCacheSizeBytes uint64
-	SmallIndexBlocksCacheRequests  uint64
-	SmallIndexBlocksCacheMisses    uint64
+	BigIndexBlocksCacheSize         uint64
+	BigIndexBlocksCacheSizeBytes    uint64
+	BigIndexBlocksCacheSizeMaxBytes uint64
+	BigIndexBlocksCacheRequests     uint64
+	BigIndexBlocksCacheMisses       uint64
+
+	SmallIndexBlocksCacheSize         uint64
+	SmallIndexBlocksCacheSizeBytes    uint64
+	SmallIndexBlocksCacheSizeMaxBytes uint64
+	SmallIndexBlocksCacheRequests     uint64
+	SmallIndexBlocksCacheMisses       uint64
 
 	BigSizeBytes   uint64
 	SmallSizeBytes uint64
@@ -362,6 +364,7 @@ func (pt *partition) UpdateMetrics(m *partitionMetrics) {
 
 		m.BigIndexBlocksCacheSize += p.ibCache.Len()
 		m.BigIndexBlocksCacheSizeBytes += p.ibCache.SizeBytes()
+		m.BigIndexBlocksCacheSizeMaxBytes += p.ibCache.SizeMaxBytes()
 		m.BigIndexBlocksCacheRequests += p.ibCache.Requests()
 		m.BigIndexBlocksCacheMisses += p.ibCache.Misses()
 		m.BigRowsCount += p.ph.RowsCount
@@ -375,6 +378,7 @@ func (pt *partition) UpdateMetrics(m *partitionMetrics) {
 
 		m.SmallIndexBlocksCacheSize += p.ibCache.Len()
 		m.SmallIndexBlocksCacheSizeBytes += p.ibCache.SizeBytes()
+		m.SmallIndexBlocksCacheSizeMaxBytes += p.ibCache.SizeMaxBytes()
 		m.SmallIndexBlocksCacheRequests += p.ibCache.Requests()
 		m.SmallIndexBlocksCacheMisses += p.ibCache.Misses()
 		m.SmallRowsCount += p.ph.RowsCount
diff --git a/lib/storage/storage.go b/lib/storage/storage.go
index 0f92eefe2..208fb2679 100644
--- a/lib/storage/storage.go
+++ b/lib/storage/storage.go
@@ -439,23 +439,26 @@ type Metrics struct {
 	TimestampsBlocksMerged uint64
 	TimestampsBytesSaved   uint64
 
-	TSIDCacheSize       uint64
-	TSIDCacheSizeBytes  uint64
-	TSIDCacheRequests   uint64
-	TSIDCacheMisses     uint64
-	TSIDCacheCollisions uint64
-
-	MetricIDCacheSize       uint64
-	MetricIDCacheSizeBytes  uint64
-	MetricIDCacheRequests   uint64
-	MetricIDCacheMisses     uint64
-	MetricIDCacheCollisions uint64
-
-	MetricNameCacheSize       uint64
-	MetricNameCacheSizeBytes  uint64
-	MetricNameCacheRequests   uint64
-	MetricNameCacheMisses     uint64
-	MetricNameCacheCollisions uint64
+	TSIDCacheSize         uint64
+	TSIDCacheSizeBytes    uint64
+	TSIDCacheSizeMaxBytes uint64
+	TSIDCacheRequests     uint64
+	TSIDCacheMisses       uint64
+	TSIDCacheCollisions   uint64
+
+	MetricIDCacheSize         uint64
+	MetricIDCacheSizeBytes    uint64
+	MetricIDCacheSizeMaxBytes uint64
+	MetricIDCacheRequests     uint64
+	MetricIDCacheMisses       uint64
+	MetricIDCacheCollisions   uint64
+
+	MetricNameCacheSize         uint64
+	MetricNameCacheSizeBytes    uint64
+	MetricNameCacheSizeMaxBytes uint64
+	MetricNameCacheRequests     uint64
+	MetricNameCacheMisses       uint64
+	MetricNameCacheCollisions   uint64
 
 	DateMetricIDCacheSize        uint64
 	DateMetricIDCacheSizeBytes   uint64
@@ -515,6 +518,7 @@ func (s *Storage) UpdateMetrics(m *Metrics) {
 	s.tsidCache.UpdateStats(&cs)
 	m.TSIDCacheSize += cs.EntriesCount
 	m.TSIDCacheSizeBytes += cs.BytesSize
+	m.TSIDCacheSizeMaxBytes += cs.MaxBytesSize
 	m.TSIDCacheRequests += cs.GetCalls
 	m.TSIDCacheMisses += cs.Misses
 	m.TSIDCacheCollisions += cs.Collisions
@@ -523,6 +527,7 @@ func (s *Storage) UpdateMetrics(m *Metrics) {
 	s.metricIDCache.UpdateStats(&cs)
 	m.MetricIDCacheSize += cs.EntriesCount
 	m.MetricIDCacheSizeBytes += cs.BytesSize
+	m.MetricIDCacheSizeMaxBytes += cs.MaxBytesSize
 	m.MetricIDCacheRequests += cs.GetCalls
 	m.MetricIDCacheMisses += cs.Misses
 	m.MetricIDCacheCollisions += cs.Collisions
@@ -531,6 +536,7 @@ func (s *Storage) UpdateMetrics(m *Metrics) {
 	s.metricNameCache.UpdateStats(&cs)
 	m.MetricNameCacheSize += cs.EntriesCount
 	m.MetricNameCacheSizeBytes += cs.BytesSize
+	m.MetricNameCacheSizeMaxBytes += cs.MaxBytesSize
 	m.MetricNameCacheRequests += cs.GetCalls
 	m.MetricNameCacheMisses += cs.Misses
 	m.MetricNameCacheCollisions += cs.Collisions
diff --git a/lib/workingsetcache/cache.go b/lib/workingsetcache/cache.go
index 7a96b1f5f..ff26470ed 100644
--- a/lib/workingsetcache/cache.go
+++ b/lib/workingsetcache/cache.go
@@ -21,9 +21,6 @@ const (
 //
 // The cache evicts inactive entries after the given expireDuration.
 // Recently accessed entries survive expireDuration.
-//
-// Comparing to fastcache, this cache minimizes the required RAM size
-// to values smaller than maxBytes.
 type Cache struct {
 	curr atomic.Value
 	prev atomic.Value
@@ -36,9 +33,6 @@ type Cache struct {
 	// After the process of switching, this flag will be set to whole.
 	mode uint32
 
-	// The maximum cache size in bytes.
-	maxBytes int
-
 	// mu serializes access to curr, prev and mode
 	// in expirationWatcher and cacheSizeWatcher.
 	mu sync.Mutex
@@ -65,7 +59,7 @@ func Load(filePath string, maxBytes int, expireDuration time.Duration) *Cache {
 		// Try loading it again with maxBytes / 2 size.
 		curr := fastcache.New(maxBytes / 2)
 		prev := fastcache.LoadFromFileOrNew(filePath, maxBytes/2)
-		c := newCacheInternal(curr, prev, maxBytes, split)
+		c := newCacheInternal(curr, prev, split)
 		c.runWatchers(expireDuration)
 		return c
 	}
@@ -74,24 +68,23 @@ func Load(filePath string, maxBytes int, expireDuration time.Duration) *Cache {
 	// Set its' mode to `whole`.
 	// There is no need in runWatchers call.
 	prev := fastcache.New(1024)
-	return newCacheInternal(curr, prev, maxBytes, whole)
+	return newCacheInternal(curr, prev, whole)
 }
 
-// New creates new cache with the given maxBytes capcity and the given expireDuration
+// New creates new cache with the given maxBytes capacity and the given expireDuration
 // for inactive entries.
 //
 // Stop must be called on the returned cache when it is no longer needed.
 func New(maxBytes int, expireDuration time.Duration) *Cache {
 	curr := fastcache.New(maxBytes / 2)
 	prev := fastcache.New(1024)
-	c := newCacheInternal(curr, prev, maxBytes, split)
+	c := newCacheInternal(curr, prev, split)
 	c.runWatchers(expireDuration)
 	return c
 }
 
-func newCacheInternal(curr, prev *fastcache.Cache, maxBytes, mode int) *Cache {
+func newCacheInternal(curr, prev *fastcache.Cache, mode int) *Cache {
 	var c Cache
-	c.maxBytes = maxBytes
 	c.curr.Store(curr)
 	c.prev.Store(prev)
 	c.stopCh = make(chan struct{})
@@ -128,13 +121,15 @@ func (c *Cache) expirationWatcher(expireDuration time.Duration) {
 			c.mu.Unlock()
 			return
 		}
-		// Expire prev cache and create fresh curr cache with c.maxBytes/2 capacity.
-		// Do not reuse prev cache, since it can have too big capacity.
+		// Expire prev cache and create fresh curr cache with the same capacity.
+		// Do not reuse prev cache, since it can occupy too big amounts of memory.
 		prev := c.prev.Load().(*fastcache.Cache)
 		prev.Reset()
 		curr := c.curr.Load().(*fastcache.Cache)
+		var cs fastcache.Stats
+		curr.UpdateStats(&cs)
 		c.prev.Store(curr)
-		curr = fastcache.New(c.maxBytes / 2)
+		curr = fastcache.New(int(cs.MaxBytesSize))
 		c.curr.Store(curr)
 		c.mu.Unlock()
 	}
@@ -144,6 +139,7 @@ func (c *Cache) cacheSizeWatcher() {
 	t := time.NewTicker(time.Minute)
 	defer t.Stop()
 
+	var maxBytesSize uint64
 	for {
 		select {
 		case <-c.stopCh:
@@ -153,12 +149,13 @@ func (c *Cache) cacheSizeWatcher() {
 		var cs fastcache.Stats
 		curr := c.curr.Load().(*fastcache.Cache)
 		curr.UpdateStats(&cs)
-		if cs.BytesSize >= uint64(0.95*float64(c.maxBytes)/2) {
+		if cs.BytesSize >= uint64(0.9*float64(cs.MaxBytesSize)) {
+			maxBytesSize = cs.MaxBytesSize
 			break
 		}
 	}
 
-	// curr cache size exceeds 50% of its capacity. It is better
+	// curr cache size exceeds 90% of its capacity. It is better
 	// to double the size of curr cache and stop using prev cache,
 	// since this will result in higher summary cache capacity.
 	//
@@ -166,7 +163,7 @@ func (c *Cache) cacheSizeWatcher() {
 	// 1) switch to mode=switching
 	// 2) move curr cache to prev
 	// 3) create curr with the double size
-	// 4) wait until curr size exceeds c.maxBytes/2, i.e. it is populated with new data
+	// 4) wait until curr size exceeds maxBytesSize, i.e. it is populated with new data
 	// 5) switch to mode=whole
 	// 6) drop prev
 
@@ -176,7 +173,7 @@ func (c *Cache) cacheSizeWatcher() {
 	prev.Reset()
 	curr := c.curr.Load().(*fastcache.Cache)
 	c.prev.Store(curr)
-	c.curr.Store(fastcache.New(c.maxBytes))
+	c.curr.Store(fastcache.New(int(maxBytesSize * 2)))
 	c.mu.Unlock()
 
 	for {
@@ -188,7 +185,7 @@ func (c *Cache) cacheSizeWatcher() {
 		var cs fastcache.Stats
 		curr := c.curr.Load().(*fastcache.Cache)
 		curr.UpdateStats(&cs)
-		if cs.BytesSize >= uint64(c.maxBytes)/2 {
+		if cs.BytesSize >= maxBytesSize {
 			break
 		}
 	}
@@ -245,6 +242,7 @@ func (c *Cache) UpdateStats(fcs *fastcache.Stats) {
 	fcs.Corruptions += cs.Corruptions
 	fcs.EntriesCount += cs.EntriesCount
 	fcs.BytesSize += cs.BytesSize
+	fcs.MaxBytesSize += cs.MaxBytesSize
 
 	fcs.GetCalls += atomic.LoadUint64(&c.cs.GetCalls)
 	fcs.SetCalls += atomic.LoadUint64(&c.cs.SetCalls)
@@ -255,6 +253,7 @@ func (c *Cache) UpdateStats(fcs *fastcache.Stats) {
 	prev.UpdateStats(&cs)
 	fcs.EntriesCount += cs.EntriesCount
 	fcs.BytesSize += cs.BytesSize
+	fcs.MaxBytesSize += cs.MaxBytesSize
 }
 
 // Get appends the found value for the given key to dst and returns the result.
diff --git a/vendor/github.com/VictoriaMetrics/fastcache/fastcache.go b/vendor/github.com/VictoriaMetrics/fastcache/fastcache.go
index 20a3c0218..342b67d8d 100644
--- a/vendor/github.com/VictoriaMetrics/fastcache/fastcache.go
+++ b/vendor/github.com/VictoriaMetrics/fastcache/fastcache.go
@@ -53,6 +53,9 @@ type Stats struct {
 	// BytesSize is the current size of the cache in bytes.
 	BytesSize uint64
 
+	// MaxBytesSize is the maximum allowed size of the cache in bytes (aka capacity).
+	MaxBytesSize uint64
+
 	// BigStats contains stats for GetBig/SetBig methods.
 	BigStats
 }
@@ -296,6 +299,7 @@ func (b *bucket) UpdateStats(s *Stats) {
 	for _, chunk := range b.chunks {
 		s.BytesSize += uint64(cap(chunk))
 	}
+	s.MaxBytesSize += uint64(len(b.chunks))*chunkSize
 	b.mu.RUnlock()
 }
 
diff --git a/vendor/github.com/aws/aws-sdk-go/aws/endpoints/defaults.go b/vendor/github.com/aws/aws-sdk-go/aws/endpoints/defaults.go
index b9f4a26de..64435c7bd 100644
--- a/vendor/github.com/aws/aws-sdk-go/aws/endpoints/defaults.go
+++ b/vendor/github.com/aws/aws-sdk-go/aws/endpoints/defaults.go
@@ -1951,6 +1951,9 @@ var awsPartition = partition{
 				endpointKey{
 					Region: "ap-northeast-2",
 				}: endpoint{},
+				endpointKey{
+					Region: "ap-northeast-3",
+				}: endpoint{},
 				endpointKey{
 					Region: "ap-south-1",
 				}: endpoint{},
@@ -3223,36 +3226,12 @@ var awsPartition = partition{
 		},
 		"cloudhsm": service{
 			Endpoints: serviceEndpoints{
-				endpointKey{
-					Region: "ap-northeast-1",
-				}: endpoint{},
-				endpointKey{
-					Region: "ap-southeast-1",
-				}: endpoint{},
-				endpointKey{
-					Region: "ap-southeast-2",
-				}: endpoint{},
-				endpointKey{
-					Region: "ca-central-1",
-				}: endpoint{},
-				endpointKey{
-					Region: "eu-central-1",
-				}: endpoint{},
 				endpointKey{
 					Region: "eu-west-1",
 				}: endpoint{},
 				endpointKey{
 					Region: "us-east-1",
 				}: endpoint{},
-				endpointKey{
-					Region: "us-east-2",
-				}: endpoint{},
-				endpointKey{
-					Region: "us-west-1",
-				}: endpoint{},
-				endpointKey{
-					Region: "us-west-2",
-				}: endpoint{},
 			},
 		},
 		"cloudhsmv2": service{
@@ -8132,6 +8111,55 @@ var awsPartition = partition{
 				},
 			},
 		},
+		"evidently": service{
+			Endpoints: serviceEndpoints{
+				endpointKey{
+					Region: "ap-northeast-1",
+				}: endpoint{
+					Hostname: "evidently.ap-northeast-1.amazonaws.com",
+				},
+				endpointKey{
+					Region: "ap-southeast-1",
+				}: endpoint{
+					Hostname: "evidently.ap-southeast-1.amazonaws.com",
+				},
+				endpointKey{
+					Region: "ap-southeast-2",
+				}: endpoint{
+					Hostname: "evidently.ap-southeast-2.amazonaws.com",
+				},
+				endpointKey{
+					Region: "eu-central-1",
+				}: endpoint{
+					Hostname: "evidently.eu-central-1.amazonaws.com",
+				},
+				endpointKey{
+					Region: "eu-north-1",
+				}: endpoint{
+					Hostname: "evidently.eu-north-1.amazonaws.com",
+				},
+				endpointKey{
+					Region: "eu-west-1",
+				}: endpoint{
+					Hostname: "evidently.eu-west-1.amazonaws.com",
+				},
+				endpointKey{
+					Region: "us-east-1",
+				}: endpoint{
+					Hostname: "evidently.us-east-1.amazonaws.com",
+				},
+				endpointKey{
+					Region: "us-east-2",
+				}: endpoint{
+					Hostname: "evidently.us-east-2.amazonaws.com",
+				},
+				endpointKey{
+					Region: "us-west-2",
+				}: endpoint{
+					Hostname: "evidently.us-west-2.amazonaws.com",
+				},
+			},
+		},
 		"finspace": service{
 			Endpoints: serviceEndpoints{
 				endpointKey{
@@ -10087,6 +10115,67 @@ var awsPartition = partition{
 				},
 			},
 		},
+		"inspector2": service{
+			Endpoints: serviceEndpoints{
+				endpointKey{
+					Region: "ap-east-1",
+				}: endpoint{},
+				endpointKey{
+					Region: "ap-northeast-1",
+				}: endpoint{},
+				endpointKey{
+					Region: "ap-northeast-2",
+				}: endpoint{},
+				endpointKey{
+					Region: "ap-south-1",
+				}: endpoint{},
+				endpointKey{
+					Region: "ap-southeast-1",
+				}: endpoint{},
+				endpointKey{
+					Region: "ap-southeast-2",
+				}: endpoint{},
+				endpointKey{
+					Region: "ca-central-1",
+				}: endpoint{},
+				endpointKey{
+					Region: "eu-central-1",
+				}: endpoint{},
+				endpointKey{
+					Region: "eu-north-1",
+				}: endpoint{},
+				endpointKey{
+					Region: "eu-south-1",
+				}: endpoint{},
+				endpointKey{
+					Region: "eu-west-1",
+				}: endpoint{},
+				endpointKey{
+					Region: "eu-west-2",
+				}: endpoint{},
+				endpointKey{
+					Region: "eu-west-3",
+				}: endpoint{},
+				endpointKey{
+					Region: "me-south-1",
+				}: endpoint{},
+				endpointKey{
+					Region: "sa-east-1",
+				}: endpoint{},
+				endpointKey{
+					Region: "us-east-1",
+				}: endpoint{},
+				endpointKey{
+					Region: "us-east-2",
+				}: endpoint{},
+				endpointKey{
+					Region: "us-west-1",
+				}: endpoint{},
+				endpointKey{
+					Region: "us-west-2",
+				}: endpoint{},
+			},
+		},
 		"iot": service{
 			Defaults: endpointDefaults{
 				defaultKey{}: endpoint{
@@ -14645,6 +14734,73 @@ var awsPartition = partition{
 				},
 			},
 		},
+		"rbin": service{
+			Endpoints: serviceEndpoints{
+				endpointKey{
+					Region: "af-south-1",
+				}: endpoint{},
+				endpointKey{
+					Region: "ap-east-1",
+				}: endpoint{},
+				endpointKey{
+					Region: "ap-northeast-1",
+				}: endpoint{},
+				endpointKey{
+					Region: "ap-northeast-2",
+				}: endpoint{},
+				endpointKey{
+					Region: "ap-northeast-3",
+				}: endpoint{},
+				endpointKey{
+					Region: "ap-south-1",
+				}: endpoint{},
+				endpointKey{
+					Region: "ap-southeast-1",
+				}: endpoint{},
+				endpointKey{
+					Region: "ap-southeast-2",
+				}: endpoint{},
+				endpointKey{
+					Region: "ca-central-1",
+				}: endpoint{},
+				endpointKey{
+					Region: "eu-central-1",
+				}: endpoint{},
+				endpointKey{
+					Region: "eu-north-1",
+				}: endpoint{},
+				endpointKey{
+					Region: "eu-south-1",
+				}: endpoint{},
+				endpointKey{
+					Region: "eu-west-1",
+				}: endpoint{},
+				endpointKey{
+					Region: "eu-west-2",
+				}: endpoint{},
+				endpointKey{
+					Region: "eu-west-3",
+				}: endpoint{},
+				endpointKey{
+					Region: "me-south-1",
+				}: endpoint{},
+				endpointKey{
+					Region: "sa-east-1",
+				}: endpoint{},
+				endpointKey{
+					Region: "us-east-1",
+				}: endpoint{},
+				endpointKey{
+					Region: "us-east-2",
+				}: endpoint{},
+				endpointKey{
+					Region: "us-west-1",
+				}: endpoint{},
+				endpointKey{
+					Region: "us-west-2",
+				}: endpoint{},
+			},
+		},
 		"rds": service{
 			Endpoints: serviceEndpoints{
 				endpointKey{
@@ -15595,6 +15751,40 @@ var awsPartition = partition{
 				}: endpoint{},
 			},
 		},
+		"rum": service{
+			Endpoints: serviceEndpoints{
+				endpointKey{
+					Region: "ap-northeast-1",
+				}: endpoint{},
+				endpointKey{
+					Region: "ap-southeast-1",
+				}: endpoint{},
+				endpointKey{
+					Region: "ap-southeast-2",
+				}: endpoint{},
+				endpointKey{
+					Region: "eu-central-1",
+				}: endpoint{},
+				endpointKey{
+					Region: "eu-north-1",
+				}: endpoint{},
+				endpointKey{
+					Region: "eu-west-1",
+				}: endpoint{},
+				endpointKey{
+					Region: "eu-west-2",
+				}: endpoint{},
+				endpointKey{
+					Region: "us-east-1",
+				}: endpoint{},
+				endpointKey{
+					Region: "us-east-2",
+				}: endpoint{},
+				endpointKey{
+					Region: "us-west-2",
+				}: endpoint{},
+			},
+		},
 		"runtime-v2-lex": service{
 			Endpoints: serviceEndpoints{
 				endpointKey{
@@ -20841,6 +21031,19 @@ var awsPartition = partition{
 				},
 			},
 		},
+		"workspaces-web": service{
+			Endpoints: serviceEndpoints{
+				endpointKey{
+					Region: "eu-west-1",
+				}: endpoint{},
+				endpointKey{
+					Region: "us-east-1",
+				}: endpoint{},
+				endpointKey{
+					Region: "us-west-2",
+				}: endpoint{},
+			},
+		},
 		"xray": service{
 			Endpoints: serviceEndpoints{
 				endpointKey{
diff --git a/vendor/github.com/aws/aws-sdk-go/aws/version.go b/vendor/github.com/aws/aws-sdk-go/aws/version.go
index 65a6bb6ec..47e3c8066 100644
--- a/vendor/github.com/aws/aws-sdk-go/aws/version.go
+++ b/vendor/github.com/aws/aws-sdk-go/aws/version.go
@@ -5,4 +5,4 @@ package aws
 const SDKName = "aws-sdk-go"
 
 // SDKVersion is the version of this SDK
-const SDKVersion = "1.42.14"
+const SDKVersion = "1.42.17"
diff --git a/vendor/github.com/aws/aws-sdk-go/service/s3/api.go b/vendor/github.com/aws/aws-sdk-go/service/s3/api.go
index 231487485..45ce9ac22 100644
--- a/vendor/github.com/aws/aws-sdk-go/service/s3/api.go
+++ b/vendor/github.com/aws/aws-sdk-go/service/s3/api.go
@@ -420,6 +420,21 @@ func (c *S3) CopyObjectRequest(input *CopyObjectInput) (req *request.Request, ou
 // see Access Control List (ACL) Overview (https://docs.aws.amazon.com/AmazonS3/latest/dev/acl-overview.html)
 // and Managing ACLs Using the REST API (https://docs.aws.amazon.com/AmazonS3/latest/dev/acl-using-rest-api.html).
 //
+// If the bucket that you're copying objects to uses the bucket owner enforced
+// setting for S3 Object Ownership, ACLs are disabled and no longer affect permissions.
+// Buckets that use this setting only accept PUT requests that don't specify
+// an ACL or PUT requests that specify bucket owner full control ACLs, such
+// as the bucket-owner-full-control canned ACL or an equivalent form of this
+// ACL expressed in the XML format.
+//
+// For more information, see Controlling ownership of objects and disabling
+// ACLs (https://docs.aws.amazon.com/AmazonS3/latest/userguide/about-object-ownership.html)
+// in the Amazon S3 User Guide.
+//
+// If your bucket uses the bucket owner enforced setting for Object Ownership,
+// all objects written to the bucket by any account will be owned by the bucket
+// owner.
+//
 // Storage Class Options
 //
 // You can use the CopyObject action to change the storage class of an object
@@ -558,8 +573,19 @@ func (c *S3) CreateBucketRequest(input *CreateBucketInput) (req *request.Request
 // your application must be able to handle 307 redirect. For more information,
 // see Virtual hosting of buckets (https://docs.aws.amazon.com/AmazonS3/latest/dev/VirtualHosting.html).
 //
-// When creating a bucket using this operation, you can optionally specify the
-// accounts or groups that should be granted specific permissions on the bucket.
+// Access control lists (ACLs)
+//
+// When creating a bucket using this operation, you can optionally configure
+// the bucket ACL to specify the accounts or groups that should be granted specific
+// permissions on the bucket.
+//
+// If your CreateBucket request includes the BucketOwnerEnforced value for the
+// x-amz-object-ownership header, your request can either not specify an ACL
+// or specify bucket owner full control ACLs, such as the bucket-owner-full-control
+// canned ACL or an equivalent ACL expressed in the XML format. For more information,
+// see Controlling object ownership (https://docs.aws.amazon.com/AmazonS3/latest/userguide/about-object-ownership.html)
+// in the Amazon S3 User Guide.
+//
 // There are two ways to grant the appropriate permissions using the request
 // headers.
 //
@@ -572,11 +598,11 @@ func (c *S3) CreateBucketRequest(input *CreateBucketInput) (req *request.Request
 //    x-amz-grant-read-acp, x-amz-grant-write-acp, and x-amz-grant-full-control
 //    headers. These headers map to the set of permissions Amazon S3 supports
 //    in an ACL. For more information, see Access control list (ACL) overview
-//    (https://docs.aws.amazon.com/AmazonS3/latest/dev/acl-overview.html). You
-//    specify each grantee as a type=value pair, where the type is one of the
-//    following: id – if the value specified is the canonical user ID of an
-//    Amazon Web Services account uri – if you are granting permissions to
-//    a predefined group emailAddress – if the value specified is the email
+//    (https://docs.aws.amazon.com/AmazonS3/latest/userguide/acl-overview.html).
+//    You specify each grantee as a type=value pair, where the type is one of
+//    the following: id – if the value specified is the canonical user ID
+//    of an Amazon Web Services account uri – if you are granting permissions
+//    to a predefined group emailAddress – if the value specified is the email
 //    address of an Amazon Web Services account Using email addresses to specify
 //    a grantee is only supported in the following Amazon Web Services Regions:
 //    US East (N. Virginia) US West (N. California) US West (Oregon) Asia Pacific
@@ -593,15 +619,23 @@ func (c *S3) CreateBucketRequest(input *CreateBucketInput) (req *request.Request
 //
 // Permissions
 //
-// If your CreateBucket request specifies ACL permissions and the ACL is public-read,
-// public-read-write, authenticated-read, or if you specify access permissions
-// explicitly through any other ACL, both s3:CreateBucket and s3:PutBucketAcl
-// permissions are needed. If the ACL the CreateBucket request is private, only
-// s3:CreateBucket permission is needed.
+// In addition to s3:CreateBucket, the following permissions are required when
+// your CreateBucket includes specific headers:
+//
+//    * ACLs - If your CreateBucket request specifies ACL permissions and the
+//    ACL is public-read, public-read-write, authenticated-read, or if you specify
+//    access permissions explicitly through any other ACL, both s3:CreateBucket
+//    and s3:PutBucketAcl permissions are needed. If the ACL the CreateBucket
+//    request is private or doesn't specify any ACLs, only s3:CreateBucket permission
+//    is needed.
 //
-// If ObjectLockEnabledForBucket is set to true in your CreateBucket request,
-// s3:PutBucketObjectLockConfiguration and s3:PutBucketVersioning permissions
-// are required.
+//    * Object Lock - If ObjectLockEnabledForBucket is set to true in your CreateBucket
+//    request, s3:PutBucketObjectLockConfiguration and s3:PutBucketVersioning
+//    permissions are required.
+//
+//    * S3 Object Ownership - If your CreateBucket request includes the the
+//    x-amz-object-ownership header, s3:PutBucketOwnershipControls permission
+//    is required.
 //
 // The following operations are related to CreateBucket:
 //
@@ -1281,17 +1315,16 @@ func (c *S3) DeleteBucketIntelligentTieringConfigurationRequest(input *DeleteBuc
 // The S3 Intelligent-Tiering storage class is designed to optimize storage
 // costs by automatically moving data to the most cost-effective storage access
 // tier, without performance impact or operational overhead. S3 Intelligent-Tiering
-// delivers automatic cost savings in two low latency and high throughput access
-// tiers. For data that can be accessed asynchronously, you can choose to activate
-// automatic archiving capabilities within the S3 Intelligent-Tiering storage
-// class.
+// delivers automatic cost savings in three low latency and high throughput
+// access tiers. To get the lowest storage cost on data that can be accessed
+// in minutes to hours, you can choose to activate additional archiving capabilities.
 //
 // The S3 Intelligent-Tiering storage class is the ideal storage class for data
 // with unknown, changing, or unpredictable access patterns, independent of
 // object size or retention period. If the size of an object is less than 128
-// KB, it is not eligible for auto-tiering. Smaller objects can be stored, but
-// they are always charged at the Frequent Access tier rates in the S3 Intelligent-Tiering
-// storage class.
+// KB, it is not monitored and not eligible for auto-tiering. Smaller objects
+// can be stored, but they are always charged at the Frequent Access tier rates
+// in the S3 Intelligent-Tiering storage class.
 //
 // For more information, see Storage class for automatically optimizing frequently
 // and infrequently accessed objects (https://docs.aws.amazon.com/AmazonS3/latest/dev/storage-class-intro.html#sc-dynamic-data-access).
@@ -2618,6 +2651,12 @@ func (c *S3) GetBucketAclRequest(input *GetBucketAclInput) (req *request.Request
 // is granted to the anonymous user, you can return the ACL of the bucket without
 // using an authorization header.
 //
+// If your bucket uses the bucket owner enforced setting for S3 Object Ownership,
+// requests to read ACLs are still supported and return the bucket-owner-full-control
+// ACL with the owner being the account that created the bucket. For more information,
+// see Controlling object ownership and disabling ACLs (https://docs.aws.amazon.com/AmazonS3/latest/userguide/about-object-ownership.html)
+// in the Amazon S3 User Guide.
+//
 // Related Resources
 //
 //    * ListObjects (https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListObjects.html)
@@ -2971,17 +3010,16 @@ func (c *S3) GetBucketIntelligentTieringConfigurationRequest(input *GetBucketInt
 // The S3 Intelligent-Tiering storage class is designed to optimize storage
 // costs by automatically moving data to the most cost-effective storage access
 // tier, without performance impact or operational overhead. S3 Intelligent-Tiering
-// delivers automatic cost savings in two low latency and high throughput access
-// tiers. For data that can be accessed asynchronously, you can choose to activate
-// automatic archiving capabilities within the S3 Intelligent-Tiering storage
-// class.
+// delivers automatic cost savings in three low latency and high throughput
+// access tiers. To get the lowest storage cost on data that can be accessed
+// in minutes to hours, you can choose to activate additional archiving capabilities.
 //
 // The S3 Intelligent-Tiering storage class is the ideal storage class for data
 // with unknown, changing, or unpredictable access patterns, independent of
 // object size or retention period. If the size of an object is less than 128
-// KB, it is not eligible for auto-tiering. Smaller objects can be stored, but
-// they are always charged at the Frequent Access tier rates in the S3 Intelligent-Tiering
-// storage class.
+// KB, it is not monitored and not eligible for auto-tiering. Smaller objects
+// can be stored, but they are always charged at the Frequent Access tier rates
+// in the S3 Intelligent-Tiering storage class.
 //
 // For more information, see Storage class for automatically optimizing frequently
 // and infrequently accessed objects (https://docs.aws.amazon.com/AmazonS3/latest/dev/storage-class-intro.html#sc-dynamic-data-access).
@@ -3809,10 +3847,10 @@ func (c *S3) GetBucketOwnershipControlsRequest(input *GetBucketOwnershipControls
 //
 // Retrieves OwnershipControls for an Amazon S3 bucket. To use this operation,
 // you must have the s3:GetBucketOwnershipControls permission. For more information
-// about Amazon S3 permissions, see Specifying Permissions in a Policy (https://docs.aws.amazon.com/AmazonS3/latest/dev/using-with-s3-actions.html).
+// about Amazon S3 permissions, see Specifying permissions in a policy (https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-with-s3-actions.html).
 //
 // For information about Amazon S3 Object Ownership, see Using Object Ownership
-// (https://docs.aws.amazon.com/AmazonS3/latest/dev/about-object-ownership.html).
+// (https://docs.aws.amazon.com/AmazonS3/latest/userguide/about-object-ownership.html).
 //
 // The following operations are related to GetBucketOwnershipControls:
 //
@@ -4739,6 +4777,12 @@ func (c *S3) GetObjectAclRequest(input *GetObjectAclInput) (req *request.Request
 // By default, GET returns ACL information about the current version of an object.
 // To return ACL information about a different version, use the versionId subresource.
 //
+// If your bucket uses the bucket owner enforced setting for S3 Object Ownership,
+// requests to read ACLs are still supported and return the bucket-owner-full-control
+// ACL with the owner being the account that created the bucket. For more information,
+// see Controlling object ownership and disabling ACLs (https://docs.aws.amazon.com/AmazonS3/latest/userguide/about-object-ownership.html)
+// in the Amazon S3 User Guide.
+//
 // The following operations are related to GetObjectAcl:
 //
 //    * GetObject (https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObject.html)
@@ -5680,17 +5724,16 @@ func (c *S3) ListBucketIntelligentTieringConfigurationsRequest(input *ListBucket
 // The S3 Intelligent-Tiering storage class is designed to optimize storage
 // costs by automatically moving data to the most cost-effective storage access
 // tier, without performance impact or operational overhead. S3 Intelligent-Tiering
-// delivers automatic cost savings in two low latency and high throughput access
-// tiers. For data that can be accessed asynchronously, you can choose to activate
-// automatic archiving capabilities within the S3 Intelligent-Tiering storage
-// class.
+// delivers automatic cost savings in three low latency and high throughput
+// access tiers. To get the lowest storage cost on data that can be accessed
+// in minutes to hours, you can choose to activate additional archiving capabilities.
 //
 // The S3 Intelligent-Tiering storage class is the ideal storage class for data
 // with unknown, changing, or unpredictable access patterns, independent of
 // object size or retention period. If the size of an object is less than 128
-// KB, it is not eligible for auto-tiering. Smaller objects can be stored, but
-// they are always charged at the Frequent Access tier rates in the S3 Intelligent-Tiering
-// storage class.
+// KB, it is not monitored and not eligible for auto-tiering. Smaller objects
+// can be stored, but they are always charged at the Frequent Access tier rates
+// in the S3 Intelligent-Tiering storage class.
 //
 // For more information, see Storage class for automatically optimizing frequently
 // and infrequently accessed objects (https://docs.aws.amazon.com/AmazonS3/latest/dev/storage-class-intro.html#sc-dynamic-data-access).
@@ -6985,6 +7028,14 @@ func (c *S3) PutBucketAclRequest(input *PutBucketAclInput) (req *request.Request
 // existing application that updates a bucket ACL using the request body, then
 // you can continue to use that approach.
 //
+// If your bucket uses the bucket owner enforced setting for S3 Object Ownership,
+// ACLs are disabled and no longer affect permissions. You must use policies
+// to grant access to your bucket and the objects in it. Requests to set ACLs
+// or update ACLs fail and return the AccessControlListNotSupported error code.
+// Requests to read ACLs are still supported. For more information, see Controlling
+// object ownership (https://docs.aws.amazon.com/AmazonS3/latest/userguide/about-object-ownership.html)
+// in the Amazon S3 User Guide.
+//
 // Access Permissions
 //
 // You can set access permissions using one of the following methods:
@@ -7479,17 +7530,16 @@ func (c *S3) PutBucketIntelligentTieringConfigurationRequest(input *PutBucketInt
 // The S3 Intelligent-Tiering storage class is designed to optimize storage
 // costs by automatically moving data to the most cost-effective storage access
 // tier, without performance impact or operational overhead. S3 Intelligent-Tiering
-// delivers automatic cost savings in two low latency and high throughput access
-// tiers. For data that can be accessed asynchronously, you can choose to activate
-// automatic archiving capabilities within the S3 Intelligent-Tiering storage
-// class.
+// delivers automatic cost savings in three low latency and high throughput
+// access tiers. To get the lowest storage cost on data that can be accessed
+// in minutes to hours, you can choose to activate additional archiving capabilities.
 //
 // The S3 Intelligent-Tiering storage class is the ideal storage class for data
 // with unknown, changing, or unpredictable access patterns, independent of
 // object size or retention period. If the size of an object is less than 128
-// KB, it is not eligible for auto-tiering. Smaller objects can be stored, but
-// they are always charged at the Frequent Access tier rates in the S3 Intelligent-Tiering
-// storage class.
+// KB, it is not monitored and not eligible for auto-tiering. Smaller objects
+// can be stored, but they are always charged at the Frequent Access tier rates
+// in the S3 Intelligent-Tiering storage class.
 //
 // For more information, see Storage class for automatically optimizing frequently
 // and infrequently accessed objects (https://docs.aws.amazon.com/AmazonS3/latest/dev/storage-class-intro.html#sc-dynamic-data-access).
@@ -8003,6 +8053,12 @@ func (c *S3) PutBucketLoggingRequest(input *PutBucketLoggingInput) (req *request
 // the Grantee request element to grant access to other people. The Permissions
 // request element specifies the kind of access the grantee has to the logs.
 //
+// If the target bucket for log delivery uses the bucket owner enforced setting
+// for S3 Object Ownership, you can't use the Grantee request element to grant
+// access to others. Permissions can only be granted using policies. For more
+// information, see Permissions for server access log delivery (https://docs.aws.amazon.com/AmazonS3/latest/userguide/enable-server-access-logging.html#grant-log-delivery-permissions-general)
+// in the Amazon S3 User Guide.
+//
 // Grantee Values
 //
 // You can specify the person (grantee) to whom you're assigning access rights
@@ -8026,7 +8082,8 @@ func (c *S3) PutBucketLoggingRequest(input *PutBucketLoggingInput) (req *request
 // <BucketLoggingStatus xmlns="http://doc.s3.amazonaws.com/2006-03-01" />
 //
 // For more information about server access logging, see Server Access Logging
-// (https://docs.aws.amazon.com/AmazonS3/latest/dev/ServerLogs.html).
+// (https://docs.aws.amazon.com/AmazonS3/latest/userguide/ServerLogs.html) in
+// the Amazon S3 User Guide.
 //
 // For more information about creating a bucket, see CreateBucket (https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateBucket.html).
 // For more information about returning the logging status of a bucket, see
@@ -8435,11 +8492,11 @@ func (c *S3) PutBucketOwnershipControlsRequest(input *PutBucketOwnershipControls
 //
 // Creates or modifies OwnershipControls for an Amazon S3 bucket. To use this
 // operation, you must have the s3:PutBucketOwnershipControls permission. For
-// more information about Amazon S3 permissions, see Specifying Permissions
-// in a Policy (https://docs.aws.amazon.com/AmazonS3/latest/dev/using-with-s3-actions.html).
+// more information about Amazon S3 permissions, see Specifying permissions
+// in a policy (https://docs.aws.amazon.com/AmazonS3/latest/user-guide/using-with-s3-actions.html).
 //
-// For information about Amazon S3 Object Ownership, see Using Object Ownership
-// (https://docs.aws.amazon.com/AmazonS3/latest/dev/about-object-ownership.html).
+// For information about Amazon S3 Object Ownership, see Using object ownership
+// (https://docs.aws.amazon.com/AmazonS3/latest/user-guide/about-object-ownership.html).
 //
 // The following operations are related to PutBucketOwnershipControls:
 //
@@ -9277,6 +9334,23 @@ func (c *S3) PutObjectRequest(input *PutObjectInput) (req *request.Request, outp
 // Overview (https://docs.aws.amazon.com/AmazonS3/latest/dev/acl-overview.html)
 // and Managing ACLs Using the REST API (https://docs.aws.amazon.com/AmazonS3/latest/dev/acl-using-rest-api.html).
 //
+// If the bucket that you're uploading objects to uses the bucket owner enforced
+// setting for S3 Object Ownership, ACLs are disabled and no longer affect permissions.
+// Buckets that use this setting only accept PUT requests that don't specify
+// an ACL or PUT requests that specify bucket owner full control ACLs, such
+// as the bucket-owner-full-control canned ACL or an equivalent form of this
+// ACL expressed in the XML format. PUT requests that contain other ACLs (for
+// example, custom grants to certain Amazon Web Services accounts) fail and
+// return a 400 error with the error code AccessControlListNotSupported.
+//
+// For more information, see Controlling ownership of objects and disabling
+// ACLs (https://docs.aws.amazon.com/AmazonS3/latest/userguide/about-object-ownership.html)
+// in the Amazon S3 User Guide.
+//
+// If your bucket uses the bucket owner enforced setting for Object Ownership,
+// all objects written to the bucket by any account will be owned by the bucket
+// owner.
+//
 // Storage Class Options
 //
 // By default, Amazon S3 uses the STANDARD Storage Class to store newly created
@@ -9396,6 +9470,14 @@ func (c *S3) PutObjectAclRequest(input *PutObjectAclInput) (req *request.Request
 // Control List (ACL) Overview (https://docs.aws.amazon.com/AmazonS3/latest/dev/acl-overview.html)
 // in the Amazon S3 User Guide.
 //
+// If your bucket uses the bucket owner enforced setting for S3 Object Ownership,
+// ACLs are disabled and no longer affect permissions. You must use policies
+// to grant access to your bucket and the objects in it. Requests to set ACLs
+// or update ACLs fail and return the AccessControlListNotSupported error code.
+// Requests to read ACLs are still supported. For more information, see Controlling
+// object ownership (https://docs.aws.amazon.com/AmazonS3/latest/userguide/about-object-ownership.html)
+// in the Amazon S3 User Guide.
+//
 // Access Permissions
 //
 // You can set access permissions using one of the following methods:
@@ -13734,6 +13816,22 @@ type CreateBucketInput struct {
 
 	// Specifies whether you want S3 Object Lock to be enabled for the new bucket.
 	ObjectLockEnabledForBucket *bool `location:"header" locationName:"x-amz-bucket-object-lock-enabled" type:"boolean"`
+
+	// The container element for object ownership for a bucket's ownership controls.
+	//
+	// BucketOwnerPreferred - Objects uploaded to the bucket change ownership to
+	// the bucket owner if the objects are uploaded with the bucket-owner-full-control
+	// canned ACL.
+	//
+	// ObjectWriter - The uploading account will own the object if the object is
+	// uploaded with the bucket-owner-full-control canned ACL.
+	//
+	// BucketOwnerEnforced - Access control lists (ACLs) are disabled and no longer
+	// affect permissions. The bucket owner automatically owns and has full control
+	// over every object in the bucket. The bucket only accepts PUT requests that
+	// don't specify an ACL or bucket owner full control ACLs, such as the bucket-owner-full-control
+	// canned ACL or an equivalent form of this ACL expressed in the XML format.
+	ObjectOwnership *string `location:"header" locationName:"x-amz-object-ownership" type:"string" enum:"ObjectOwnership"`
 }
 
 // String returns the string representation.
@@ -13831,6 +13929,12 @@ func (s *CreateBucketInput) SetObjectLockEnabledForBucket(v bool) *CreateBucketI
 	return s
 }
 
+// SetObjectOwnership sets the ObjectOwnership field's value.
+func (s *CreateBucketInput) SetObjectOwnership(v string) *CreateBucketInput {
+	s.ObjectOwnership = &v
+	return s
+}
+
 type CreateBucketOutput struct {
 	_ struct{} `type:"structure"`
 
@@ -17821,6 +17925,29 @@ func (s *ErrorDocument) SetKey(v string) *ErrorDocument {
 	return s
 }
 
+// A container for specifying the configuration for Amazon EventBridge.
+type EventBridgeConfiguration struct {
+	_ struct{} `type:"structure"`
+}
+
+// String returns the string representation.
+//
+// API parameter values that are decorated as "sensitive" in the API will not
+// be included in the string output. The member name will be present, but the
+// value will be replaced with "sensitive".
+func (s EventBridgeConfiguration) String() string {
+	return awsutil.Prettify(s)
+}
+
+// GoString returns the string representation.
+//
+// API parameter values that are decorated as "sensitive" in the API will not
+// be included in the string output. The member name will be present, but the
+// value will be replaced with "sensitive".
+func (s EventBridgeConfiguration) GoString() string {
+	return s.String()
+}
+
 // Optional configuration to replicate existing source bucket objects. For more
 // information, see Replicating Existing Objects (https://docs.aws.amazon.com/AmazonS3/latest/dev/replication-what-is-isnot-replicated.html#existing-object-replication)
 // in the Amazon S3 User Guide.
@@ -19667,8 +19794,8 @@ func (s GetBucketOwnershipControlsInput) updateArnableField(v string) (interface
 type GetBucketOwnershipControlsOutput struct {
 	_ struct{} `type:"structure" payload:"OwnershipControls"`
 
-	// The OwnershipControls (BucketOwnerPreferred or ObjectWriter) currently in
-	// effect for this Amazon S3 bucket.
+	// The OwnershipControls (BucketOwnerEnforced, BucketOwnerPreferred, or ObjectWriter)
+	// currently in effect for this Amazon S3 bucket.
 	OwnershipControls *OwnershipControls `type:"structure"`
 }
 
@@ -27454,6 +27581,11 @@ type LoggingEnabled struct {
 	TargetBucket *string `type:"string" required:"true"`
 
 	// Container for granting information.
+	//
+	// Buckets that use the bucket owner enforced setting for Object Ownership don't
+	// support target grants. For more information, see Permissions for server access
+	// log delivery (https://docs.aws.amazon.com/AmazonS3/latest/userguide/enable-server-access-logging.html#grant-log-delivery-permissions-general)
+	// in the Amazon S3 User Guide.
 	TargetGrants []*TargetGrant `locationNameList:"Grant" type:"list"`
 
 	// A prefix for all log object keys. If you store log files from multiple Amazon
@@ -27980,12 +28112,12 @@ func (s *NoncurrentVersionExpiration) SetNoncurrentDays(v int64) *NoncurrentVers
 }
 
 // Container for the transition rule that describes when noncurrent objects
-// transition to the STANDARD_IA, ONEZONE_IA, INTELLIGENT_TIERING, GLACIER,
-// or DEEP_ARCHIVE storage class. If your bucket is versioning-enabled (or versioning
-// is suspended), you can set this action to request that Amazon S3 transition
-// noncurrent object versions to the STANDARD_IA, ONEZONE_IA, INTELLIGENT_TIERING,
-// GLACIER, or DEEP_ARCHIVE storage class at a specific period in the object's
-// lifetime.
+// transition to the STANDARD_IA, ONEZONE_IA, INTELLIGENT_TIERING, GLACIER_IR,
+// GLACIER, or DEEP_ARCHIVE storage class. If your bucket is versioning-enabled
+// (or versioning is suspended), you can set this action to request that Amazon
+// S3 transition noncurrent object versions to the STANDARD_IA, ONEZONE_IA,
+// INTELLIGENT_TIERING, GLACIER_IR, GLACIER, or DEEP_ARCHIVE storage class at
+// a specific period in the object's lifetime.
 type NoncurrentVersionTransition struct {
 	_ struct{} `type:"structure"`
 
@@ -28048,6 +28180,9 @@ func (s *NoncurrentVersionTransition) SetStorageClass(v string) *NoncurrentVersi
 type NotificationConfiguration struct {
 	_ struct{} `type:"structure"`
 
+	// Enables delivery of events to Amazon EventBridge.
+	EventBridgeConfiguration *EventBridgeConfiguration `type:"structure"`
+
 	// Describes the Lambda functions to invoke and the events for which to invoke
 	// them.
 	LambdaFunctionConfigurations []*LambdaFunctionConfiguration `locationName:"CloudFunctionConfiguration" type:"list" flattened:"true"`
@@ -28119,6 +28254,12 @@ func (s *NotificationConfiguration) Validate() error {
 	return nil
 }
 
+// SetEventBridgeConfiguration sets the EventBridgeConfiguration field's value.
+func (s *NotificationConfiguration) SetEventBridgeConfiguration(v *EventBridgeConfiguration) *NotificationConfiguration {
+	s.EventBridgeConfiguration = v
+	return s
+}
+
 // SetLambdaFunctionConfigurations sets the LambdaFunctionConfigurations field's value.
 func (s *NotificationConfiguration) SetLambdaFunctionConfigurations(v []*LambdaFunctionConfiguration) *NotificationConfiguration {
 	s.LambdaFunctionConfigurations = v
@@ -28830,6 +28971,12 @@ type OwnershipControlsRule struct {
 	// ObjectWriter - The uploading account will own the object if the object is
 	// uploaded with the bucket-owner-full-control canned ACL.
 	//
+	// BucketOwnerEnforced - Access control lists (ACLs) are disabled and no longer
+	// affect permissions. The bucket owner automatically owns and has full control
+	// over every object in the bucket. The bucket only accepts PUT requests that
+	// don't specify an ACL or bucket owner full control ACLs, such as the bucket-owner-full-control
+	// canned ACL or an equivalent form of this ACL expressed in the XML format.
+	//
 	// ObjectOwnership is a required field
 	ObjectOwnership *string `type:"string" required:"true" enum:"ObjectOwnership"`
 }
@@ -30780,6 +30927,10 @@ type PutBucketNotificationConfigurationInput struct {
 	//
 	// NotificationConfiguration is a required field
 	NotificationConfiguration *NotificationConfiguration `locationName:"NotificationConfiguration" type:"structure" required:"true" xmlURI:"http://s3.amazonaws.com/doc/2006-03-01/"`
+
+	// Skips validation of Amazon SQS, Amazon SNS, and Lambda destinations. True
+	// or false value.
+	SkipDestinationValidation *bool `location:"header" locationName:"x-amz-skip-destination-validation" type:"boolean"`
 }
 
 // String returns the string representation.
@@ -30849,6 +31000,12 @@ func (s *PutBucketNotificationConfigurationInput) SetNotificationConfiguration(v
 	return s
 }
 
+// SetSkipDestinationValidation sets the SkipDestinationValidation field's value.
+func (s *PutBucketNotificationConfigurationInput) SetSkipDestinationValidation(v bool) *PutBucketNotificationConfigurationInput {
+	s.SkipDestinationValidation = &v
+	return s
+}
+
 func (s *PutBucketNotificationConfigurationInput) getEndpointARN() (arn.Resource, error) {
 	if s.Bucket == nil {
 		return nil, fmt.Errorf("member Bucket is nil")
@@ -31041,8 +31198,8 @@ type PutBucketOwnershipControlsInput struct {
 	// error.
 	ExpectedBucketOwner *string `location:"header" locationName:"x-amz-expected-bucket-owner" type:"string"`
 
-	// The OwnershipControls (BucketOwnerPreferred or ObjectWriter) that you want
-	// to apply to this Amazon S3 bucket.
+	// The OwnershipControls (BucketOwnerEnforced, BucketOwnerPreferred, or ObjectWriter)
+	// that you want to apply to this Amazon S3 bucket.
 	//
 	// OwnershipControls is a required field
 	OwnershipControls *OwnershipControls `locationName:"OwnershipControls" type:"structure" required:"true" xmlURI:"http://s3.amazonaws.com/doc/2006-03-01/"`
@@ -35162,12 +35319,12 @@ type Rule struct {
 	NoncurrentVersionExpiration *NoncurrentVersionExpiration `type:"structure"`
 
 	// Container for the transition rule that describes when noncurrent objects
-	// transition to the STANDARD_IA, ONEZONE_IA, INTELLIGENT_TIERING, GLACIER,
-	// or DEEP_ARCHIVE storage class. If your bucket is versioning-enabled (or versioning
-	// is suspended), you can set this action to request that Amazon S3 transition
-	// noncurrent object versions to the STANDARD_IA, ONEZONE_IA, INTELLIGENT_TIERING,
-	// GLACIER, or DEEP_ARCHIVE storage class at a specific period in the object's
-	// lifetime.
+	// transition to the STANDARD_IA, ONEZONE_IA, INTELLIGENT_TIERING, GLACIER_IR,
+	// GLACIER, or DEEP_ARCHIVE storage class. If your bucket is versioning-enabled
+	// (or versioning is suspended), you can set this action to request that Amazon
+	// S3 transition noncurrent object versions to the STANDARD_IA, ONEZONE_IA,
+	// INTELLIGENT_TIERING, GLACIER_IR, GLACIER, or DEEP_ARCHIVE storage class at
+	// a specific period in the object's lifetime.
 	NoncurrentVersionTransition *NoncurrentVersionTransition `type:"structure"`
 
 	// Object key prefix that identifies one or more objects to which this rule
@@ -36623,6 +36780,11 @@ func (s *Tagging) SetTagSet(v []*Tag) *Tagging {
 }
 
 // Container for granting information.
+//
+// Buckets that use the bucket owner enforced setting for Object Ownership don't
+// support target grants. For more information, see Permissions server access
+// log delivery (https://docs.aws.amazon.com/AmazonS3/latest/userguide/enable-server-access-logging.html#grant-log-delivery-permissions-general)
+// in the Amazon S3 User Guide.
 type TargetGrant struct {
 	_ struct{} `type:"structure"`
 
@@ -38691,6 +38853,36 @@ const (
 
 	// EventS3ReplicationOperationReplicatedAfterThreshold is a Event enum value
 	EventS3ReplicationOperationReplicatedAfterThreshold = "s3:Replication:OperationReplicatedAfterThreshold"
+
+	// EventS3ObjectRestoreDelete is a Event enum value
+	EventS3ObjectRestoreDelete = "s3:ObjectRestore:Delete"
+
+	// EventS3LifecycleTransition is a Event enum value
+	EventS3LifecycleTransition = "s3:LifecycleTransition"
+
+	// EventS3IntelligentTiering is a Event enum value
+	EventS3IntelligentTiering = "s3:IntelligentTiering"
+
+	// EventS3ObjectAclPut is a Event enum value
+	EventS3ObjectAclPut = "s3:ObjectAcl:Put"
+
+	// EventS3LifecycleExpiration is a Event enum value
+	EventS3LifecycleExpiration = "s3:LifecycleExpiration:*"
+
+	// EventS3LifecycleExpirationDelete is a Event enum value
+	EventS3LifecycleExpirationDelete = "s3:LifecycleExpiration:Delete"
+
+	// EventS3LifecycleExpirationDeleteMarkerCreated is a Event enum value
+	EventS3LifecycleExpirationDeleteMarkerCreated = "s3:LifecycleExpiration:DeleteMarkerCreated"
+
+	// EventS3ObjectTagging is a Event enum value
+	EventS3ObjectTagging = "s3:ObjectTagging:*"
+
+	// EventS3ObjectTaggingPut is a Event enum value
+	EventS3ObjectTaggingPut = "s3:ObjectTagging:Put"
+
+	// EventS3ObjectTaggingDelete is a Event enum value
+	EventS3ObjectTaggingDelete = "s3:ObjectTagging:Delete"
 )
 
 // Event_Values returns all elements of the Event enum
@@ -38713,6 +38905,16 @@ func Event_Values() []string {
 		EventS3ReplicationOperationNotTracked,
 		EventS3ReplicationOperationMissedThreshold,
 		EventS3ReplicationOperationReplicatedAfterThreshold,
+		EventS3ObjectRestoreDelete,
+		EventS3LifecycleTransition,
+		EventS3IntelligentTiering,
+		EventS3ObjectAclPut,
+		EventS3LifecycleExpiration,
+		EventS3LifecycleExpirationDelete,
+		EventS3LifecycleExpirationDeleteMarkerCreated,
+		EventS3ObjectTagging,
+		EventS3ObjectTaggingPut,
+		EventS3ObjectTaggingDelete,
 	}
 }
 
@@ -39120,12 +39322,21 @@ func ObjectLockRetentionMode_Values() []string {
 //
 // ObjectWriter - The uploading account will own the object if the object is
 // uploaded with the bucket-owner-full-control canned ACL.
+//
+// BucketOwnerEnforced - Access control lists (ACLs) are disabled and no longer
+// affect permissions. The bucket owner automatically owns and has full control
+// over every object in the bucket. The bucket only accepts PUT requests that
+// don't specify an ACL or bucket owner full control ACLs, such as the bucket-owner-full-control
+// canned ACL or an equivalent form of this ACL expressed in the XML format.
 const (
 	// ObjectOwnershipBucketOwnerPreferred is a ObjectOwnership enum value
 	ObjectOwnershipBucketOwnerPreferred = "BucketOwnerPreferred"
 
 	// ObjectOwnershipObjectWriter is a ObjectOwnership enum value
 	ObjectOwnershipObjectWriter = "ObjectWriter"
+
+	// ObjectOwnershipBucketOwnerEnforced is a ObjectOwnership enum value
+	ObjectOwnershipBucketOwnerEnforced = "BucketOwnerEnforced"
 )
 
 // ObjectOwnership_Values returns all elements of the ObjectOwnership enum
@@ -39133,6 +39344,7 @@ func ObjectOwnership_Values() []string {
 	return []string{
 		ObjectOwnershipBucketOwnerPreferred,
 		ObjectOwnershipObjectWriter,
+		ObjectOwnershipBucketOwnerEnforced,
 	}
 }
 
@@ -39160,6 +39372,9 @@ const (
 
 	// ObjectStorageClassOutposts is a ObjectStorageClass enum value
 	ObjectStorageClassOutposts = "OUTPOSTS"
+
+	// ObjectStorageClassGlacierIr is a ObjectStorageClass enum value
+	ObjectStorageClassGlacierIr = "GLACIER_IR"
 )
 
 // ObjectStorageClass_Values returns all elements of the ObjectStorageClass enum
@@ -39173,6 +39388,7 @@ func ObjectStorageClass_Values() []string {
 		ObjectStorageClassIntelligentTiering,
 		ObjectStorageClassDeepArchive,
 		ObjectStorageClassOutposts,
+		ObjectStorageClassGlacierIr,
 	}
 }
 
@@ -39447,6 +39663,9 @@ const (
 
 	// StorageClassOutposts is a StorageClass enum value
 	StorageClassOutposts = "OUTPOSTS"
+
+	// StorageClassGlacierIr is a StorageClass enum value
+	StorageClassGlacierIr = "GLACIER_IR"
 )
 
 // StorageClass_Values returns all elements of the StorageClass enum
@@ -39460,6 +39679,7 @@ func StorageClass_Values() []string {
 		StorageClassGlacier,
 		StorageClassDeepArchive,
 		StorageClassOutposts,
+		StorageClassGlacierIr,
 	}
 }
 
@@ -39526,6 +39746,9 @@ const (
 
 	// TransitionStorageClassDeepArchive is a TransitionStorageClass enum value
 	TransitionStorageClassDeepArchive = "DEEP_ARCHIVE"
+
+	// TransitionStorageClassGlacierIr is a TransitionStorageClass enum value
+	TransitionStorageClassGlacierIr = "GLACIER_IR"
 )
 
 // TransitionStorageClass_Values returns all elements of the TransitionStorageClass enum
@@ -39536,6 +39759,7 @@ func TransitionStorageClass_Values() []string {
 		TransitionStorageClassOnezoneIa,
 		TransitionStorageClassIntelligentTiering,
 		TransitionStorageClassDeepArchive,
+		TransitionStorageClassGlacierIr,
 	}
 }
 
diff --git a/vendor/github.com/cncf/xds/go/xds/type/matcher/v3/matcher.pb.go b/vendor/github.com/cncf/xds/go/xds/type/matcher/v3/matcher.pb.go
index 92677f4fa..6b912e508 100644
--- a/vendor/github.com/cncf/xds/go/xds/type/matcher/v3/matcher.pb.go
+++ b/vendor/github.com/cncf/xds/go/xds/type/matcher/v3/matcher.pb.go
@@ -706,7 +706,7 @@ var file_xds_type_matcher_v3_matcher_proto_rawDesc = []byte{
 	0x2f, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x2f, 0x76, 0x33, 0x2f, 0x73, 0x74, 0x72, 0x69,
 	0x6e, 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x17, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61,
 	0x74, 0x65, 0x2f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74,
-	0x6f, 0x22, 0x85, 0x10, 0x0a, 0x07, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x12, 0x4d, 0x0a,
+	0x6f, 0x22, 0x80, 0x10, 0x0a, 0x07, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x12, 0x4d, 0x0a,
 	0x0c, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x18, 0x01, 0x20,
 	0x01, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x78, 0x64, 0x73, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x2e, 0x6d,
 	0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x2e, 0x76, 0x33, 0x2e, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x65,
@@ -833,14 +833,14 @@ var file_xds_type_matcher_v3_matcher_proto_rawDesc = []byte{
 	0x74, 0x63, 0x68, 0x65, 0x72, 0x2e, 0x4f, 0x6e, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x52, 0x05, 0x76,
 	0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x42, 0x10, 0x0a, 0x09, 0x74, 0x72, 0x65, 0x65,
 	0x5f, 0x74, 0x79, 0x70, 0x65, 0x12, 0x03, 0xf8, 0x42, 0x01, 0x3a, 0x08, 0xd2, 0xc6, 0xa4, 0xe1,
-	0x06, 0x02, 0x08, 0x01, 0x42, 0x13, 0x0a, 0x0c, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x5f,
-	0x74, 0x79, 0x70, 0x65, 0x12, 0x03, 0xf8, 0x42, 0x01, 0x42, 0x5c, 0x0a, 0x1e, 0x63, 0x6f, 0x6d,
-	0x2e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x78, 0x64, 0x73, 0x2e, 0x74, 0x79, 0x70, 0x65,
-	0x2e, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x2e, 0x76, 0x33, 0x42, 0x0c, 0x4d, 0x61, 0x74,
-	0x63, 0x68, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x2a, 0x67, 0x69, 0x74,
-	0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6e, 0x63, 0x66, 0x2f, 0x78, 0x64, 0x73,
-	0x2f, 0x67, 0x6f, 0x2f, 0x78, 0x64, 0x73, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x2f, 0x6d, 0x61, 0x74,
-	0x63, 0x68, 0x65, 0x72, 0x2f, 0x76, 0x33, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+	0x06, 0x02, 0x08, 0x01, 0x42, 0x0e, 0x0a, 0x0c, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x5f,
+	0x74, 0x79, 0x70, 0x65, 0x42, 0x5c, 0x0a, 0x1e, 0x63, 0x6f, 0x6d, 0x2e, 0x67, 0x69, 0x74, 0x68,
+	0x75, 0x62, 0x2e, 0x78, 0x64, 0x73, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x2e, 0x6d, 0x61, 0x74, 0x63,
+	0x68, 0x65, 0x72, 0x2e, 0x76, 0x33, 0x42, 0x0c, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x50,
+	0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x2a, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63,
+	0x6f, 0x6d, 0x2f, 0x63, 0x6e, 0x63, 0x66, 0x2f, 0x78, 0x64, 0x73, 0x2f, 0x67, 0x6f, 0x2f, 0x78,
+	0x64, 0x73, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x2f, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x2f,
+	0x76, 0x33, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
 }
 
 var (
diff --git a/vendor/github.com/cncf/xds/go/xds/type/matcher/v3/matcher.pb.validate.go b/vendor/github.com/cncf/xds/go/xds/type/matcher/v3/matcher.pb.validate.go
index ea38307b2..3175b856b 100644
--- a/vendor/github.com/cncf/xds/go/xds/type/matcher/v3/matcher.pb.validate.go
+++ b/vendor/github.com/cncf/xds/go/xds/type/matcher/v3/matcher.pb.validate.go
@@ -76,12 +76,6 @@ func (m *Matcher) Validate() error {
 			}
 		}
 
-	default:
-		return MatcherValidationError{
-			field:  "MatcherType",
-			reason: "value is required",
-		}
-
 	}
 
 	return nil
diff --git a/vendor/golang.org/x/net/http2/transport.go b/vendor/golang.org/x/net/http2/transport.go
index 581999bed..f135b0f75 100644
--- a/vendor/golang.org/x/net/http2/transport.go
+++ b/vendor/golang.org/x/net/http2/transport.go
@@ -1252,12 +1252,12 @@ func (cs *clientStream) writeRequest(req *http.Request) (err error) {
 	}
 
 	continueTimeout := cc.t.expectContinueTimeout()
-	if continueTimeout != 0 &&
-		!httpguts.HeaderValuesContainsToken(
-			req.Header["Expect"],
-			"100-continue") {
-		continueTimeout = 0
-		cs.on100 = make(chan struct{}, 1)
+	if continueTimeout != 0 {
+		if !httpguts.HeaderValuesContainsToken(req.Header["Expect"], "100-continue") {
+			continueTimeout = 0
+		} else {
+			cs.on100 = make(chan struct{}, 1)
+		}
 	}
 
 	// Past this point (where we send request headers), it is possible for
diff --git a/vendor/modules.txt b/vendor/modules.txt
index edb431bc3..bb3c2b692 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -10,7 +10,7 @@ cloud.google.com/go/internal/version
 ## explicit
 cloud.google.com/go/storage
 cloud.google.com/go/storage/internal/apiv2
-# github.com/VictoriaMetrics/fastcache v1.7.0
+# github.com/VictoriaMetrics/fastcache v1.8.0
 ## explicit
 github.com/VictoriaMetrics/fastcache
 # github.com/VictoriaMetrics/fasthttp v1.1.0
@@ -28,7 +28,7 @@ github.com/VictoriaMetrics/metricsql/binaryop
 # github.com/VividCortex/ewma v1.2.0
 ## explicit
 github.com/VividCortex/ewma
-# github.com/aws/aws-sdk-go v1.42.14
+# github.com/aws/aws-sdk-go v1.42.17
 ## explicit
 github.com/aws/aws-sdk-go/aws
 github.com/aws/aws-sdk-go/aws/arn
@@ -96,7 +96,8 @@ github.com/cheggaaa/pb/v3
 github.com/cheggaaa/pb/v3/termutil
 # github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4
 github.com/cncf/udpa/go/udpa/type/v1
-# github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1
+# github.com/cncf/xds/go v0.0.0-20211130200136-a8f946100490
+## explicit
 github.com/cncf/xds/go/udpa/annotations
 github.com/cncf/xds/go/udpa/type/v1
 github.com/cncf/xds/go/xds/annotations/v3
@@ -303,7 +304,7 @@ go.opencensus.io/trace/propagation
 go.opencensus.io/trace/tracestate
 # go.uber.org/atomic v1.9.0
 go.uber.org/atomic
-# golang.org/x/net v0.0.0-20211123203042-d83791d6bcd9
+# golang.org/x/net v0.0.0-20211201190559-0a0e4e1bb54c
 ## explicit
 golang.org/x/net/context
 golang.org/x/net/context/ctxhttp
@@ -372,7 +373,7 @@ google.golang.org/appengine/internal/socket
 google.golang.org/appengine/internal/urlfetch
 google.golang.org/appengine/socket
 google.golang.org/appengine/urlfetch
-# google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1
+# google.golang.org/genproto v0.0.0-20211129164237-f09f9a12af12
 ## explicit
 google.golang.org/genproto/googleapis/api/annotations
 google.golang.org/genproto/googleapis/api/expr/v1alpha1


Test patch:
diff --git a/app/vmalert/config/config_test.go b/app/vmalert/config/config_test.go
index 8acdafb74..626baa75b 100644
--- a/app/vmalert/config/config_test.go
+++ b/app/vmalert/config/config_test.go
@@ -7,10 +7,11 @@ import (
 	"testing"
 	"time"
 
+	"gopkg.in/yaml.v2"
+
 	"github.com/VictoriaMetrics/VictoriaMetrics/app/vmalert/datasource"
 	"github.com/VictoriaMetrics/VictoriaMetrics/app/vmalert/notifier"
 	"github.com/VictoriaMetrics/VictoriaMetrics/app/vmalert/utils"
-	"gopkg.in/yaml.v2"
 )
 
 func TestMain(m *testing.M) {
@@ -474,4 +475,83 @@ rules:
     expr: sum by(job) (up == 1)
 `)
 	})
+
+	t.Run("`params` change", func(t *testing.T) {
+		f(t, `
+name: TestGroup
+params:
+    nocache: ["1"]
+rules:
+  - alert: foo
+    expr: sum by(job) (up == 1)
+`, `
+name: TestGroup
+params:
+    nocache: ["0"]
+rules:
+  - alert: foo
+    expr: sum by(job) (up == 1)
+`)
+	})
+}
+
+func TestGroupParams(t *testing.T) {
+	f := func(t *testing.T, data string, expParams url.Values) {
+		t.Helper()
+		var g Group
+		if err := yaml.Unmarshal([]byte(data), &g); err != nil {
+			t.Fatalf("failed to unmarshal: %s", err)
+		}
+		got, exp := g.Params.Encode(), expParams.Encode()
+		if got != exp {
+			t.Fatalf("expected to have %q; got %q", exp, got)
+		}
+	}
+
+	t.Run("no params", func(t *testing.T) {
+		f(t, `
+name: TestGroup
+rules:
+  - alert: ExampleAlertAlwaysFiring
+    expr: sum by(job) (up == 1)
+`, url.Values{})
+	})
+
+	t.Run("params", func(t *testing.T) {
+		f(t, `
+name: TestGroup
+params:
+  nocache: ["1"]
+  denyPartialResponse: ["true"]
+rules:
+  - alert: ExampleAlertAlwaysFiring
+    expr: sum by(job) (up == 1)
+`, url.Values{"nocache": {"1"}, "denyPartialResponse": {"true"}})
+	})
+
+	t.Run("extra labels", func(t *testing.T) {
+		f(t, `
+name: TestGroup
+extra_filter_labels:
+  job: victoriametrics
+  env: prod
+rules:
+  - alert: ExampleAlertAlwaysFiring
+    expr: sum by(job) (up == 1)
+`, url.Values{extraLabelParam: {"job=victoriametrics", "env=prod"}})
+	})
+
+	t.Run("extra labels and params", func(t *testing.T) {
+		f(t, `
+name: TestGroup
+extra_filter_labels:
+  job: victoriametrics
+params:
+  nocache: ["1"]
+  extra_label: ["env=prod"]
+rules:
+  - alert: ExampleAlertAlwaysFiring
+    expr: sum by(job) (up == 1)
+`, url.Values{"nocache": {"1"}, extraLabelParam: {"env=prod", "job=victoriametrics"}})
+	})
 }
diff --git a/app/vmalert/config/testdata/rules0-good.rules b/app/vmalert/config/testdata/rules0-good.rules
index 7d7df09b1..da170bef3 100644
--- a/app/vmalert/config/testdata/rules0-good.rules
+++ b/app/vmalert/config/testdata/rules0-good.rules
@@ -1,5 +1,8 @@
 groups:
   - name: groupGorSingleAlert
+    params:
+      nocache: ["1"]
+      denyPartialResponse: ["true"]
     rules:
       - alert: VMRows
         for: 10s
diff --git a/app/vmalert/config/testdata/rules2-good.rules b/app/vmalert/config/testdata/rules2-good.rules
index d1a1c4260..c307375ac 100644
--- a/app/vmalert/config/testdata/rules2-good.rules
+++ b/app/vmalert/config/testdata/rules2-good.rules
@@ -2,8 +2,11 @@ groups:
   - name: TestGroup
     interval: 2s
     concurrency: 2
-    extra_filter_labels:
+    extra_filter_labels: # deprecated param, use `params` instead
         job: victoriametrics
+    params:
+      denyPartialResponse: ["true"]
+      extra_label: ["env=dev"]
     rules:
       - alert: Conns
         expr: sum(vm_tcplistener_conns) by(instance) > 1
diff --git a/app/vmalert/datasource/vm_test.go b/app/vmalert/datasource/vm_test.go
index 946cedfe7..068cb6277 100644
--- a/app/vmalert/datasource/vm_test.go
+++ b/app/vmalert/datasource/vm_test.go
@@ -5,6 +5,7 @@ import (
 	"fmt"
 	"net/http"
 	"net/http/httptest"
+	"net/url"
 	"reflect"
 	"strconv"
 	"strings"
@@ -440,10 +441,10 @@ func TestRequestParams(t *testing.T) {
 			},
 		},
 		{
-			"round digits",
+			"prometheus extra params",
 			false,
 			&VMStorage{
-				extraParams: []Param{{"round_digits", "10"}},
+				extraParams: url.Values{"round_digits": {"10"}},
 			},
 			func(t *testing.T, r *http.Request) {
 				exp := fmt.Sprintf("query=%s&round_digits=10&time=%d", query, timestamp.Unix())
@@ -451,45 +452,32 @@ func TestRequestParams(t *testing.T) {
 			},
 		},
 		{
-			"extra labels",
-			false,
-			&VMStorage{
-				extraLabels: []string{
-					"env=prod",
-					"query=es=cape",
-				},
-			},
-			func(t *testing.T, r *http.Request) {
-				exp := fmt.Sprintf("extra_label=env%%3Dprod&extra_label=query%%3Des%%3Dcape&query=%s&time=%d", query, timestamp.Unix())
-				checkEqualString(t, exp, r.URL.RawQuery)
-			},
-		},
-		{
-			"extra labels range",
+			"prometheus extra params range",
 			true,
 			&VMStorage{
-				extraLabels: []string{
-					"env=prod",
-					"query=es=cape",
+				extraParams: url.Values{
+					"nocache":      {"1"},
+					"max_lookback": {"1h"},
 				},
 			},
 			func(t *testing.T, r *http.Request) {
-				exp := fmt.Sprintf("end=%d&extra_label=env%%3Dprod&extra_label=query%%3Des%%3Dcape&query=%s&start=%d",
+				exp := fmt.Sprintf("end=%d&max_lookback=1h&nocache=1&query=%s&start=%d",
 					timestamp.Unix(), query, timestamp.Unix())
 				checkEqualString(t, exp, r.URL.RawQuery)
 			},
 		},
 		{
-			"extra params",
+			"graphite extra params",
 			false,
 			&VMStorage{
-				extraParams: []Param{
-					{Key: "nocache", Value: "1"},
-					{Key: "max_lookback", Value: "1h"},
+				dataSourceType: NewGraphiteType(),
+				extraParams: url.Values{
+					"nocache":      {"1"},
+					"max_lookback": {"1h"},
 				},
 			},
 			func(t *testing.T, r *http.Request) {
-				exp := fmt.Sprintf("max_lookback=1h&nocache=1&query=%s&time=%d", query, timestamp.Unix())
+				exp := fmt.Sprintf("format=json&from=-5min&max_lookback=1h&nocache=1&target=%s&until=now", query)
 				checkEqualString(t, exp, r.URL.RawQuery)
 			},
 		},
@@ -519,7 +507,7 @@ func TestRequestParams(t *testing.T) {
 func checkEqualString(t *testing.T, exp, got string) {
 	t.Helper()
 	if got != exp {
-		t.Errorf("expected to get %q; got %q", exp, got)
+		t.Errorf("expected to get: \n%q; \ngot: \n%q", exp, got)
 	}
 }
 
diff --git a/lib/protoparser/graphite/parser_test.go b/lib/protoparser/graphite/parser_test.go
index da986ec2e..e2922548a 100644
--- a/lib/protoparser/graphite/parser_test.go
+++ b/lib/protoparser/graphite/parser_test.go
@@ -288,6 +288,31 @@ func TestRowsUnmarshalSuccess(t *testing.T) {
 		}},
 	})
 
+	// Whitespace after the timestamp
+	// See https://github.com/VictoriaMetrics/VictoriaMetrics/issues/1865
+	f("foo.baz 125 1789 \na 1.34 567\t  ", &Rows{
+		Rows: []Row{
+			{
+				Metric:    "foo.baz",
+				Value:     125,
+				Timestamp: 1789,
+			},
+			{
+				Metric:    "a",
+				Value:     1.34,
+				Timestamp: 567,
+			},
+		},
+	})
+
+	// Multiple whitespaces as separators
+	f("foo.baz \t125  1789 \t\n", &Rows{
+		Rows: []Row{{
+			Metric:    "foo.baz",
+			Value:     125,
+			Timestamp: 1789,
+		}},
+	})
 }
 
 func Test_streamContext_Read(t *testing.T) {