Repository: prometheus/prometheus
Pull request #12393 (2023-05-25 11:53:49)

Mark 2.45 as LTS
As the 2.37 LTS is going EOL in July 2023, let's mark 2.45 as LTS. I have synced with Jesus about this. He will bootstrap the release and after a few week I will do the maintenance for the lifetime of the LTS.

<!--
    Don't forget!

    - Please sign CNCF's Developer Certificate of Origin and sign-off your commits by adding the -s / --sign-off flag to `git commit`. See https://github.com/apps/dco for more information.

    - If the PR adds or changes a behaviour or fixes a bug of an exported API it would need a unit/e2e test.

    - Where possible use only exported APIs for tests to simplify the review and make it as close as possible to an actual library usage.

    - No tests are needed for internal implementation changes.

    - Performance improvements would need a benchmark test to prove it.

    - All exposed objects should have a comment.

    - All comments should start with a capital letter and end with a full stop.
 -->



Patch:
diff --git a/.github/workflows/buf-lint.yml b/.github/workflows/buf-lint.yml
index 79430ee56..3275d08fc 100644
--- a/.github/workflows/buf-lint.yml
+++ b/.github/workflows/buf-lint.yml
@@ -10,7 +10,7 @@ jobs:
     runs-on: ubuntu-latest
     steps:
       - uses: actions/checkout@v3
-      - uses: bufbuild/buf-setup-action@v1.17.0
+      - uses: bufbuild/buf-setup-action@v1.16.0
         with:
           github_token: ${{ secrets.GITHUB_TOKEN }}
       - uses: bufbuild/buf-lint-action@v1
diff --git a/.github/workflows/buf.yml b/.github/workflows/buf.yml
index 06e53172e..c80183b18 100644
--- a/.github/workflows/buf.yml
+++ b/.github/workflows/buf.yml
@@ -9,7 +9,7 @@ jobs:
     runs-on: ubuntu-latest
     steps:
       - uses: actions/checkout@v3
-      - uses: bufbuild/buf-setup-action@v1.17.0
+      - uses: bufbuild/buf-setup-action@v1.16.0
         with:
           github_token: ${{ secrets.GITHUB_TOKEN }}
       - uses: bufbuild/buf-lint-action@v1
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 7ff702215..f7dc32273 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -20,10 +20,6 @@ details about this code change see #10991.
 * [BUGFIX] TSDB: Block compaction failed when shutting down. #12179
 * [BUGFIX] TSDB: Out-of-order chunks could be ignored if the write-behind log was deleted. #12127
 
-## 2.43.1 / 2023-05-03
-
-* [BUGFIX] Labels: `Set()` after `Del()` would be ignored, which broke some relabeling rules. #12322
-
 ## 2.43.0 / 2023-03-21
 
 We are working on some performance improvements in Prometheus, which are only
@@ -37,7 +33,7 @@ the gains on their production architecture. We are providing release artefacts
 improvements for testing. #10991
 
 * [FEATURE] Promtool: Add HTTP client configuration to query commands. #11487
-* [FEATURE] Scrape: Add `scrape_config_files` to include scrape configs from different files. #12019
+* [FEATURE] Scrape: Add `include_scrape_configs` to include scrape configs from different files. #12019
 * [FEATURE] HTTP client: Add `no_proxy` to exclude URLs from proxied requests. #12098
 * [FEATURE] HTTP client: Add `proxy_from_enviroment` to read proxies from env variables. #12098
 * [ENHANCEMENT] API: Add support for setting lookback delta per query via the API. #12088
diff --git a/RELEASE.md b/RELEASE.md
index d7f24dabd..f5c907fe9 100644
--- a/RELEASE.md
+++ b/RELEASE.md
@@ -49,7 +49,7 @@ Release cadence of first pre-releases being cut is 6 weeks.
 | v2.42          | 2023-01-25                                 | Kemal Akkoyun (GitHub: @kakkoyun)           |
 | v2.43          | 2023-03-08                                 | Julien Pivotto (GitHub: @roidelapluie)      |
 | v2.44          | 2023-04-19                                 | Bryan Boreham (GitHub: @bboreham)           |
-| v2.45          | 2023-05-31                                 | Jesus Vazquez (Github: @jesusvazquez)       |
+| v2.45 LTS      | 2023-05-31                                 | Jesus Vazquez (Github: @jesusvazquez)       |
 | v2.46          | 2023-07-12                                 | **searching for volunteer**                 |
 
 If you are interested in volunteering please create a pull request against the [prometheus/prometheus](https://github.com/prometheus/prometheus) repository and propose yourself for the release series of your choice.
diff --git a/cmd/prometheus/main.go b/cmd/prometheus/main.go
index e05ac7957..778b131c8 100644
--- a/cmd/prometheus/main.go
+++ b/cmd/prometheus/main.go
@@ -1486,11 +1486,11 @@ func (s *readyStorage) Snapshot(dir string, withHead bool) error {
 }
 
 // Stats implements the api_v1.TSDBAdminStats interface.
-func (s *readyStorage) Stats(statsByLabelName string, limit int) (*tsdb.Stats, error) {
+func (s *readyStorage) Stats(statsByLabelName string) (*tsdb.Stats, error) {
 	if x := s.get(); x != nil {
 		switch db := x.(type) {
 		case *tsdb.DB:
-			return db.Head().Stats(statsByLabelName, limit), nil
+			return db.Head().Stats(statsByLabelName), nil
 		case *agent.DB:
 			return nil, agent.ErrUnsupported
 		default:
diff --git a/docs/querying/api.md b/docs/querying/api.md
index edce366ee..ef7fa54c6 100644
--- a/docs/querying/api.md
+++ b/docs/querying/api.md
@@ -1074,10 +1074,6 @@ The following endpoint returns various cardinality statistics about the Promethe
 ```
 GET /api/v1/status/tsdb
 ```
-URL query parameters:
-- `limit=<number>`: Limit the number of returned items to a given number for each set of statistics. By default, 10 items are returned.
-
-The `data` section of the query result consists of
 - **headStats**: This provides the following data about the head block of the TSDB:
   - **numSeries**: The number of series.
   - **chunkCount**: The number of chunks.
diff --git a/documentation/examples/remote_storage/go.mod b/documentation/examples/remote_storage/go.mod
index 1db3e9a9e..5e0e6ddb1 100644
--- a/documentation/examples/remote_storage/go.mod
+++ b/documentation/examples/remote_storage/go.mod
@@ -8,7 +8,7 @@ require (
 	github.com/gogo/protobuf v1.3.2
 	github.com/golang/snappy v0.0.4
 	github.com/influxdata/influxdb v1.11.0
-	github.com/prometheus/client_golang v1.15.0
+	github.com/prometheus/client_golang v1.14.0
 	github.com/prometheus/common v0.42.0
 	github.com/prometheus/prometheus v0.43.0
 	github.com/stretchr/testify v1.8.2
@@ -29,7 +29,7 @@ require (
 	github.com/grafana/regexp v0.0.0-20221122212121-6b5c0a4cb7fd // indirect
 	github.com/jmespath/go-jmespath v0.4.0 // indirect
 	github.com/jpillora/backoff v1.0.0 // indirect
-	github.com/kr/text v0.2.0 // indirect
+	github.com/kr/pretty v0.3.0 // indirect
 	github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
 	github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f // indirect
 	github.com/pkg/errors v0.9.1 // indirect
@@ -51,7 +51,7 @@ require (
 	golang.org/x/text v0.8.0 // indirect
 	golang.org/x/time v0.3.0 // indirect
 	google.golang.org/appengine v1.6.7 // indirect
-	google.golang.org/protobuf v1.30.0 // indirect
+	google.golang.org/protobuf v1.29.0 // indirect
 	gopkg.in/yaml.v2 v2.4.0 // indirect
 	gopkg.in/yaml.v3 v3.0.1 // indirect
 )
diff --git a/documentation/examples/remote_storage/go.sum b/documentation/examples/remote_storage/go.sum
index c4350e78b..11c294515 100644
--- a/documentation/examples/remote_storage/go.sum
+++ b/documentation/examples/remote_storage/go.sum
@@ -141,7 +141,8 @@ github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxv
 github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
 github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
 github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
-github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
+github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
+github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
 github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
 github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
 github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
@@ -180,8 +181,8 @@ github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXP
 github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
 github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
 github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0=
-github.com/prometheus/client_golang v1.15.0 h1:5fCgGYogn0hFdhyhLbw7hEsWxufKtY9klyvdNfFlFhM=
-github.com/prometheus/client_golang v1.15.0/go.mod h1:e9yaBhRPU2pPNsZwE+JdQl0KEt1N9XgF6zxWmaC0xOk=
+github.com/prometheus/client_golang v1.14.0 h1:nJdhIvne2eSX/XRAFV9PcvFFRbrjbcTUj0VP62TMhnw=
+github.com/prometheus/client_golang v1.14.0/go.mod h1:8vpkKitgIVNcqrRBWh1C4TIUQgYNtG/XQE4E/Zae36Y=
 github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
 github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
 github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
@@ -203,6 +204,7 @@ github.com/prometheus/procfs v0.9.0 h1:wzCHvIvM5SxWqYvwgVL7yJY8Lz3PKn49KQtpgMYJf
 github.com/prometheus/procfs v0.9.0/go.mod h1:+pB4zwohETzFnmlpe6yd2lSc+0/46IYZRB/chUwxUZY=
 github.com/prometheus/prometheus v0.43.0 h1:18iCSfrbAHbXvYFvR38U1Pt4uZmU9SmDcCpCrBKUiGg=
 github.com/prometheus/prometheus v0.43.0/go.mod h1:2BA14LgBeqlPuzObSEbh+Y+JwLH2GcqDlJKbF2sA6FM=
+github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
 github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
 github.com/scaleway/scaleway-sdk-go v1.0.0-beta.14 h1:yFl3jyaSVLNYXlnNYM5z2pagEk1dYQhfr1p20T1NyKY=
 github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
@@ -339,12 +341,14 @@ google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzi
 google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
 google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
 google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
-google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng=
-google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
+google.golang.org/protobuf v1.29.0 h1:44S3JjaKmLEE4YIkjzexaP+NzZsudE3Zin5Njn/pYX0=
+google.golang.org/protobuf v1.29.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
 gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
+gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
 gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
 gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
 gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
diff --git a/go.mod b/go.mod
index c90285438..7b309b03f 100644
--- a/go.mod
+++ b/go.mod
@@ -11,7 +11,7 @@ require (
 	github.com/aws/aws-sdk-go v1.44.245
 	github.com/cespare/xxhash/v2 v2.2.0
 	github.com/dennwc/varint v1.0.0
-	github.com/digitalocean/godo v1.99.0
+	github.com/digitalocean/godo v1.98.0
 	github.com/docker/docker v23.0.4+incompatible
 	github.com/edsrzf/mmap-go v1.1.0
 	github.com/envoyproxy/go-control-plane v0.11.0
@@ -29,7 +29,7 @@ require (
 	github.com/grpc-ecosystem/grpc-gateway v1.16.0
 	github.com/hashicorp/consul/api v1.20.0
 	github.com/hashicorp/nomad/api v0.0.0-20230418003350-3067191c5197
-	github.com/hetznercloud/hcloud-go v1.45.1
+	github.com/hetznercloud/hcloud-go v1.42.0
 	github.com/ionos-cloud/sdk-go/v6 v6.1.6
 	github.com/json-iterator/go v1.1.12
 	github.com/kolo/xmlrpc v0.0.0-20220921171641-a4b6fa1dd06b
@@ -41,7 +41,7 @@ require (
 	github.com/ovh/go-ovh v1.4.1
 	github.com/pkg/errors v0.9.1
 	github.com/prometheus/alertmanager v0.25.0
-	github.com/prometheus/client_golang v1.15.1
+	github.com/prometheus/client_golang v1.15.0
 	github.com/prometheus/client_model v0.3.0
 	github.com/prometheus/common v0.42.0
 	github.com/prometheus/common/assets v0.2.0
diff --git a/go.sum b/go.sum
index 9ecc5c727..c699aa9df 100644
--- a/go.sum
+++ b/go.sum
@@ -149,8 +149,8 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
 github.com/dennwc/varint v1.0.0 h1:kGNFFSSw8ToIy3obO/kKr8U9GZYUAxQEVuix4zfDWzE=
 github.com/dennwc/varint v1.0.0/go.mod h1:hnItb35rvZvJrbTALZtY/iQfDs48JKRG1RPpgziApxA=
 github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
-github.com/digitalocean/godo v1.99.0 h1:gUHO7n9bDaZFWvbzOum4bXE0/09ZuYA9yA8idQHX57E=
-github.com/digitalocean/godo v1.99.0/go.mod h1:SsS2oXo2rznfM/nORlZ/6JaUJZFhmKTib1YhopUc8NA=
+github.com/digitalocean/godo v1.98.0 h1:potyC1eD0N9n5/P4/WmJuKgg+OGYZOBWEW+/aKTX6QQ=
+github.com/digitalocean/godo v1.98.0/go.mod h1:NRpFznZFvhHjBoqZAaOD3khVzsJ3EibzKqFL4R60dmA=
 github.com/dnaeon/go-vcr v1.2.0 h1:zHCHvJYTMh1N7xnV7zf1m1GPBF9Ad0Jk/whtQ1663qI=
 github.com/docker/distribution v2.8.1+incompatible h1:Q50tZOPR6T/hjNsyc9g8/syEs6bk8XXApsHjKukMl68=
 github.com/docker/distribution v2.8.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
@@ -456,8 +456,8 @@ github.com/hashicorp/nomad/api v0.0.0-20230418003350-3067191c5197/go.mod h1:2TCr
 github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc=
 github.com/hashicorp/serf v0.10.1 h1:Z1H2J60yRKvfDYAOZLd2MU0ND4AH/WDz7xYHDWQsIPY=
 github.com/hashicorp/serf v0.10.1/go.mod h1:yL2t6BqATOLGc5HF7qbFkTfXoPIY0WZdWHfEvMqbG+4=
-github.com/hetznercloud/hcloud-go v1.45.1 h1:nl0OOklFfQT5J6AaNIOhl5Ruh3fhmGmhvZEqHbibVuk=
-github.com/hetznercloud/hcloud-go v1.45.1/go.mod h1:aAUGxSfSnB8/lVXHNEDxtCT1jykaul8kqjD7f5KQXF8=
+github.com/hetznercloud/hcloud-go v1.42.0 h1:Es/CDOForQN3nOOP5Vxh1N/YHjpCg386iYEX5zCgi+A=
+github.com/hetznercloud/hcloud-go v1.42.0/go.mod h1:YADL8AbmQYH0Eo+1lkuyoc8LutT0UeMvaKP47nNUb+Y=
 github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
 github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg=
 github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
@@ -647,8 +647,8 @@ github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeD
 github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU=
 github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
 github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0=
-github.com/prometheus/client_golang v1.15.1 h1:8tXpTmJbyH5lydzFPoxSIJ0J46jdh3tylbvM1xCv0LI=
-github.com/prometheus/client_golang v1.15.1/go.mod h1:e9yaBhRPU2pPNsZwE+JdQl0KEt1N9XgF6zxWmaC0xOk=
+github.com/prometheus/client_golang v1.15.0 h1:5fCgGYogn0hFdhyhLbw7hEsWxufKtY9klyvdNfFlFhM=
+github.com/prometheus/client_golang v1.15.0/go.mod h1:e9yaBhRPU2pPNsZwE+JdQl0KEt1N9XgF6zxWmaC0xOk=
 github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
 github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
 github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
diff --git a/scrape/manager.go b/scrape/manager.go
index d7cf6792c..d75fe30cf 100644
--- a/scrape/manager.go
+++ b/scrape/manager.go
@@ -150,7 +150,7 @@ type Manager struct {
 	append    storage.Appendable
 	graceShut chan struct{}
 
-	offsetSeed    uint64     // Global offsetSeed seed is used to spread scrape workload across HA setup.
+	jitterSeed    uint64     // Global jitterSeed seed is used to spread scrape workload across HA setup.
 	mtxScrape     sync.Mutex // Guards the fields below.
 	scrapeConfigs map[string]*config.ScrapeConfig
 	scrapePools   map[string]*scrapePool
@@ -214,7 +214,7 @@ func (m *Manager) reload() {
 				level.Error(m.logger).Log("msg", "error reloading target set", "err", "invalid config id:"+setName)
 				continue
 			}
-			sp, err := newScrapePool(scrapeConfig, m.append, m.offsetSeed, log.With(m.logger, "scrape_pool", setName), m.opts)
+			sp, err := newScrapePool(scrapeConfig, m.append, m.jitterSeed, log.With(m.logger, "scrape_pool", setName), m.opts)
 			if err != nil {
 				level.Error(m.logger).Log("msg", "error creating new scrape pool", "err", err, "scrape_pool", setName)
 				continue
@@ -234,8 +234,8 @@ func (m *Manager) reload() {
 	wg.Wait()
 }
 
-// setOffsetSeed calculates a global offsetSeed per server relying on extra label set.
-func (m *Manager) setOffsetSeed(labels labels.Labels) error {
+// setJitterSeed calculates a global jitterSeed per server relying on extra label set.
+func (m *Manager) setJitterSeed(labels labels.Labels) error {
 	h := fnv.New64a()
 	hostname, err := osutil.GetFQDN()
 	if err != nil {
@@ -244,7 +244,7 @@ func (m *Manager) setOffsetSeed(labels labels.Labels) error {
 	if _, err := fmt.Fprintf(h, "%s%s", hostname, labels.String()); err != nil {
 		return err
 	}
-	m.offsetSeed = h.Sum64()
+	m.jitterSeed = h.Sum64()
 	return nil
 }
 
@@ -281,7 +281,7 @@ func (m *Manager) ApplyConfig(cfg *config.Config) error {
 	}
 	m.scrapeConfigs = c
 
-	if err := m.setOffsetSeed(cfg.GlobalConfig.ExternalLabels); err != nil {
+	if err := m.setJitterSeed(cfg.GlobalConfig.ExternalLabels); err != nil {
 		return err
 	}
 
diff --git a/scrape/scrape.go b/scrape/scrape.go
index 8c4cc51e7..a97cbf539 100644
--- a/scrape/scrape.go
+++ b/scrape/scrape.go
@@ -279,7 +279,7 @@ const maxAheadTime = 10 * time.Minute
 // returning an empty label set is interpreted as "drop"
 type labelsMutator func(labels.Labels) labels.Labels
 
-func newScrapePool(cfg *config.ScrapeConfig, app storage.Appendable, offsetSeed uint64, logger log.Logger, options *Options) (*scrapePool, error) {
+func newScrapePool(cfg *config.ScrapeConfig, app storage.Appendable, jitterSeed uint64, logger log.Logger, options *Options) (*scrapePool, error) {
 	targetScrapePools.Inc()
 	if logger == nil {
 		logger = log.NewNopLogger()
@@ -325,7 +325,7 @@ func newScrapePool(cfg *config.ScrapeConfig, app storage.Appendable, offsetSeed
 			func(l labels.Labels) labels.Labels { return mutateReportSampleLabels(l, opts.target) },
 			func(ctx context.Context) storage.Appender { return app.Appender(ctx) },
 			cache,
-			offsetSeed,
+			jitterSeed,
 			opts.honorTimestamps,
 			opts.sampleLimit,
 			opts.bucketLimit,
@@ -775,7 +775,7 @@ func appender(app storage.Appender, sampleLimit, bucketLimit int) storage.Append
 type scraper interface {
 	scrape(ctx context.Context, w io.Writer) (string, error)
 	Report(start time.Time, dur time.Duration, err error)
-	offset(interval time.Duration, offsetSeed uint64) time.Duration
+	offset(interval time.Duration, jitterSeed uint64) time.Duration
 }
 
 // targetScraper implements the scraper interface for a target.
@@ -891,7 +891,7 @@ type scrapeLoop struct {
 	cache                   *scrapeCache
 	lastScrapeSize          int
 	buffers                 *pool.Pool
-	offsetSeed              uint64
+	jitterSeed              uint64
 	honorTimestamps         bool
 	forcedErr               error
 	forcedErrMtx            sync.Mutex
@@ -1175,7 +1175,7 @@ func newScrapeLoop(ctx context.Context,
 	reportSampleMutator labelsMutator,
 	appender func(ctx context.Context) storage.Appender,
 	cache *scrapeCache,
-	offsetSeed uint64,
+	jitterSeed uint64,
 	honorTimestamps bool,
 	sampleLimit int,
 	bucketLimit int,
@@ -1217,7 +1217,7 @@ func newScrapeLoop(ctx context.Context,
 		sampleMutator:           sampleMutator,
 		reportSampleMutator:     reportSampleMutator,
 		stopped:                 make(chan struct{}),
-		offsetSeed:              offsetSeed,
+		jitterSeed:              jitterSeed,
 		l:                       l,
 		parentCtx:               ctx,
 		appenderCtx:             appenderCtx,
@@ -1238,7 +1238,7 @@ func newScrapeLoop(ctx context.Context,
 
 func (sl *scrapeLoop) run(errc chan<- error) {
 	select {
-	case <-time.After(sl.scraper.offset(sl.interval, sl.offsetSeed)):
+	case <-time.After(sl.scraper.offset(sl.interval, sl.jitterSeed)):
 		// Continue after a scraping offset.
 	case <-sl.ctx.Done():
 		close(sl.stopped)
diff --git a/tsdb/db.go b/tsdb/db.go
index 12974150b..a0d0a4b26 100644
--- a/tsdb/db.go
+++ b/tsdb/db.go
@@ -640,9 +640,6 @@ func validateOpts(opts *Options, rngs []int64) (*Options, []int64) {
 	if opts.HeadChunksWriteQueueSize < 0 {
 		opts.HeadChunksWriteQueueSize = chunks.DefaultWriteQueueSize
 	}
-	if opts.SamplesPerChunk <= 0 {
-		opts.SamplesPerChunk = DefaultSamplesPerChunk
-	}
 	if opts.MaxBlockChunkSegmentSize <= 0 {
 		opts.MaxBlockChunkSegmentSize = chunks.DefaultChunkSegmentSize
 	}
diff --git a/tsdb/head.go b/tsdb/head.go
index a1d61fd6a..aa7a3c125 100644
--- a/tsdb/head.go
+++ b/tsdb/head.go
@@ -978,7 +978,7 @@ func (h *Head) DisableNativeHistograms() {
 }
 
 // PostingsCardinalityStats returns top 10 highest cardinality stats By label and value names.
-func (h *Head) PostingsCardinalityStats(statsByLabelName string, limit int) *index.PostingsStats {
+func (h *Head) PostingsCardinalityStats(statsByLabelName string) *index.PostingsStats {
 	h.cardinalityMutex.Lock()
 	defer h.cardinalityMutex.Unlock()
 	currentTime := time.Duration(time.Now().Unix()) * time.Second
@@ -989,7 +989,7 @@ func (h *Head) PostingsCardinalityStats(statsByLabelName string, limit int) *ind
 	if h.cardinalityCache != nil {
 		return h.cardinalityCache
 	}
-	h.cardinalityCache = h.postings.Stats(statsByLabelName, limit)
+	h.cardinalityCache = h.postings.Stats(statsByLabelName)
 	h.lastPostingsStatsCall = time.Duration(time.Now().Unix()) * time.Second
 
 	return h.cardinalityCache
@@ -1329,12 +1329,12 @@ type Stats struct {
 
 // Stats returns important current HEAD statistics. Note that it is expensive to
 // calculate these.
-func (h *Head) Stats(statsByLabelName string, limit int) *Stats {
+func (h *Head) Stats(statsByLabelName string) *Stats {
 	return &Stats{
 		NumSeries:         h.NumSeries(),
 		MaxTime:           h.MaxTime(),
 		MinTime:           h.MinTime(),
-		IndexPostingStats: h.PostingsCardinalityStats(statsByLabelName, limit),
+		IndexPostingStats: h.PostingsCardinalityStats(statsByLabelName),
 	}
 }
 
@@ -1614,7 +1614,7 @@ func (h *Head) getOrCreate(hash uint64, lset labels.Labels) (*memSeries, bool, e
 
 func (h *Head) getOrCreateWithID(id chunks.HeadSeriesRef, hash uint64, lset labels.Labels) (*memSeries, bool, error) {
 	s, created, err := h.series.getOrSet(hash, lset, func() *memSeries {
-		return newMemSeries(lset, id, h.opts.IsolationDisabled)
+		return newMemSeries(lset, id, h.opts.IsolationDisabled, h.opts.SamplesPerChunk)
 	})
 	if err != nil {
 		return nil, false, err
@@ -1922,7 +1922,8 @@ type memSeries struct {
 
 	mmMaxTime int64 // Max time of any mmapped chunk, only used during WAL replay.
 
-	nextAt int64 // Timestamp at which to cut the next chunk.
+	samplesPerChunk int   // Target number of samples per chunk.
+	nextAt          int64 // Timestamp at which to cut the next chunk.
 
 	// We keep the last value here (in addition to appending it to the chunk) so we can check for duplicates.
 	lastValue float64
@@ -1950,11 +1951,12 @@ type memSeriesOOOFields struct {
 	firstOOOChunkID  chunks.HeadChunkID // HeadOOOChunkID for oooMmappedChunks[0].
 }
 
-func newMemSeries(lset labels.Labels, id chunks.HeadSeriesRef, isolationDisabled bool) *memSeries {
+func newMemSeries(lset labels.Labels, id chunks.HeadSeriesRef, isolationDisabled bool, samplesPerChunk int) *memSeries {
 	s := &memSeries{
-		lset:   lset,
-		ref:    id,
-		nextAt: math.MinInt64,
+		lset:            lset,
+		ref:             id,
+		nextAt:          math.MinInt64,
+		samplesPerChunk: samplesPerChunk,
 	}
 	if !isolationDisabled {
 		s.txs = newTxRing(4)
diff --git a/tsdb/head_append.go b/tsdb/head_append.go
index 44847dceb..060d32b7f 100644
--- a/tsdb/head_append.go
+++ b/tsdb/head_append.go
@@ -987,7 +987,7 @@ func (a *headAppender) Commit() (err error) {
 				samplesAppended--
 			}
 		default:
-			ok, chunkCreated = series.append(s.T, s.V, a.appendID, a.head.chunkDiskMapper, chunkRange, a.head.opts.SamplesPerChunk)
+			ok, chunkCreated = series.append(s.T, s.V, a.appendID, a.head.chunkDiskMapper, chunkRange)
 			if ok {
 				if s.T < inOrderMint {
 					inOrderMint = s.T
@@ -1016,7 +1016,7 @@ func (a *headAppender) Commit() (err error) {
 	for i, s := range a.histograms {
 		series = a.histogramSeries[i]
 		series.Lock()
-		ok, chunkCreated := series.appendHistogram(s.T, s.H, a.appendID, a.head.chunkDiskMapper, chunkRange, a.head.opts.SamplesPerChunk)
+		ok, chunkCreated := series.appendHistogram(s.T, s.H, a.appendID, a.head.chunkDiskMapper, chunkRange)
 		series.cleanupAppendIDsBelow(a.cleanupAppendIDsBelow)
 		series.pendingCommit = false
 		series.Unlock()
@@ -1042,7 +1042,7 @@ func (a *headAppender) Commit() (err error) {
 	for i, s := range a.floatHistograms {
 		series = a.floatHistogramSeries[i]
 		series.Lock()
-		ok, chunkCreated := series.appendFloatHistogram(s.T, s.FH, a.appendID, a.head.chunkDiskMapper, chunkRange, a.head.opts.SamplesPerChunk)
+		ok, chunkCreated := series.appendFloatHistogram(s.T, s.FH, a.appendID, a.head.chunkDiskMapper, chunkRange)
 		series.cleanupAppendIDsBelow(a.cleanupAppendIDsBelow)
 		series.pendingCommit = false
 		series.Unlock()
@@ -1122,8 +1122,8 @@ func (s *memSeries) insert(t int64, v float64, chunkDiskMapper *chunks.ChunkDisk
 // the appendID for isolation. (The appendID can be zero, which results in no
 // isolation for this append.)
 // It is unsafe to call this concurrently with s.iterator(...) without holding the series lock.
-func (s *memSeries) append(t int64, v float64, appendID uint64, chunkDiskMapper *chunks.ChunkDiskMapper, chunkRange int64, samplesPerChunk int) (sampleInOrder, chunkCreated bool) {
-	c, sampleInOrder, chunkCreated := s.appendPreprocessor(t, chunkenc.EncXOR, chunkDiskMapper, chunkRange, samplesPerChunk)
+func (s *memSeries) append(t int64, v float64, appendID uint64, chunkDiskMapper *chunks.ChunkDiskMapper, chunkRange int64) (sampleInOrder, chunkCreated bool) {
+	c, sampleInOrder, chunkCreated := s.appendPreprocessor(t, chunkenc.EncXOR, chunkDiskMapper, chunkRange)
 	if !sampleInOrder {
 		return sampleInOrder, chunkCreated
 	}
@@ -1144,7 +1144,7 @@ func (s *memSeries) append(t int64, v float64, appendID uint64, chunkDiskMapper
 
 // appendHistogram adds the histogram.
 // It is unsafe to call this concurrently with s.iterator(...) without holding the series lock.
-func (s *memSeries) appendHistogram(t int64, h *histogram.Histogram, appendID uint64, chunkDiskMapper *chunks.ChunkDiskMapper, chunkRange int64, samplesPerChunk int) (sampleInOrder, chunkCreated bool) {
+func (s *memSeries) appendHistogram(t int64, h *histogram.Histogram, appendID uint64, chunkDiskMapper *chunks.ChunkDiskMapper, chunkRange int64) (sampleInOrder, chunkCreated bool) {
 	// Head controls the execution of recoding, so that we own the proper
 	// chunk reference afterwards. We check for Appendable from appender before
 	// appendPreprocessor because in case it ends up creating a new chunk,
@@ -1157,7 +1157,7 @@ func (s *memSeries) appendHistogram(t int64, h *histogram.Histogram, appendID ui
 		pMergedSpans, nMergedSpans         []histogram.Span
 		okToAppend, counterReset, gauge    bool
 	)
-	c, sampleInOrder, chunkCreated := s.appendPreprocessor(t, chunkenc.EncHistogram, chunkDiskMapper, chunkRange, samplesPerChunk)
+	c, sampleInOrder, chunkCreated := s.appendPreprocessor(t, chunkenc.EncHistogram, chunkDiskMapper, chunkRange)
 	if !sampleInOrder {
 		return sampleInOrder, chunkCreated
 	}
@@ -1238,7 +1238,7 @@ func (s *memSeries) appendHistogram(t int64, h *histogram.Histogram, appendID ui
 
 // appendFloatHistogram adds the float histogram.
 // It is unsafe to call this concurrently with s.iterator(...) without holding the series lock.
-func (s *memSeries) appendFloatHistogram(t int64, fh *histogram.FloatHistogram, appendID uint64, chunkDiskMapper *chunks.ChunkDiskMapper, chunkRange int64, samplesPerChunk int) (sampleInOrder, chunkCreated bool) {
+func (s *memSeries) appendFloatHistogram(t int64, fh *histogram.FloatHistogram, appendID uint64, chunkDiskMapper *chunks.ChunkDiskMapper, chunkRange int64) (sampleInOrder, chunkCreated bool) {
 	// Head controls the execution of recoding, so that we own the proper
 	// chunk reference afterwards.  We check for Appendable from appender before
 	// appendPreprocessor because in case it ends up creating a new chunk,
@@ -1251,7 +1251,7 @@ func (s *memSeries) appendFloatHistogram(t int64, fh *histogram.FloatHistogram,
 		pMergedSpans, nMergedSpans         []histogram.Span
 		okToAppend, counterReset, gauge    bool
 	)
-	c, sampleInOrder, chunkCreated := s.appendPreprocessor(t, chunkenc.EncFloatHistogram, chunkDiskMapper, chunkRange, samplesPerChunk)
+	c, sampleInOrder, chunkCreated := s.appendPreprocessor(t, chunkenc.EncFloatHistogram, chunkDiskMapper, chunkRange)
 	if !sampleInOrder {
 		return sampleInOrder, chunkCreated
 	}
@@ -1334,7 +1334,7 @@ func (s *memSeries) appendFloatHistogram(t int64, fh *histogram.FloatHistogram,
 // It is unsafe to call this concurrently with s.iterator(...) without holding the series lock.
 // This should be called only when appending data.
 func (s *memSeries) appendPreprocessor(
-	t int64, e chunkenc.Encoding, chunkDiskMapper *chunks.ChunkDiskMapper, chunkRange int64, samplesPerChunk int,
+	t int64, e chunkenc.Encoding, chunkDiskMapper *chunks.ChunkDiskMapper, chunkRange int64,
 ) (c *memChunk, sampleInOrder, chunkCreated bool) {
 	c = s.head()
 
@@ -1372,7 +1372,7 @@ func (s *memSeries) appendPreprocessor(
 	// for this chunk that will try to make samples equally distributed within
 	// the remaining chunks in the current chunk range.
 	// At latest it must happen at the timestamp set when the chunk was cut.
-	if numSamples == samplesPerChunk/4 {
+	if numSamples == s.samplesPerChunk/4 {
 		s.nextAt = computeChunkEndTime(c.minTime, c.maxTime, s.nextAt)
 	}
 	// If numSamples > samplesPerChunk*2 then our previous prediction was invalid,
@@ -1380,7 +1380,7 @@ func (s *memSeries) appendPreprocessor(
 	// Since we assume that the rate is higher, we're being conservative and cutting at 2*samplesPerChunk
 	// as we expect more chunks to come.
 	// Note that next chunk will have its nextAt recalculated for the new rate.
-	if t >= s.nextAt || numSamples >= samplesPerChunk*2 {
+	if t >= s.nextAt || numSamples >= s.samplesPerChunk*2 {
 		c = s.cutNewHeadChunk(t, e, chunkDiskMapper, chunkRange)
 		chunkCreated = true
 	}
diff --git a/tsdb/head_read.go b/tsdb/head_read.go
index 0e6e005ea..9c546ab16 100644
--- a/tsdb/head_read.go
+++ b/tsdb/head_read.go
@@ -331,7 +331,7 @@ func (h *headChunkReader) chunk(meta chunks.Meta, copyLastChunk bool) (chunkenc.
 	}
 	s.Unlock()
 
-	return &safeHeadChunk{
+	return &safeChunk{
 		Chunk:    chk,
 		s:        s,
 		cid:      cid,
@@ -627,15 +627,15 @@ func (b boundedIterator) Seek(t int64) chunkenc.ValueType {
 	return b.Iterator.Seek(t)
 }
 
-// safeHeadChunk makes sure that the chunk can be accessed without a race condition
-type safeHeadChunk struct {
+// safeChunk makes sure that the chunk can be accessed without a race condition
+type safeChunk struct {
 	chunkenc.Chunk
 	s        *memSeries
 	cid      chunks.HeadChunkID
 	isoState *isolationState
 }
 
-func (c *safeHeadChunk) Iterator(reuseIter chunkenc.Iterator) chunkenc.Iterator {
+func (c *safeChunk) Iterator(reuseIter chunkenc.Iterator) chunkenc.Iterator {
 	c.s.Lock()
 	it := c.s.iterator(c.cid, c.Chunk, c.isoState, reuseIter)
 	c.s.Unlock()
diff --git a/tsdb/head_wal.go b/tsdb/head_wal.go
index 9741d1da0..6e81f1793 100644
--- a/tsdb/head_wal.go
+++ b/tsdb/head_wal.go
@@ -588,7 +588,7 @@ func (wp *walSubsetProcessor) processWALSamples(h *Head, mmappedChunks, oooMmapp
 			if s.T <= ms.mmMaxTime {
 				continue
 			}
-			if _, chunkCreated := ms.append(s.T, s.V, 0, h.chunkDiskMapper, chunkRange, h.opts.SamplesPerChunk); chunkCreated {
+			if _, chunkCreated := ms.append(s.T, s.V, 0, h.chunkDiskMapper, chunkRange); chunkCreated {
 				h.metrics.chunksCreated.Inc()
 				h.metrics.chunks.Inc()
 			}
@@ -618,9 +618,9 @@ func (wp *walSubsetProcessor) processWALSamples(h *Head, mmappedChunks, oooMmapp
 			}
 			var chunkCreated bool
 			if s.h != nil {
-				_, chunkCreated = ms.appendHistogram(s.t, s.h, 0, h.chunkDiskMapper, chunkRange, h.opts.SamplesPerChunk)
+				_, chunkCreated = ms.appendHistogram(s.t, s.h, 0, h.chunkDiskMapper, chunkRange)
 			} else {
-				_, chunkCreated = ms.appendFloatHistogram(s.t, s.fh, 0, h.chunkDiskMapper, chunkRange, h.opts.SamplesPerChunk)
+				_, chunkCreated = ms.appendFloatHistogram(s.t, s.fh, 0, h.chunkDiskMapper, chunkRange)
 			}
 			if chunkCreated {
 				h.metrics.chunksCreated.Inc()
diff --git a/tsdb/index/postings.go b/tsdb/index/postings.go
index 2ac6edbdc..b93d3a202 100644
--- a/tsdb/index/postings.go
+++ b/tsdb/index/postings.go
@@ -156,8 +156,10 @@ type PostingsStats struct {
 }
 
 // Stats calculates the cardinality statistics from postings.
-func (p *MemPostings) Stats(label string, limit int) *PostingsStats {
+func (p *MemPostings) Stats(label string) *PostingsStats {
+	const maxNumOfRecords = 10
 	var size uint64
+
 	p.mtx.RLock()
 
 	metrics := &maxHeap{}
@@ -166,10 +168,10 @@ func (p *MemPostings) Stats(label string, limit int) *PostingsStats {
 	labelValuePairs := &maxHeap{}
 	numLabelPairs := 0
 
-	metrics.init(limit)
-	labels.init(limit)
-	labelValueLength.init(limit)
-	labelValuePairs.init(limit)
+	metrics.init(maxNumOfRecords)
+	labels.init(maxNumOfRecords)
+	labelValueLength.init(maxNumOfRecords)
+	labelValuePairs.init(maxNumOfRecords)
 
 	for n, e := range p.m {
 		if n == "" {
@@ -182,9 +184,8 @@ func (p *MemPostings) Stats(label string, limit int) *PostingsStats {
 			if n == label {
 				metrics.push(Stat{Name: name, Count: uint64(len(values))})
 			}
-			seriesCnt := uint64(len(values))
-			labelValuePairs.push(Stat{Name: n + "=" + name, Count: seriesCnt})
-			size += uint64(len(name)) * seriesCnt
+			labelValuePairs.push(Stat{Name: n + "=" + name, Count: uint64(len(values))})
+			size += uint64(len(name))
 		}
 		labelValueLength.push(Stat{Name: n, Count: size})
 	}
diff --git a/tsdb/querier.go b/tsdb/querier.go
index 9baf3f242..8b17bb745 100644
--- a/tsdb/querier.go
+++ b/tsdb/querier.go
@@ -361,22 +361,6 @@ func postingsForMatcher(ix IndexReader, m *labels.Matcher) (index.Postings, erro
 
 // inversePostingsForMatcher returns the postings for the series with the label name set but not matching the matcher.
 func inversePostingsForMatcher(ix IndexReader, m *labels.Matcher) (index.Postings, error) {
-	// Fast-path for MatchNotRegexp matching.
-	// Inverse of a MatchNotRegexp is MatchRegexp (double negation).
-	// Fast-path for set matching.
-	if m.Type == labels.MatchNotRegexp {
-		setMatches := findSetMatches(m.GetRegexString())
-		if len(setMatches) > 0 {
-			return ix.Postings(m.Name, setMatches...)
-		}
-	}
-
-	// Fast-path for MatchNotEqual matching.
-	// Inverse of a MatchNotEqual is MatchEqual (double negation).
-	if m.Type == labels.MatchNotEqual {
-		return ix.Postings(m.Name, m.Value)
-	}
-
 	vals, err := ix.LabelValues(m.Name)
 	if err != nil {
 		return nil, err
@@ -387,6 +371,14 @@ func inversePostingsForMatcher(ix IndexReader, m *labels.Matcher) (index.Posting
 	if m.Type == labels.MatchEqual && m.Value == "" {
 		res = vals
 	} else {
+		// Inverse of a MatchNotRegexp is MatchRegexp (double negation).
+		// Fast-path for set matching.
+		if m.Type == labels.MatchNotRegexp {
+			setMatches := findSetMatches(m.GetRegexString())
+			if len(setMatches) > 0 {
+				return ix.Postings(m.Name, setMatches...)
+			}
+		}
 		for _, val := range vals {
 			if !m.Matches(val) {
 				res = append(res, val)
@@ -793,35 +785,14 @@ func (p *populateWithDelChunkSeriesIterator) Next() bool {
 		if app, err = newChunk.Appender(); err != nil {
 			break
 		}
-
-		switch hc := p.currChkMeta.Chunk.(type) {
-		case *chunkenc.HistogramChunk:
+		if hc, ok := p.currChkMeta.Chunk.(*chunkenc.HistogramChunk); ok {
 			newChunk.(*chunkenc.HistogramChunk).SetCounterResetHeader(hc.GetCounterResetHeader())
-		case *safeHeadChunk:
-			if unwrapped, ok := hc.Chunk.(*chunkenc.HistogramChunk); ok {
-				newChunk.(*chunkenc.HistogramChunk).SetCounterResetHeader(unwrapped.GetCounterResetHeader())
-			} else {
-				err = fmt.Errorf("internal error, could not unwrap safeHeadChunk to histogram chunk: %T", hc.Chunk)
-			}
-		default:
-			err = fmt.Errorf("internal error, unknown chunk type %T when expecting histogram", p.currChkMeta.Chunk)
 		}
-		if err != nil {
-			break
-		}
-
 		var h *histogram.Histogram
 		t, h = p.currDelIter.AtHistogram()
 		p.curr.MinTime = t
 
-		// Detect missing gauge reset hint.
-		if h.CounterResetHint == histogram.GaugeType && newChunk.(*chunkenc.HistogramChunk).GetCounterResetHeader() != chunkenc.GaugeType {
-			err = fmt.Errorf("found gauge histogram in non gauge chunk")
-			break
-		}
-
 		app.AppendHistogram(t, h)
-
 		for vt := p.currDelIter.Next(); vt != chunkenc.ValNone; vt = p.currDelIter.Next() {
 			if vt != chunkenc.ValHistogram {
 				err = fmt.Errorf("found value type %v in histogram chunk", vt)
@@ -830,37 +801,23 @@ func (p *populateWithDelChunkSeriesIterator) Next() bool {
 			t, h = p.currDelIter.AtHistogram()
 
 			// Defend against corrupted chunks.
-			if h.CounterResetHint == histogram.GaugeType {
-				pI, nI, bpI, bnI, _, _, okToAppend := app.(*chunkenc.HistogramAppender).AppendableGauge(h)
-				if !okToAppend {
-					err = errors.New("unable to append histogram due to unexpected schema change")
-					break
-				}
-				if len(pI)+len(nI)+len(bpI)+len(bnI) > 0 {
-					err = fmt.Errorf(
-						"bucket layout has changed unexpectedly: forward %d positive, %d negative, backward %d positive %d negative bucket interjections required",
-						len(pI), len(nI), len(bpI), len(bnI),
-					)
-					break
-				}
-			} else {
-				pI, nI, okToAppend, counterReset := app.(*chunkenc.HistogramAppender).Appendable(h)
-				if len(pI)+len(nI) > 0 {
-					err = fmt.Errorf(
-						"bucket layout has changed unexpectedly: %d positive and %d negative bucket interjections required",
-						len(pI), len(nI),
-					)
-					break
-				}
-				if counterReset {
-					err = errors.New("detected unexpected counter reset in histogram")
-					break
-				}
-				if !okToAppend {
-					err = errors.New("unable to append histogram due to unexpected schema change")
-					break
-				}
+			pI, nI, okToAppend, counterReset := app.(*chunkenc.HistogramAppender).Appendable(h)
+			if len(pI)+len(nI) > 0 {
+				err = fmt.Errorf(
+					"bucket layout has changed unexpectedly: %d positive and %d negative bucket interjections required",
+					len(pI), len(nI),
+				)
+				break
+			}
+			if counterReset {
+				err = errors.New("detected unexpected counter reset in histogram")
+				break
 			}
+			if !okToAppend {
+				err = errors.New("unable to append histogram due to unexpected schema change")
+				break
+			}
+
 			app.AppendHistogram(t, h)
 		}
 	case chunkenc.ValFloat:
@@ -885,35 +842,14 @@ func (p *populateWithDelChunkSeriesIterator) Next() bool {
 		if app, err = newChunk.Appender(); err != nil {
 			break
 		}
-
-		switch hc := p.currChkMeta.Chunk.(type) {
-		case *chunkenc.FloatHistogramChunk:
+		if hc, ok := p.currChkMeta.Chunk.(*chunkenc.FloatHistogramChunk); ok {
 			newChunk.(*chunkenc.FloatHistogramChunk).SetCounterResetHeader(hc.GetCounterResetHeader())
-		case *safeHeadChunk:
-			if unwrapped, ok := hc.Chunk.(*chunkenc.FloatHistogramChunk); ok {
-				newChunk.(*chunkenc.FloatHistogramChunk).SetCounterResetHeader(unwrapped.GetCounterResetHeader())
-			} else {
-				err = fmt.Errorf("internal error, could not unwrap safeHeadChunk to float histogram chunk: %T", hc.Chunk)
-			}
-		default:
-			err = fmt.Errorf("internal error, unknown chunk type %T when expecting float histogram", p.currChkMeta.Chunk)
-		}
-		if err != nil {
-			break
 		}
-
 		var h *histogram.FloatHistogram
 		t, h = p.currDelIter.AtFloatHistogram()
 		p.curr.MinTime = t
 
-		// Detect missing gauge reset hint.
-		if h.CounterResetHint == histogram.GaugeType && newChunk.(*chunkenc.FloatHistogramChunk).GetCounterResetHeader() != chunkenc.GaugeType {
-			err = fmt.Errorf("found float gauge histogram in non gauge chunk")
-			break
-		}
-
 		app.AppendFloatHistogram(t, h)
-
 		for vt := p.currDelIter.Next(); vt != chunkenc.ValNone; vt = p.currDelIter.Next() {
 			if vt != chunkenc.ValFloatHistogram {
 				err = fmt.Errorf("found value type %v in histogram chunk", vt)
@@ -922,36 +858,21 @@ func (p *populateWithDelChunkSeriesIterator) Next() bool {
 			t, h = p.currDelIter.AtFloatHistogram()
 
 			// Defend against corrupted chunks.
-			if h.CounterResetHint == histogram.GaugeType {
-				pI, nI, bpI, bnI, _, _, okToAppend := app.(*chunkenc.FloatHistogramAppender).AppendableGauge(h)
-				if !okToAppend {
-					err = errors.New("unable to append histogram due to unexpected schema change")
-					break
-				}
-				if len(pI)+len(nI)+len(bpI)+len(bnI) > 0 {
-					err = fmt.Errorf(
-						"bucket layout has changed unexpectedly: forward %d positive, %d negative, backward %d positive %d negative bucket interjections required",
-						len(pI), len(nI), len(bpI), len(bnI),
-					)
-					break
-				}
-			} else {
-				pI, nI, okToAppend, counterReset := app.(*chunkenc.FloatHistogramAppender).Appendable(h)
-				if len(pI)+len(nI) > 0 {
-					err = fmt.Errorf(
-						"bucket layout has changed unexpectedly: %d positive and %d negative bucket interjections required",
-						len(pI), len(nI),
-					)
-					break
-				}
-				if counterReset {
-					err = errors.New("detected unexpected counter reset in histogram")
-					break
-				}
-				if !okToAppend {
-					err = errors.New("unable to append histogram due to unexpected schema change")
-					break
-				}
+			pI, nI, okToAppend, counterReset := app.(*chunkenc.FloatHistogramAppender).Appendable(h)
+			if len(pI)+len(nI) > 0 {
+				err = fmt.Errorf(
+					"bucket layout has changed unexpectedly: %d positive and %d negative bucket interjections required",
+					len(pI), len(nI),
+				)
+				break
+			}
+			if counterReset {
+				err = errors.New("detected unexpected counter reset in histogram")
+				break
+			}
+			if !okToAppend {
+				err = errors.New("unable to append histogram due to unexpected schema change")
+				break
 			}
 
 			app.AppendFloatHistogram(t, h)
diff --git a/tsdb/tombstones/tombstones.go b/tsdb/tombstones/tombstones.go
index 94daf5195..a52e1caa9 100644
--- a/tsdb/tombstones/tombstones.go
+++ b/tsdb/tombstones/tombstones.go
@@ -18,7 +18,6 @@ import (
 	"fmt"
 	"hash"
 	"hash/crc32"
-	"math"
 	"os"
 	"path/filepath"
 	"sort"
@@ -253,14 +252,7 @@ func NewTestMemTombstones(intervals []Intervals) *MemTombstones {
 func (t *MemTombstones) Get(ref storage.SeriesRef) (Intervals, error) {
 	t.mtx.RLock()
 	defer t.mtx.RUnlock()
-	intervals, ok := t.intvlGroups[ref]
-	if !ok {
-		return nil, nil
-	}
-	// Make a copy to avoid race.
-	res := make(Intervals, len(intervals))
-	copy(res, intervals)
-	return res, nil
+	return t.intvlGroups[ref], nil
 }
 
 func (t *MemTombstones) DeleteTombstones(refs map[storage.SeriesRef]struct{}) {
@@ -357,23 +349,17 @@ func (in Intervals) Add(n Interval) Intervals {
 	// Find min and max indexes of intervals that overlap with the new interval.
 	// Intervals are closed [t1, t2] and t is discreet, so if neighbour intervals are 1 step difference
 	// to the new one, we can merge those together.
-	mini := 0
-	if n.Mint != math.MinInt64 { // Avoid overflow.
-		mini = sort.Search(len(in), func(i int) bool { return in[i].Maxt >= n.Mint-1 })
-		if mini == len(in) {
-			return append(in, n)
-		}
+	mini := sort.Search(len(in), func(i int) bool { return in[i].Maxt >= n.Mint-1 })
+	if mini == len(in) {
+		return append(in, n)
 	}
 
-	maxi := len(in)
-	if n.Maxt != math.MaxInt64 { // Avoid overflow.
-		maxi = sort.Search(len(in)-mini, func(i int) bool { return in[mini+i].Mint > n.Maxt+1 })
-		if maxi == 0 {
-			if mini == 0 {
-				return append(Intervals{n}, in...)
-			}
-			return append(in[:mini], append(Intervals{n}, in[mini:]...)...)
+	maxi := sort.Search(len(in)-mini, func(i int) bool { return in[mini+i].Mint > n.Maxt+1 })
+	if maxi == 0 {
+		if mini == 0 {
+			return append(Intervals{n}, in...)
 		}
+		return append(in[:mini], append(Intervals{n}, in[mini:]...)...)
 	}
 
 	if n.Mint < in[mini].Mint {
diff --git a/tsdb/tsdbutil/chunks.go b/tsdb/tsdbutil/chunks.go
index 6e57016fe..02a7dd619 100644
--- a/tsdb/tsdbutil/chunks.go
+++ b/tsdb/tsdbutil/chunks.go
@@ -71,19 +71,9 @@ func ChunkFromSamplesGeneric(s Samples) chunks.Meta {
 		case chunkenc.ValFloat:
 			ca.Append(s.Get(i).T(), s.Get(i).F())
 		case chunkenc.ValHistogram:
-			h := s.Get(i).H()
-			ca.AppendHistogram(s.Get(i).T(), h)
-			if i == 0 && h.CounterResetHint == histogram.GaugeType {
-				hc := c.(*chunkenc.HistogramChunk)
-				hc.SetCounterResetHeader(chunkenc.GaugeType)
-			}
+			ca.AppendHistogram(s.Get(i).T(), s.Get(i).H())
 		case chunkenc.ValFloatHistogram:
-			fh := s.Get(i).FH()
-			ca.AppendFloatHistogram(s.Get(i).T(), fh)
-			if i == 0 && fh.CounterResetHint == histogram.GaugeType {
-				hc := c.(*chunkenc.FloatHistogramChunk)
-				hc.SetCounterResetHeader(chunkenc.GaugeType)
-			}
+			ca.AppendFloatHistogram(s.Get(i).T(), s.Get(i).FH())
 		default:
 			panic(fmt.Sprintf("unknown sample type %s", sampleType.String()))
 		}
diff --git a/tsdb/tsdbutil/histogram.go b/tsdb/tsdbutil/histogram.go
index 2145034e1..3c276c841 100644
--- a/tsdb/tsdbutil/histogram.go
+++ b/tsdb/tsdbutil/histogram.go
@@ -108,13 +108,3 @@ func GenerateTestGaugeFloatHistogram(i int) *histogram.FloatHistogram {
 	h.CounterResetHint = histogram.GaugeType
 	return h
 }
-
-func SetHistogramNotCounterReset(h *histogram.Histogram) *histogram.Histogram {
-	h.CounterResetHint = histogram.NotCounterReset
-	return h
-}
-
-func SetFloatHistogramNotCounterReset(h *histogram.FloatHistogram) *histogram.FloatHistogram {
-	h.CounterResetHint = histogram.NotCounterReset
-	return h
-}
diff --git a/web/api/v1/api.go b/web/api/v1/api.go
index f7249efb0..e1168e1a6 100644
--- a/web/api/v1/api.go
+++ b/web/api/v1/api.go
@@ -171,7 +171,7 @@ type TSDBAdminStats interface {
 	CleanTombstones() error
 	Delete(mint, maxt int64, ms ...*labels.Matcher) error
 	Snapshot(dir string, withHead bool) error
-	Stats(statsByLabelName string, limit int) (*tsdb.Stats, error)
+	Stats(statsByLabelName string) (*tsdb.Stats, error)
 	WALReplayStatus() (tsdb.WALReplayStatus, error)
 }
 
@@ -1472,15 +1472,8 @@ func TSDBStatsFromIndexStats(stats []index.Stat) []TSDBStat {
 	return result
 }
 
-func (api *API) serveTSDBStatus(r *http.Request) apiFuncResult {
-	limit := 10
-	if s := r.FormValue("limit"); s != "" {
-		var err error
-		if limit, err = strconv.Atoi(s); err != nil || limit < 1 {
-			return apiFuncResult{nil, &apiError{errorBadData, errors.New("limit must be a positive number")}, nil, nil}
-		}
-	}
-	s, err := api.db.Stats(labels.MetricName, limit)
+func (api *API) serveTSDBStatus(*http.Request) apiFuncResult {
+	s, err := api.db.Stats(labels.MetricName)
 	if err != nil {
 		return apiFuncResult{nil, &apiError{errorInternal, err}, nil, nil}
 	}


Test patch:
diff --git a/scrape/manager_test.go b/scrape/manager_test.go
index 50f632013..d05d25fa2 100644
--- a/scrape/manager_test.go
+++ b/scrape/manager_test.go
@@ -596,7 +596,7 @@ func TestManagerTargetsUpdates(t *testing.T) {
 	}
 }
 
-func TestSetOffsetSeed(t *testing.T) {
+func TestSetJitter(t *testing.T) {
 	getConfig := func(prometheus string) *config.Config {
 		cfgText := `
 global:
@@ -617,24 +617,24 @@ global:
 
 	// Load the first config.
 	cfg1 := getConfig("ha1")
-	if err := scrapeManager.setOffsetSeed(cfg1.GlobalConfig.ExternalLabels); err != nil {
+	if err := scrapeManager.setJitterSeed(cfg1.GlobalConfig.ExternalLabels); err != nil {
 		t.Error(err)
 	}
-	offsetSeed1 := scrapeManager.offsetSeed
+	jitter1 := scrapeManager.jitterSeed
 
-	if offsetSeed1 == 0 {
-		t.Error("Offset seed has to be a hash of uint64")
+	if jitter1 == 0 {
+		t.Error("Jitter has to be a hash of uint64")
 	}
 
 	// Load the first config.
 	cfg2 := getConfig("ha2")
-	if err := scrapeManager.setOffsetSeed(cfg2.GlobalConfig.ExternalLabels); err != nil {
+	if err := scrapeManager.setJitterSeed(cfg2.GlobalConfig.ExternalLabels); err != nil {
 		t.Error(err)
 	}
-	offsetSeed2 := scrapeManager.offsetSeed
+	jitter2 := scrapeManager.jitterSeed
 
-	if offsetSeed1 == offsetSeed2 {
-		t.Error("Offset seed should not be the same on different set of external labels")
+	if jitter1 == jitter2 {
+		t.Error("Jitter should not be the same on different set of external labels")
 	}
 }
 
diff --git a/scrape/target_test.go b/scrape/target_test.go
index 4f0c840cd..12d3b5a4d 100644
--- a/scrape/target_test.go
+++ b/scrape/target_test.go
@@ -59,7 +59,7 @@ func TestTargetLabels(t *testing.T) {
 
 func TestTargetOffset(t *testing.T) {
 	interval := 10 * time.Second
-	offsetSeed := uint64(0)
+	jitter := uint64(0)
 
 	offsets := make([]time.Duration, 10000)
 
@@ -68,7 +68,7 @@ func TestTargetOffset(t *testing.T) {
 		target := newTestTarget("example.com:80", 0, labels.FromStrings(
 			"label", fmt.Sprintf("%d", i),
 		))
-		offsets[i] = target.offset(interval, offsetSeed)
+		offsets[i] = target.offset(interval, jitter)
 	}
 
 	// Put the offsets into buckets and validate that they are all
diff --git a/tsdb/head_test.go b/tsdb/head_test.go
index 14468e071..af3df378e 100644
--- a/tsdb/head_test.go
+++ b/tsdb/head_test.go
@@ -285,8 +285,8 @@ func BenchmarkLoadWAL(b *testing.B) {
 						require.NoError(b, err)
 						for k := 0; k < c.batches*c.seriesPerBatch; k++ {
 							// Create one mmapped chunk per series, with one sample at the given time.
-							s := newMemSeries(labels.Labels{}, chunks.HeadSeriesRef(k)*101, defaultIsolationDisabled)
-							s.append(c.mmappedChunkT, 42, 0, chunkDiskMapper, c.mmappedChunkT, DefaultSamplesPerChunk)
+							s := newMemSeries(labels.Labels{}, chunks.HeadSeriesRef(k)*101, defaultIsolationDisabled, DefaultSamplesPerChunk)
+							s.append(c.mmappedChunkT, 42, 0, chunkDiskMapper, c.mmappedChunkT)
 							s.mmapCurrentHeadChunk(chunkDiskMapper)
 						}
 						require.NoError(b, chunkDiskMapper.Close())
@@ -807,10 +807,10 @@ func TestMemSeries_truncateChunks(t *testing.T) {
 		},
 	}
 
-	s := newMemSeries(labels.FromStrings("a", "b"), 1, defaultIsolationDisabled)
+	s := newMemSeries(labels.FromStrings("a", "b"), 1, defaultIsolationDisabled, DefaultSamplesPerChunk)
 
 	for i := 0; i < 4000; i += 5 {
-		ok, _ := s.append(int64(i), float64(i), 0, chunkDiskMapper, chunkRange, DefaultSamplesPerChunk)
+		ok, _ := s.append(int64(i), float64(i), 0, chunkDiskMapper, chunkRange)
 		require.True(t, ok, "sample append failed")
 	}
 
@@ -1338,24 +1338,24 @@ func TestMemSeries_append(t *testing.T) {
 	}()
 	const chunkRange = 500
 
-	s := newMemSeries(labels.Labels{}, 1, defaultIsolationDisabled)
+	s := newMemSeries(labels.Labels{}, 1, defaultIsolationDisabled, DefaultSamplesPerChunk)
 
 	// Add first two samples at the very end of a chunk range and the next two
 	// on and after it.
 	// New chunk must correctly be cut at 1000.
-	ok, chunkCreated := s.append(998, 1, 0, chunkDiskMapper, chunkRange, DefaultSamplesPerChunk)
+	ok, chunkCreated := s.append(998, 1, 0, chunkDiskMapper, chunkRange)
 	require.True(t, ok, "append failed")
 	require.True(t, chunkCreated, "first sample created chunk")
 
-	ok, chunkCreated = s.append(999, 2, 0, chunkDiskMapper, chunkRange, DefaultSamplesPerChunk)
+	ok, chunkCreated = s.append(999, 2, 0, chunkDiskMapper, chunkRange)
 	require.True(t, ok, "append failed")
 	require.False(t, chunkCreated, "second sample should use same chunk")
 
-	ok, chunkCreated = s.append(1000, 3, 0, chunkDiskMapper, chunkRange, DefaultSamplesPerChunk)
+	ok, chunkCreated = s.append(1000, 3, 0, chunkDiskMapper, chunkRange)
 	require.True(t, ok, "append failed")
 	require.True(t, chunkCreated, "expected new chunk on boundary")
 
-	ok, chunkCreated = s.append(1001, 4, 0, chunkDiskMapper, chunkRange, DefaultSamplesPerChunk)
+	ok, chunkCreated = s.append(1001, 4, 0, chunkDiskMapper, chunkRange)
 	require.True(t, ok, "append failed")
 	require.False(t, chunkCreated, "second sample should use same chunk")
 
@@ -1368,7 +1368,7 @@ func TestMemSeries_append(t *testing.T) {
 	// Fill the range [1000,2000) with many samples. Intermediate chunks should be cut
 	// at approximately 120 samples per chunk.
 	for i := 1; i < 1000; i++ {
-		ok, _ := s.append(1001+int64(i), float64(i), 0, chunkDiskMapper, chunkRange, DefaultSamplesPerChunk)
+		ok, _ := s.append(1001+int64(i), float64(i), 0, chunkDiskMapper, chunkRange)
 		require.True(t, ok, "append failed")
 	}
 
@@ -1392,7 +1392,7 @@ func TestMemSeries_appendHistogram(t *testing.T) {
 	}()
 	chunkRange := int64(1000)
 
-	s := newMemSeries(labels.Labels{}, 1, defaultIsolationDisabled)
+	s := newMemSeries(labels.Labels{}, 1, defaultIsolationDisabled, DefaultSamplesPerChunk)
 
 	histograms := tsdbutil.GenerateTestHistograms(4)
 	histogramWithOneMoreBucket := histograms[3].Copy()
@@ -1404,19 +1404,19 @@ func TestMemSeries_appendHistogram(t *testing.T) {
 	// Add first two samples at the very end of a chunk range and the next two
 	// on and after it.
 	// New chunk must correctly be cut at 1000.
-	ok, chunkCreated := s.appendHistogram(998, histograms[0], 0, chunkDiskMapper, chunkRange, DefaultSamplesPerChunk)
+	ok, chunkCreated := s.appendHistogram(998, histograms[0], 0, chunkDiskMapper, chunkRange)
 	require.True(t, ok, "append failed")
 	require.True(t, chunkCreated, "first sample created chunk")
 
-	ok, chunkCreated = s.appendHistogram(999, histograms[1], 0, chunkDiskMapper, chunkRange, DefaultSamplesPerChunk)
+	ok, chunkCreated = s.appendHistogram(999, histograms[1], 0, chunkDiskMapper, chunkRange)
 	require.True(t, ok, "append failed")
 	require.False(t, chunkCreated, "second sample should use same chunk")
 
-	ok, chunkCreated = s.appendHistogram(1000, histograms[2], 0, chunkDiskMapper, chunkRange, DefaultSamplesPerChunk)
+	ok, chunkCreated = s.appendHistogram(1000, histograms[2], 0, chunkDiskMapper, chunkRange)
 	require.True(t, ok, "append failed")
 	require.True(t, chunkCreated, "expected new chunk on boundary")
 
-	ok, chunkCreated = s.appendHistogram(1001, histograms[3], 0, chunkDiskMapper, chunkRange, DefaultSamplesPerChunk)
+	ok, chunkCreated = s.appendHistogram(1001, histograms[3], 0, chunkDiskMapper, chunkRange)
 	require.True(t, ok, "append failed")
 	require.False(t, chunkCreated, "second sample should use same chunk")
 
@@ -1426,7 +1426,7 @@ func TestMemSeries_appendHistogram(t *testing.T) {
 	require.Equal(t, int64(1000), s.headChunk.minTime, "wrong chunk range")
 	require.Equal(t, int64(1001), s.headChunk.maxTime, "wrong chunk range")
 
-	ok, chunkCreated = s.appendHistogram(1002, histogramWithOneMoreBucket, 0, chunkDiskMapper, chunkRange, DefaultSamplesPerChunk)
+	ok, chunkCreated = s.appendHistogram(1002, histogramWithOneMoreBucket, 0, chunkDiskMapper, chunkRange)
 	require.True(t, ok, "append failed")
 	require.False(t, chunkCreated, "third sample should trigger a re-encoded chunk")
 
@@ -1448,7 +1448,7 @@ func TestMemSeries_append_atVariableRate(t *testing.T) {
 	})
 	chunkRange := DefaultBlockDuration
 
-	s := newMemSeries(labels.Labels{}, 1, defaultIsolationDisabled)
+	s := newMemSeries(labels.Labels{}, 1, defaultIsolationDisabled, DefaultSamplesPerChunk)
 
 	// At this slow rate, we will fill the chunk in two block durations.
 	slowRate := (DefaultBlockDuration * 2) / samplesPerChunk
@@ -1456,7 +1456,7 @@ func TestMemSeries_append_atVariableRate(t *testing.T) {
 	var nextTs int64
 	var totalAppendedSamples int
 	for i := 0; i < samplesPerChunk/4; i++ {
-		ok, _ := s.append(nextTs, float64(i), 0, chunkDiskMapper, chunkRange, DefaultSamplesPerChunk)
+		ok, _ := s.append(nextTs, float64(i), 0, chunkDiskMapper, chunkRange)
 		require.Truef(t, ok, "slow sample %d was not appended", i)
 		nextTs += slowRate
 		totalAppendedSamples++
@@ -1465,12 +1465,12 @@ func TestMemSeries_append_atVariableRate(t *testing.T) {
 
 	// Suddenly, the rate increases and we receive a sample every millisecond.
 	for i := 0; i < math.MaxUint16; i++ {
-		ok, _ := s.append(nextTs, float64(i), 0, chunkDiskMapper, chunkRange, DefaultSamplesPerChunk)
+		ok, _ := s.append(nextTs, float64(i), 0, chunkDiskMapper, chunkRange)
 		require.Truef(t, ok, "quick sample %d was not appended", i)
 		nextTs++
 		totalAppendedSamples++
 	}
-	ok, chunkCreated := s.append(DefaultBlockDuration, float64(0), 0, chunkDiskMapper, chunkRange, DefaultSamplesPerChunk)
+	ok, chunkCreated := s.append(DefaultBlockDuration, float64(0), 0, chunkDiskMapper, chunkRange)
 	require.True(t, ok, "new chunk sample was not appended")
 	require.True(t, chunkCreated, "sample at block duration timestamp should create a new chunk")
 
@@ -1495,18 +1495,18 @@ func TestGCChunkAccess(t *testing.T) {
 	s, _, _ := h.getOrCreate(1, labels.FromStrings("a", "1"))
 
 	// Appending 2 samples for the first chunk.
-	ok, chunkCreated := s.append(0, 0, 0, h.chunkDiskMapper, chunkRange, DefaultSamplesPerChunk)
+	ok, chunkCreated := s.append(0, 0, 0, h.chunkDiskMapper, chunkRange)
 	require.True(t, ok, "series append failed")
 	require.True(t, chunkCreated, "chunks was not created")
-	ok, chunkCreated = s.append(999, 999, 0, h.chunkDiskMapper, chunkRange, DefaultSamplesPerChunk)
+	ok, chunkCreated = s.append(999, 999, 0, h.chunkDiskMapper, chunkRange)
 	require.True(t, ok, "series append failed")
 	require.False(t, chunkCreated, "chunks was created")
 
 	// A new chunks should be created here as it's beyond the chunk range.
-	ok, chunkCreated = s.append(1000, 1000, 0, h.chunkDiskMapper, chunkRange, DefaultSamplesPerChunk)
+	ok, chunkCreated = s.append(1000, 1000, 0, h.chunkDiskMapper, chunkRange)
 	require.True(t, ok, "series append failed")
 	require.True(t, chunkCreated, "chunks was not created")
-	ok, chunkCreated = s.append(1999, 1999, 0, h.chunkDiskMapper, chunkRange, DefaultSamplesPerChunk)
+	ok, chunkCreated = s.append(1999, 1999, 0, h.chunkDiskMapper, chunkRange)
 	require.True(t, ok, "series append failed")
 	require.False(t, chunkCreated, "chunks was created")
 
@@ -1548,18 +1548,18 @@ func TestGCSeriesAccess(t *testing.T) {
 	s, _, _ := h.getOrCreate(1, labels.FromStrings("a", "1"))
 
 	// Appending 2 samples for the first chunk.
-	ok, chunkCreated := s.append(0, 0, 0, h.chunkDiskMapper, chunkRange, DefaultSamplesPerChunk)
+	ok, chunkCreated := s.append(0, 0, 0, h.chunkDiskMapper, chunkRange)
 	require.True(t, ok, "series append failed")
 	require.True(t, chunkCreated, "chunks was not created")
-	ok, chunkCreated = s.append(999, 999, 0, h.chunkDiskMapper, chunkRange, DefaultSamplesPerChunk)
+	ok, chunkCreated = s.append(999, 999, 0, h.chunkDiskMapper, chunkRange)
 	require.True(t, ok, "series append failed")
 	require.False(t, chunkCreated, "chunks was created")
 
 	// A new chunks should be created here as it's beyond the chunk range.
-	ok, chunkCreated = s.append(1000, 1000, 0, h.chunkDiskMapper, chunkRange, DefaultSamplesPerChunk)
+	ok, chunkCreated = s.append(1000, 1000, 0, h.chunkDiskMapper, chunkRange)
 	require.True(t, ok, "series append failed")
 	require.True(t, chunkCreated, "chunks was not created")
-	ok, chunkCreated = s.append(1999, 1999, 0, h.chunkDiskMapper, chunkRange, DefaultSamplesPerChunk)
+	ok, chunkCreated = s.append(1999, 1999, 0, h.chunkDiskMapper, chunkRange)
 	require.True(t, ok, "series append failed")
 	require.False(t, chunkCreated, "chunks was created")
 
@@ -1795,10 +1795,10 @@ func TestHeadReadWriterRepair(t *testing.T) {
 		require.True(t, created, "series was not created")
 
 		for i := 0; i < 7; i++ {
-			ok, chunkCreated := s.append(int64(i*chunkRange), float64(i*chunkRange), 0, h.chunkDiskMapper, chunkRange, DefaultSamplesPerChunk)
+			ok, chunkCreated := s.append(int64(i*chunkRange), float64(i*chunkRange), 0, h.chunkDiskMapper, chunkRange)
 			require.True(t, ok, "series append failed")
 			require.True(t, chunkCreated, "chunk was not created")
-			ok, chunkCreated = s.append(int64(i*chunkRange)+chunkRange-1, float64(i*chunkRange), 0, h.chunkDiskMapper, chunkRange, DefaultSamplesPerChunk)
+			ok, chunkCreated = s.append(int64(i*chunkRange)+chunkRange-1, float64(i*chunkRange), 0, h.chunkDiskMapper, chunkRange)
 			require.True(t, ok, "series append failed")
 			require.False(t, chunkCreated, "chunk was created")
 			h.chunkDiskMapper.CutNewFile()
@@ -2146,7 +2146,7 @@ func TestIsolationAppendIDZeroIsNoop(t *testing.T) {
 
 	s, _, _ := h.getOrCreate(1, labels.FromStrings("a", "1"))
 
-	ok, _ := s.append(0, 0, 0, h.chunkDiskMapper, h.chunkRange.Load(), DefaultSamplesPerChunk)
+	ok, _ := s.append(0, 0, 0, h.chunkDiskMapper, h.chunkRange.Load())
 	require.True(t, ok, "Series append failed.")
 	require.Equal(t, 0, s.txs.txIDCount, "Series should not have an appendID after append with appendID=0.")
 }
@@ -2610,10 +2610,10 @@ func TestIteratorSeekIntoBuffer(t *testing.T) {
 	}()
 	const chunkRange = 500
 
-	s := newMemSeries(labels.Labels{}, 1, defaultIsolationDisabled)
+	s := newMemSeries(labels.Labels{}, 1, defaultIsolationDisabled, DefaultSamplesPerChunk)
 
 	for i := 0; i < 7; i++ {
-		ok, _ := s.append(int64(i), float64(i), 0, chunkDiskMapper, chunkRange, DefaultSamplesPerChunk)
+		ok, _ := s.append(int64(i), float64(i), 0, chunkDiskMapper, chunkRange)
 		require.True(t, ok, "sample append failed")
 	}
 
diff --git a/tsdb/index/postings_test.go b/tsdb/index/postings_test.go
index 9454def46..a34f3c12d 100644
--- a/tsdb/index/postings_test.go
+++ b/tsdb/index/postings_test.go
@@ -912,39 +912,10 @@ func BenchmarkPostings_Stats(b *testing.B) {
 	}
 	b.ResetTimer()
 	for n := 0; n < b.N; n++ {
-		p.Stats("__name__", 10)
+		p.Stats("__name__")
 	}
 }
 
-func TestMemPostingsStats(t *testing.T) {
-	// create a new MemPostings
-	p := NewMemPostings()
-
-	// add some postings to the MemPostings
-	p.Add(1, labels.FromStrings("label", "value1"))
-	p.Add(1, labels.FromStrings("label", "value2"))
-	p.Add(1, labels.FromStrings("label", "value3"))
-	p.Add(2, labels.FromStrings("label", "value1"))
-
-	// call the Stats method to calculate the cardinality statistics
-	stats := p.Stats("label", 10)
-
-	// assert that the expected statistics were calculated
-	require.Equal(t, uint64(2), stats.CardinalityMetricsStats[0].Count)
-	require.Equal(t, "value1", stats.CardinalityMetricsStats[0].Name)
-
-	require.Equal(t, uint64(3), stats.CardinalityLabelStats[0].Count)
-	require.Equal(t, "label", stats.CardinalityLabelStats[0].Name)
-
-	require.Equal(t, uint64(24), stats.LabelValueStats[0].Count)
-	require.Equal(t, "label", stats.LabelValueStats[0].Name)
-
-	require.Equal(t, uint64(2), stats.LabelValuePairsStats[0].Count)
-	require.Equal(t, "label=value1", stats.LabelValuePairsStats[0].Name)
-
-	require.Equal(t, 3, stats.NumLabelPairs)
-}
-
 func TestMemPostings_Delete(t *testing.T) {
 	p := NewMemPostings()
 	p.Add(1, labels.FromStrings("lbl1", "a"))
diff --git a/tsdb/querier_bench_test.go b/tsdb/querier_bench_test.go
index 19619e35b..6e5243ef1 100644
--- a/tsdb/querier_bench_test.go
+++ b/tsdb/querier_bench_test.go
@@ -125,7 +125,6 @@ func benchmarkPostingsForMatchers(b *testing.B, ir IndexReader) {
 		{`n="X",j="foo"`, []*labels.Matcher{nX, jFoo}},
 		{`j="foo",n="1"`, []*labels.Matcher{jFoo, n1}},
 		{`n="1",j!="foo"`, []*labels.Matcher{n1, jNotFoo}},
-		{`n="1",i!="2"`, []*labels.Matcher{n1, iNot2}},
 		{`n="X",j!="foo"`, []*labels.Matcher{nX, jNotFoo}},
 		{`i=~"1[0-9]",j=~"foo|bar"`, []*labels.Matcher{iCharSet, jFooBar}},
 		{`j=~"foo|bar"`, []*labels.Matcher{jFooBar}},
diff --git a/tsdb/querier_test.go b/tsdb/querier_test.go
index 5bf721a62..9e17f5b8d 100644
--- a/tsdb/querier_test.go
+++ b/tsdb/querier_test.go
@@ -29,7 +29,6 @@ import (
 	"github.com/pkg/errors"
 	"github.com/stretchr/testify/require"
 
-	"github.com/prometheus/prometheus/model/histogram"
 	"github.com/prometheus/prometheus/model/labels"
 	"github.com/prometheus/prometheus/storage"
 	"github.com/prometheus/prometheus/tsdb/chunkenc"
@@ -502,46 +501,6 @@ func TestBlockQuerier_AgainstHeadWithOpenChunks(t *testing.T) {
 	}
 }
 
-func TestBlockQuerier_TrimmingDoesNotModifyOriginalTombstoneIntervals(t *testing.T) {
-	c := blockQuerierTestCase{
-		mint: 2,
-		maxt: 6,
-		ms:   []*labels.Matcher{labels.MustNewMatcher(labels.MatchRegexp, "a", "a")},
-		exp: newMockSeriesSet([]storage.Series{
-			storage.NewListSeries(labels.FromStrings("a", "a"),
-				[]tsdbutil.Sample{sample{3, 4, nil, nil}, sample{5, 2, nil, nil}, sample{6, 3, nil, nil}},
-			),
-			storage.NewListSeries(labels.FromStrings("a", "a", "b", "b"),
-				[]tsdbutil.Sample{sample{3, 3, nil, nil}, sample{5, 3, nil, nil}, sample{6, 6, nil, nil}},
-			),
-		}),
-		expChks: newMockChunkSeriesSet([]storage.ChunkSeries{
-			storage.NewListChunkSeriesFromSamples(labels.FromStrings("a", "a"),
-				[]tsdbutil.Sample{sample{3, 4, nil, nil}}, []tsdbutil.Sample{sample{5, 2, nil, nil}, sample{6, 3, nil, nil}},
-			),
-			storage.NewListChunkSeriesFromSamples(labels.FromStrings("a", "a", "b", "b"),
-				[]tsdbutil.Sample{sample{3, 3, nil, nil}}, []tsdbutil.Sample{sample{5, 3, nil, nil}, sample{6, 6, nil, nil}},
-			),
-		}),
-	}
-	ir, cr, _, _ := createIdxChkReaders(t, testData)
-	stones := tombstones.NewMemTombstones()
-	p, err := ir.Postings("a", "a")
-	require.NoError(t, err)
-	refs, err := index.ExpandPostings(p)
-	require.NoError(t, err)
-	for _, ref := range refs {
-		stones.AddInterval(ref, tombstones.Interval{Mint: 1, Maxt: 2})
-	}
-	testBlockQuerier(t, c, ir, cr, stones)
-	for _, ref := range refs {
-		intervals, err := stones.Get(ref)
-		require.NoError(t, err)
-		// Without copy, the intervals could be [math.MinInt64, 2].
-		require.Equal(t, tombstones.Intervals{{Mint: 1, Maxt: 2}}, intervals)
-	}
-}
-
 var testData = []seriesSamples{
 	{
 		lset: map[string]string{"a": "a"},
@@ -908,202 +867,6 @@ func TestPopulateWithTombSeriesIterators(t *testing.T) {
 				sample{3, 5, nil, nil}, sample{6, 1, nil, nil}, sample{7, 89, nil, nil},
 			},
 		},
-		{
-			name: "one histogram chunk",
-			chks: [][]tsdbutil.Sample{
-				{
-					sample{1, 0, tsdbutil.GenerateTestHistogram(1), nil},
-					sample{2, 0, tsdbutil.GenerateTestHistogram(2), nil},
-					sample{3, 0, tsdbutil.GenerateTestHistogram(3), nil},
-					sample{6, 0, tsdbutil.GenerateTestHistogram(6), nil},
-				},
-			},
-			expected: []tsdbutil.Sample{
-				sample{1, 0, tsdbutil.GenerateTestHistogram(1), nil},
-				sample{2, 0, tsdbutil.SetHistogramNotCounterReset(tsdbutil.GenerateTestHistogram(2)), nil},
-				sample{3, 0, tsdbutil.SetHistogramNotCounterReset(tsdbutil.GenerateTestHistogram(3)), nil},
-				sample{6, 0, tsdbutil.SetHistogramNotCounterReset(tsdbutil.GenerateTestHistogram(6)), nil},
-			},
-			expectedChks: []chunks.Meta{
-				tsdbutil.ChunkFromSamples([]tsdbutil.Sample{
-					sample{1, 0, tsdbutil.GenerateTestHistogram(1), nil},
-					sample{2, 0, tsdbutil.SetHistogramNotCounterReset(tsdbutil.GenerateTestHistogram(2)), nil},
-					sample{3, 0, tsdbutil.SetHistogramNotCounterReset(tsdbutil.GenerateTestHistogram(3)), nil},
-					sample{6, 0, tsdbutil.SetHistogramNotCounterReset(tsdbutil.GenerateTestHistogram(6)), nil},
-				}),
-			},
-		},
-		{
-			name: "one histogram chunk intersect with deletion interval",
-			chks: [][]tsdbutil.Sample{
-				{
-					sample{1, 0, tsdbutil.GenerateTestHistogram(1), nil},
-					sample{2, 0, tsdbutil.GenerateTestHistogram(2), nil},
-					sample{3, 0, tsdbutil.GenerateTestHistogram(3), nil},
-					sample{6, 0, tsdbutil.GenerateTestHistogram(6), nil},
-				},
-			},
-			intervals: tombstones.Intervals{{Mint: 5, Maxt: 20}},
-			expected: []tsdbutil.Sample{
-				sample{1, 0, tsdbutil.GenerateTestHistogram(1), nil},
-				sample{2, 0, tsdbutil.SetHistogramNotCounterReset(tsdbutil.GenerateTestHistogram(2)), nil},
-				sample{3, 0, tsdbutil.SetHistogramNotCounterReset(tsdbutil.GenerateTestHistogram(3)), nil},
-			},
-			expectedChks: []chunks.Meta{
-				tsdbutil.ChunkFromSamples([]tsdbutil.Sample{
-					sample{1, 0, tsdbutil.GenerateTestHistogram(1), nil},
-					sample{2, 0, tsdbutil.SetHistogramNotCounterReset(tsdbutil.GenerateTestHistogram(2)), nil},
-					sample{3, 0, tsdbutil.SetHistogramNotCounterReset(tsdbutil.GenerateTestHistogram(3)), nil},
-				}),
-			},
-		},
-		{
-			name: "one float histogram chunk",
-			chks: [][]tsdbutil.Sample{
-				{
-					sample{1, 0, nil, tsdbutil.GenerateTestFloatHistogram(1)},
-					sample{2, 0, nil, tsdbutil.GenerateTestFloatHistogram(2)},
-					sample{3, 0, nil, tsdbutil.GenerateTestFloatHistogram(3)},
-					sample{6, 0, nil, tsdbutil.GenerateTestFloatHistogram(6)},
-				},
-			},
-			expected: []tsdbutil.Sample{
-				sample{1, 0, nil, tsdbutil.GenerateTestFloatHistogram(1)},
-				sample{2, 0, nil, tsdbutil.SetFloatHistogramNotCounterReset(tsdbutil.GenerateTestFloatHistogram(2))},
-				sample{3, 0, nil, tsdbutil.SetFloatHistogramNotCounterReset(tsdbutil.GenerateTestFloatHistogram(3))},
-				sample{6, 0, nil, tsdbutil.SetFloatHistogramNotCounterReset(tsdbutil.GenerateTestFloatHistogram(6))},
-			},
-			expectedChks: []chunks.Meta{
-				tsdbutil.ChunkFromSamples([]tsdbutil.Sample{
-					sample{1, 0, nil, tsdbutil.GenerateTestFloatHistogram(1)},
-					sample{2, 0, nil, tsdbutil.SetFloatHistogramNotCounterReset(tsdbutil.GenerateTestFloatHistogram(2))},
-					sample{3, 0, nil, tsdbutil.SetFloatHistogramNotCounterReset(tsdbutil.GenerateTestFloatHistogram(3))},
-					sample{6, 0, nil, tsdbutil.SetFloatHistogramNotCounterReset(tsdbutil.GenerateTestFloatHistogram(6))},
-				}),
-			},
-		},
-		{
-			name: "one float histogram chunk intersect with deletion interval",
-			chks: [][]tsdbutil.Sample{
-				{
-					sample{1, 0, nil, tsdbutil.GenerateTestFloatHistogram(1)},
-					sample{2, 0, nil, tsdbutil.GenerateTestFloatHistogram(2)},
-					sample{3, 0, nil, tsdbutil.GenerateTestFloatHistogram(3)},
-					sample{6, 0, nil, tsdbutil.GenerateTestFloatHistogram(6)},
-				},
-			},
-			intervals: tombstones.Intervals{{Mint: 5, Maxt: 20}},
-			expected: []tsdbutil.Sample{
-				sample{1, 0, nil, tsdbutil.GenerateTestFloatHistogram(1)},
-				sample{2, 0, nil, tsdbutil.SetFloatHistogramNotCounterReset(tsdbutil.GenerateTestFloatHistogram(2))},
-				sample{3, 0, nil, tsdbutil.SetFloatHistogramNotCounterReset(tsdbutil.GenerateTestFloatHistogram(3))},
-			},
-			expectedChks: []chunks.Meta{
-				tsdbutil.ChunkFromSamples([]tsdbutil.Sample{
-					sample{1, 0, nil, tsdbutil.GenerateTestFloatHistogram(1)},
-					sample{2, 0, nil, tsdbutil.SetFloatHistogramNotCounterReset(tsdbutil.GenerateTestFloatHistogram(2))},
-					sample{3, 0, nil, tsdbutil.SetFloatHistogramNotCounterReset(tsdbutil.GenerateTestFloatHistogram(3))},
-				}),
-			},
-		},
-		{
-			name: "one gauge histogram chunk",
-			chks: [][]tsdbutil.Sample{
-				{
-					sample{1, 0, tsdbutil.GenerateTestGaugeHistogram(1), nil},
-					sample{2, 0, tsdbutil.GenerateTestGaugeHistogram(2), nil},
-					sample{3, 0, tsdbutil.GenerateTestGaugeHistogram(3), nil},
-					sample{6, 0, tsdbutil.GenerateTestGaugeHistogram(6), nil},
-				},
-			},
-			expected: []tsdbutil.Sample{
-				sample{1, 0, tsdbutil.GenerateTestGaugeHistogram(1), nil},
-				sample{2, 0, tsdbutil.GenerateTestGaugeHistogram(2), nil},
-				sample{3, 0, tsdbutil.GenerateTestGaugeHistogram(3), nil},
-				sample{6, 0, tsdbutil.GenerateTestGaugeHistogram(6), nil},
-			},
-			expectedChks: []chunks.Meta{
-				tsdbutil.ChunkFromSamples([]tsdbutil.Sample{
-					sample{1, 0, tsdbutil.GenerateTestGaugeHistogram(1), nil},
-					sample{2, 0, tsdbutil.GenerateTestGaugeHistogram(2), nil},
-					sample{3, 0, tsdbutil.GenerateTestGaugeHistogram(3), nil},
-					sample{6, 0, tsdbutil.GenerateTestGaugeHistogram(6), nil},
-				}),
-			},
-		},
-		{
-			name: "one gauge histogram chunk intersect with deletion interval",
-			chks: [][]tsdbutil.Sample{
-				{
-					sample{1, 0, tsdbutil.GenerateTestGaugeHistogram(1), nil},
-					sample{2, 0, tsdbutil.GenerateTestGaugeHistogram(2), nil},
-					sample{3, 0, tsdbutil.GenerateTestGaugeHistogram(3), nil},
-					sample{6, 0, tsdbutil.GenerateTestGaugeHistogram(6), nil},
-				},
-			},
-			intervals: tombstones.Intervals{{Mint: 5, Maxt: 20}},
-			expected: []tsdbutil.Sample{
-				sample{1, 0, tsdbutil.GenerateTestGaugeHistogram(1), nil},
-				sample{2, 0, tsdbutil.GenerateTestGaugeHistogram(2), nil},
-				sample{3, 0, tsdbutil.GenerateTestGaugeHistogram(3), nil},
-			},
-			expectedChks: []chunks.Meta{
-				tsdbutil.ChunkFromSamples([]tsdbutil.Sample{
-					sample{1, 0, tsdbutil.GenerateTestGaugeHistogram(1), nil},
-					sample{2, 0, tsdbutil.GenerateTestGaugeHistogram(2), nil},
-					sample{3, 0, tsdbutil.GenerateTestGaugeHistogram(3), nil},
-				}),
-			},
-		},
-		{
-			name: "one gauge float histogram",
-			chks: [][]tsdbutil.Sample{
-				{
-					sample{1, 0, nil, tsdbutil.GenerateTestGaugeFloatHistogram(1)},
-					sample{2, 0, nil, tsdbutil.GenerateTestGaugeFloatHistogram(2)},
-					sample{3, 0, nil, tsdbutil.GenerateTestGaugeFloatHistogram(3)},
-					sample{6, 0, nil, tsdbutil.GenerateTestGaugeFloatHistogram(6)},
-				},
-			},
-			expected: []tsdbutil.Sample{
-				sample{1, 0, nil, tsdbutil.GenerateTestGaugeFloatHistogram(1)},
-				sample{2, 0, nil, tsdbutil.GenerateTestGaugeFloatHistogram(2)},
-				sample{3, 0, nil, tsdbutil.GenerateTestGaugeFloatHistogram(3)},
-				sample{6, 0, nil, tsdbutil.GenerateTestGaugeFloatHistogram(6)},
-			},
-			expectedChks: []chunks.Meta{
-				tsdbutil.ChunkFromSamples([]tsdbutil.Sample{
-					sample{1, 0, nil, tsdbutil.GenerateTestGaugeFloatHistogram(1)},
-					sample{2, 0, nil, tsdbutil.GenerateTestGaugeFloatHistogram(2)},
-					sample{3, 0, nil, tsdbutil.GenerateTestGaugeFloatHistogram(3)},
-					sample{6, 0, nil, tsdbutil.GenerateTestGaugeFloatHistogram(6)},
-				}),
-			},
-		},
-		{
-			name: "one gauge float histogram chunk intersect with deletion interval",
-			chks: [][]tsdbutil.Sample{
-				{
-					sample{1, 0, nil, tsdbutil.GenerateTestGaugeFloatHistogram(1)},
-					sample{2, 0, nil, tsdbutil.GenerateTestGaugeFloatHistogram(2)},
-					sample{3, 0, nil, tsdbutil.GenerateTestGaugeFloatHistogram(3)},
-					sample{6, 0, nil, tsdbutil.GenerateTestGaugeFloatHistogram(6)},
-				},
-			},
-			intervals: tombstones.Intervals{{Mint: 5, Maxt: 20}},
-			expected: []tsdbutil.Sample{
-				sample{1, 0, nil, tsdbutil.GenerateTestGaugeFloatHistogram(1)},
-				sample{2, 0, nil, tsdbutil.GenerateTestGaugeFloatHistogram(2)},
-				sample{3, 0, nil, tsdbutil.GenerateTestGaugeFloatHistogram(3)},
-			},
-			expectedChks: []chunks.Meta{
-				tsdbutil.ChunkFromSamples([]tsdbutil.Sample{
-					sample{1, 0, nil, tsdbutil.GenerateTestGaugeFloatHistogram(1)},
-					sample{2, 0, nil, tsdbutil.GenerateTestGaugeFloatHistogram(2)},
-					sample{3, 0, nil, tsdbutil.GenerateTestGaugeFloatHistogram(3)},
-				}),
-			},
-		},
 	}
 	for _, tc := range cases {
 		t.Run(tc.name, func(t *testing.T) {
@@ -2608,80 +2371,3 @@ func BenchmarkHeadQuerier(b *testing.B) {
 		require.NoError(b, ss.Err())
 	}
 }
-
-// This is a regression test for the case where gauge histograms were not handled by
-// populateWithDelChunkSeriesIterator correctly.
-func TestQueryWithDeletedHistograms(t *testing.T) {
-	testcases := map[string]func(int) (*histogram.Histogram, *histogram.FloatHistogram){
-		"intCounter": func(i int) (*histogram.Histogram, *histogram.FloatHistogram) {
-			return tsdbutil.GenerateTestHistogram(i), nil
-		},
-		"intgauge": func(i int) (*histogram.Histogram, *histogram.FloatHistogram) {
-			return tsdbutil.GenerateTestGaugeHistogram(rand.Int() % 1000), nil
-		},
-		"floatCounter": func(i int) (*histogram.Histogram, *histogram.FloatHistogram) {
-			return nil, tsdbutil.GenerateTestFloatHistogram(i)
-		},
-		"floatGauge": func(i int) (*histogram.Histogram, *histogram.FloatHistogram) {
-			return nil, tsdbutil.GenerateTestGaugeFloatHistogram(rand.Int() % 1000)
-		},
-	}
-
-	for name, tc := range testcases {
-		t.Run(name, func(t *testing.T) {
-			db := openTestDB(t, nil, nil)
-			defer func() {
-				require.NoError(t, db.Close())
-			}()
-
-			db.EnableNativeHistograms()
-			appender := db.Appender(context.Background())
-
-			var (
-				err       error
-				seriesRef storage.SeriesRef
-			)
-			lbs := labels.FromStrings("__name__", "test", "type", name)
-
-			for i := 0; i < 100; i++ {
-				h, fh := tc(i)
-				seriesRef, err = appender.AppendHistogram(seriesRef, lbs, int64(i), h, fh)
-				require.NoError(t, err)
-			}
-
-			err = appender.Commit()
-			require.NoError(t, err)
-
-			matcher, err := labels.NewMatcher(labels.MatchEqual, "__name__", "test")
-			require.NoError(t, err)
-
-			// Delete the last 20.
-			err = db.Delete(80, 100, matcher)
-			require.NoError(t, err)
-
-			chunkQuerier, err := db.ChunkQuerier(context.Background(), 0, 100)
-			require.NoError(t, err)
-
-			css := chunkQuerier.Select(false, nil, matcher)
-
-			seriesCount := 0
-			for css.Next() {
-				seriesCount++
-				series := css.At()
-
-				sampleCount := 0
-				it := series.Iterator(nil)
-				for it.Next() {
-					chk := it.At()
-					for cit := chk.Chunk.Iterator(nil); cit.Next() != chunkenc.ValNone; {
-						sampleCount++
-					}
-				}
-				require.NoError(t, it.Err())
-				require.Equal(t, 80, sampleCount)
-			}
-			require.NoError(t, css.Err())
-			require.Equal(t, 1, seriesCount)
-		})
-	}
-}
diff --git a/tsdb/tombstones/tombstones_test.go b/tsdb/tombstones/tombstones_test.go
index 36c9f1c1e..ffe25b0be 100644
--- a/tsdb/tombstones/tombstones_test.go
+++ b/tsdb/tombstones/tombstones_test.go
@@ -81,22 +81,6 @@ func TestDeletingTombstones(t *testing.T) {
 	require.Empty(t, intervals)
 }
 
-func TestTombstonesGetWithCopy(t *testing.T) {
-	stones := NewMemTombstones()
-	stones.AddInterval(1, Intervals{{Mint: 1, Maxt: 2}, {Mint: 7, Maxt: 8}, {Mint: 11, Maxt: 12}}...)
-
-	intervals0, err := stones.Get(1)
-	require.NoError(t, err)
-	require.Equal(t, Intervals{{Mint: 1, Maxt: 2}, {Mint: 7, Maxt: 8}, {Mint: 11, Maxt: 12}}, intervals0)
-	intervals1 := intervals0.Add(Interval{Mint: 4, Maxt: 6})
-	require.Equal(t, Intervals{{Mint: 1, Maxt: 2}, {Mint: 4, Maxt: 8}, {Mint: 11, Maxt: 12}}, intervals0) // Original slice changed.
-	require.Equal(t, Intervals{{Mint: 1, Maxt: 2}, {Mint: 4, Maxt: 8}, {Mint: 11, Maxt: 12}}, intervals1)
-
-	intervals2, err := stones.Get(1)
-	require.NoError(t, err)
-	require.Equal(t, Intervals{{Mint: 1, Maxt: 2}, {Mint: 7, Maxt: 8}, {Mint: 11, Maxt: 12}}, intervals2)
-}
-
 func TestTruncateBefore(t *testing.T) {
 	cases := []struct {
 		before  Intervals
@@ -226,26 +210,6 @@ func TestAddingNewIntervals(t *testing.T) {
 			new:   Interval{math.MinInt64, 10},
 			exp:   Intervals{{math.MinInt64, math.MaxInt64}},
 		},
-		{
-			exist: Intervals{{9, 10}},
-			new:   Interval{math.MinInt64, 7},
-			exp:   Intervals{{math.MinInt64, 7}, {9, 10}},
-		},
-		{
-			exist: Intervals{{9, 10}},
-			new:   Interval{12, math.MaxInt64},
-			exp:   Intervals{{9, 10}, {12, math.MaxInt64}},
-		},
-		{
-			exist: Intervals{{9, 10}},
-			new:   Interval{math.MinInt64, 8},
-			exp:   Intervals{{math.MinInt64, 10}},
-		},
-		{
-			exist: Intervals{{9, 10}},
-			new:   Interval{11, math.MaxInt64},
-			exp:   Intervals{{9, math.MaxInt64}},
-		},
 	}
 
 	for _, c := range cases {
diff --git a/web/api/v1/api_test.go b/web/api/v1/api_test.go
index baee2189e..620acd862 100644
--- a/web/api/v1/api_test.go
+++ b/web/api/v1/api_test.go
@@ -2622,7 +2622,7 @@ type fakeDB struct {
 func (f *fakeDB) CleanTombstones() error                        { return f.err }
 func (f *fakeDB) Delete(int64, int64, ...*labels.Matcher) error { return f.err }
 func (f *fakeDB) Snapshot(string, bool) error                   { return f.err }
-func (f *fakeDB) Stats(statsByLabelName string, limit int) (_ *tsdb.Stats, retErr error) {
+func (f *fakeDB) Stats(statsByLabelName string) (_ *tsdb.Stats, retErr error) {
 	dbDir, err := os.MkdirTemp("", "tsdb-api-ready")
 	if err != nil {
 		return nil, err
@@ -2636,7 +2636,7 @@ func (f *fakeDB) Stats(statsByLabelName string, limit int) (_ *tsdb.Stats, retEr
 	opts := tsdb.DefaultHeadOptions()
 	opts.ChunkRange = 1000
 	h, _ := tsdb.NewHead(nil, nil, nil, nil, opts, nil)
-	return h.Stats(statsByLabelName, limit), nil
+	return h.Stats(statsByLabelName), nil
 }
 
 func (f *fakeDB) WALReplayStatus() (tsdb.WALReplayStatus, error) {
@@ -3283,19 +3283,8 @@ func TestTSDBStatus(t *testing.T) {
 		{
 			db:       tsdb,
 			endpoint: tsdbStatusAPI,
-			errType:  errorNone,
-		},
-		{
-			db:       tsdb,
-			endpoint: tsdbStatusAPI,
-			values:   map[string][]string{"limit": {"20"}},
-			errType:  errorNone,
-		},
-		{
-			db:       tsdb,
-			endpoint: tsdbStatusAPI,
-			values:   map[string][]string{"limit": {"0"}},
-			errType:  errorBadData,
+
+			errType: errorNone,
 		},
 	} {
 		tc := tc
diff --git a/web/federate_test.go b/web/federate_test.go
index 6bc0ae212..bf7b6fefe 100644
--- a/web/federate_test.go
+++ b/web/federate_test.go
@@ -251,7 +251,7 @@ func (notReadyReadStorage) StartTime() (int64, error) {
 	return 0, errors.Wrap(tsdb.ErrNotReady, "wrap")
 }
 
-func (notReadyReadStorage) Stats(string, int) (*tsdb.Stats, error) {
+func (notReadyReadStorage) Stats(string) (*tsdb.Stats, error) {
 	return nil, errors.Wrap(tsdb.ErrNotReady, "wrap")
 }
 
diff --git a/web/web_test.go b/web/web_test.go
index 8832c2839..7da06a306 100644
--- a/web/web_test.go
+++ b/web/web_test.go
@@ -52,8 +52,8 @@ type dbAdapter struct {
 	*tsdb.DB
 }
 
-func (a *dbAdapter) Stats(statsByLabelName string, limit int) (*tsdb.Stats, error) {
-	return a.Head().Stats(statsByLabelName, limit), nil
+func (a *dbAdapter) Stats(statsByLabelName string) (*tsdb.Stats, error) {
+	return a.Head().Stats(statsByLabelName), nil
 }
 
 func (a *dbAdapter) WALReplayStatus() (tsdb.WALReplayStatus, error) {