diff --git a/pkg/query/iter.go b/pkg/query/iter.go
index 2a4e90b92b7..8d1d043b203 100644
--- a/pkg/query/iter.go
+++ b/pkg/query/iter.go
@@ -178,6 +178,8 @@ func chunkEncoding(e storepb.Chunk_Encoding) chunkenc.Encoding {
 		return chunkenc.EncXOR
 	case storepb.Chunk_HISTOGRAM:
 		return chunkenc.EncHistogram
+	case storepb.Chunk_FLOAT_HISTOGRAM:
+		return chunkenc.EncFloatHistogram
 	}
 	return 255 // Invalid.
 }
diff --git a/pkg/receive/writer.go b/pkg/receive/writer.go
index 039c3aea527..e6c6e88fbc3 100644
--- a/pkg/receive/writer.go
+++ b/pkg/receive/writer.go
@@ -5,6 +5,7 @@ package receive
 
 import (
 	"context"
+	"github.com/prometheus/prometheus/model/histogram"
 	"time"
 
 	"github.com/go-kit/log"
@@ -168,8 +169,18 @@ func (r *Writer) Write(ctx context.Context, tenantID string, wreq *prompb.WriteR
 		}
 
 		for _, hp := range t.Histograms {
-			h := prompb.HistogramProtoToHistogram(hp)
-			ref, err = app.AppendHistogram(ref, lset, hp.Timestamp, h, nil)
+			var (
+				h  *histogram.Histogram
+				fh *histogram.FloatHistogram
+			)
+
+			if hp.IsFloatHistogram() {
+				fh = prompb.FloatHistogramProtoToFloatHistogram(hp)
+			} else {
+				h = prompb.HistogramProtoToHistogram(hp)
+			}
+
+			ref, err = app.AppendHistogram(ref, lset, hp.Timestamp, h, fh)
 			switch err {
 			case storage.ErrOutOfOrderSample:
 				numSamplesOutOfOrder++
diff --git a/pkg/receive/writer_test.go b/pkg/receive/writer_test.go
index f3a213a7665..cfd6043d824 100644
--- a/pkg/receive/writer_test.go
+++ b/pkg/receive/writer_test.go
@@ -10,17 +10,17 @@ import (
 	"testing"
 	"time"
 
+	"github.com/efficientgo/core/testutil"
 	"github.com/go-kit/log"
 	"github.com/pkg/errors"
 	"github.com/prometheus/client_golang/prometheus"
 	"github.com/prometheus/common/model"
 	"github.com/prometheus/prometheus/model/exemplar"
-	"github.com/prometheus/prometheus/model/histogram"
 	"github.com/prometheus/prometheus/model/labels"
 	"github.com/prometheus/prometheus/storage"
 	"github.com/prometheus/prometheus/tsdb"
+	"github.com/prometheus/prometheus/tsdb/tsdbutil"
 
-	"github.com/efficientgo/core/testutil"
 	"github.com/thanos-io/thanos/pkg/block/metadata"
 	"github.com/thanos-io/thanos/pkg/runutil"
 	"github.com/thanos-io/thanos/pkg/store/labelpb"
@@ -250,7 +250,7 @@ func TestWriter(t *testing.T) {
 						{
 							Labels: append(lbls, labelpb.ZLabel{Name: "a", Value: "1"}, labelpb.ZLabel{Name: "b", Value: "2"}),
 							Histograms: []prompb.Histogram{
-								histogramToHistogramProto(9, testHistogram()),
+								prompb.HistogramToHistogramProto(10, tsdbutil.GenerateTestHistogram(0)),
 							},
 						},
 					},
@@ -261,7 +261,30 @@ func TestWriter(t *testing.T) {
 				{
 					Labels: append(lbls, labelpb.ZLabel{Name: "a", Value: "1"}, labelpb.ZLabel{Name: "b", Value: "2"}),
 					Histograms: []prompb.Histogram{
-						histogramToHistogramProto(10, testHistogram()),
+						prompb.HistogramToHistogramProto(10, tsdbutil.GenerateTestHistogram(0)),
+					},
+				},
+			},
+		},
+		"should succeed on float histogram with valid labels": {
+			reqs: []*prompb.WriteRequest{
+				{
+					Timeseries: []prompb.TimeSeries{
+						{
+							Labels: append(lbls, labelpb.ZLabel{Name: "a", Value: "1"}, labelpb.ZLabel{Name: "b", Value: "2"}),
+							Histograms: []prompb.Histogram{
+								prompb.FloatHistogramToHistogramProto(10, tsdbutil.GenerateTestFloatHistogram(1)),
+							},
+						},
+					},
+				},
+			},
+			expectedErr: nil,
+			expectedIngested: []prompb.TimeSeries{
+				{
+					Labels: append(lbls, labelpb.ZLabel{Name: "a", Value: "1"}, labelpb.ZLabel{Name: "b", Value: "2"}),
+					Histograms: []prompb.Histogram{
+						prompb.FloatHistogramToHistogramProto(10, tsdbutil.GenerateTestFloatHistogram(1)),
 					},
 				},
 			},
@@ -273,7 +296,7 @@ func TestWriter(t *testing.T) {
 						{
 							Labels: append(lbls, labelpb.ZLabel{Name: "a", Value: "1"}, labelpb.ZLabel{Name: "b", Value: "2"}),
 							Histograms: []prompb.Histogram{
-								histogramToHistogramProto(10, testHistogram()),
+								prompb.HistogramToHistogramProto(10, tsdbutil.GenerateTestHistogram(0)),
 							},
 						},
 					},
@@ -283,7 +306,7 @@ func TestWriter(t *testing.T) {
 						{
 							Labels: append(lbls, labelpb.ZLabel{Name: "a", Value: "1"}, labelpb.ZLabel{Name: "b", Value: "2"}),
 							Histograms: []prompb.Histogram{
-								histogramToHistogramProto(9, testHistogram()),
+								prompb.HistogramToHistogramProto(9, tsdbutil.GenerateTestHistogram(0)),
 							},
 						},
 					},
@@ -294,7 +317,7 @@ func TestWriter(t *testing.T) {
 				{
 					Labels: append(lbls, labelpb.ZLabel{Name: "a", Value: "1"}, labelpb.ZLabel{Name: "b", Value: "2"}),
 					Histograms: []prompb.Histogram{
-						histogramToHistogramProto(10, testHistogram()),
+						prompb.HistogramToHistogramProto(10, tsdbutil.GenerateTestHistogram(0)),
 					},
 				},
 			},
@@ -479,7 +502,7 @@ func generateLabelsAndSeries(numLabels int, numSeries int, generateHistograms bo
 		}
 
 		if generateHistograms {
-			ts[j].Histograms = []prompb.Histogram{histogramToHistogramProto(10, testHistogram())}
+			ts[j].Histograms = []prompb.Histogram{prompb.HistogramToHistogramProto(10, tsdbutil.GenerateTestHistogram(0))}
 			continue
 		}
 
@@ -488,42 +511,3 @@ func generateLabelsAndSeries(numLabels int, numSeries int, generateHistograms bo
 
 	return ts
 }
-
-func testHistogram() *histogram.Histogram {
-	return &histogram.Histogram{
-		Count:         5,
-		ZeroCount:     2,
-		Sum:           18.4,
-		ZeroThreshold: 0.1,
-		Schema:        1,
-		PositiveSpans: []histogram.Span{
-			{Offset: 0, Length: 2},
-			{Offset: 1, Length: 2},
-		},
-		PositiveBuckets: []int64{1, 1, -1, 0}, // counts: 1, 2, 1, 1 (total 5)
-	}
-}
-
-func histogramToHistogramProto(timestamp int64, h *histogram.Histogram) prompb.Histogram {
-	return prompb.Histogram{
-		Count:          &prompb.Histogram_CountInt{CountInt: h.Count},
-		Sum:            h.Sum,
-		Schema:         h.Schema,
-		ZeroThreshold:  h.ZeroThreshold,
-		ZeroCount:      &prompb.Histogram_ZeroCountInt{ZeroCountInt: h.ZeroCount},
-		NegativeSpans:  spansToSpansProto(h.NegativeSpans),
-		NegativeDeltas: h.NegativeBuckets,
-		PositiveSpans:  spansToSpansProto(h.PositiveSpans),
-		PositiveDeltas: h.PositiveBuckets,
-		Timestamp:      timestamp,
-	}
-}
-
-func spansToSpansProto(s []histogram.Span) []*prompb.BucketSpan {
-	spans := make([]*prompb.BucketSpan, len(s))
-	for i := 0; i < len(s); i++ {
-		spans[i] = &prompb.BucketSpan{Offset: s[i].Offset, Length: s[i].Length}
-	}
-
-	return spans
-}
diff --git a/pkg/store/storepb/prompb/custom.go b/pkg/store/storepb/prompb/custom.go
new file mode 100644
index 00000000000..fb3b395a9a6
--- /dev/null
+++ b/pkg/store/storepb/prompb/custom.go
@@ -0,0 +1,9 @@
+// Copyright (c) The Thanos Authors.
+// Licensed under the Apache License 2.0.
+
+package prompb
+
+func (h Histogram) IsFloatHistogram() bool {
+	_, ok := h.GetCount().(*Histogram_CountFloat)
+	return ok
+}
diff --git a/pkg/store/storepb/prompb/samples.go b/pkg/store/storepb/prompb/samples.go
index a276d9264ea..ff9c658120a 100644
--- a/pkg/store/storepb/prompb/samples.go
+++ b/pkg/store/storepb/prompb/samples.go
@@ -62,71 +62,119 @@ func SamplesFromPromqlSeries(series promql.Series) ([]Sample, []Histogram) {
 // HistogramProtoToHistogram extracts a (normal integer) Histogram from the
 // provided proto message. The caller has to make sure that the proto message
 // represents an interger histogram and not a float histogram.
-// Taken from https://github.com/prometheus/prometheus/blob/d33eb3ab17616a54b97d9f7791c791a79823f279/storage/remote/codec.go#L529-L542.
 func HistogramProtoToHistogram(hp Histogram) *histogram.Histogram {
+	if hp.IsFloatHistogram() {
+		panic("HistogramProtoToHistogram called with a float histogram")
+	}
 	return &histogram.Histogram{
-		Schema:          hp.Schema,
-		ZeroThreshold:   hp.ZeroThreshold,
-		ZeroCount:       hp.GetZeroCountInt(),
-		Count:           hp.GetCountInt(),
-		Sum:             hp.Sum,
-		PositiveSpans:   spansProtoToSpans(hp.GetPositiveSpans()),
-		PositiveBuckets: hp.GetPositiveDeltas(),
-		NegativeSpans:   spansProtoToSpans(hp.GetNegativeSpans()),
-		NegativeBuckets: hp.GetNegativeDeltas(),
+		CounterResetHint: histogram.CounterResetHint(hp.ResetHint),
+		Schema:           hp.Schema,
+		ZeroThreshold:    hp.ZeroThreshold,
+		ZeroCount:        hp.GetZeroCountInt(),
+		Count:            hp.GetCountInt(),
+		Sum:              hp.Sum,
+		PositiveSpans:    spansProtoToSpans(hp.GetPositiveSpans()),
+		PositiveBuckets:  hp.GetPositiveDeltas(),
+		NegativeSpans:    spansProtoToSpans(hp.GetNegativeSpans()),
+		NegativeBuckets:  hp.GetNegativeDeltas(),
 	}
 }
 
 // FloatHistogramToHistogramProto converts a float histogram to a protobuf type.
-// Taken from https://github.com/prometheus/prometheus/blob/d33eb3ab17616a54b97d9f7791c791a79823f279/storage/remote/codec.go#L587-L601.
-func FloatHistogramToHistogramProto(timestamp int64, fh *histogram.FloatHistogram) Histogram {
-	return Histogram{
-		Count:          &Histogram_CountFloat{CountFloat: fh.Count},
-		Sum:            fh.Sum,
-		Schema:         fh.Schema,
-		ZeroThreshold:  fh.ZeroThreshold,
-		ZeroCount:      &Histogram_ZeroCountFloat{ZeroCountFloat: fh.ZeroCount},
-		NegativeSpans:  spansToSpansProto(fh.NegativeSpans),
-		NegativeCounts: fh.NegativeBuckets,
-		PositiveSpans:  spansToSpansProto(fh.PositiveSpans),
-		PositiveCounts: fh.PositiveBuckets,
-		ResetHint:      Histogram_ResetHint(fh.CounterResetHint),
-		Timestamp:      timestamp,
+func FloatHistogramProtoToFloatHistogram(hp Histogram) *histogram.FloatHistogram {
+	if !hp.IsFloatHistogram() {
+		panic("FloatHistogramProtoToFloatHistogram called with an integer histogram")
+	}
+	return &histogram.FloatHistogram{
+		CounterResetHint: histogram.CounterResetHint(hp.ResetHint),
+		Schema:           hp.Schema,
+		ZeroThreshold:    hp.ZeroThreshold,
+		ZeroCount:        hp.GetZeroCountFloat(),
+		Count:            hp.GetCountFloat(),
+		Sum:              hp.Sum,
+		PositiveSpans:    spansProtoToSpans(hp.GetPositiveSpans()),
+		PositiveBuckets:  hp.GetPositiveCounts(),
+		NegativeSpans:    spansProtoToSpans(hp.GetNegativeSpans()),
+		NegativeBuckets:  hp.GetNegativeCounts(),
 	}
 }
 
 // HistogramProtoToFloatHistogram extracts a (normal integer) Histogram from the
 // provided proto message to a Float Histogram. The caller has to make sure that
 // the proto message represents an float histogram and not a integer histogram.
-// Taken from https://github.com/prometheus/prometheus/blob/d33eb3ab17616a54b97d9f7791c791a79823f279/storage/remote/codec.go#L547-L560.
 func HistogramProtoToFloatHistogram(hp Histogram) *histogram.FloatHistogram {
+	if hp.IsFloatHistogram() {
+		panic("HistogramProtoToFloatHistogram called with a float histogram")
+	}
 	return &histogram.FloatHistogram{
 		CounterResetHint: histogram.CounterResetHint(hp.ResetHint),
 		Schema:           hp.Schema,
 		ZeroThreshold:    hp.ZeroThreshold,
-		ZeroCount:        hp.GetZeroCountFloat(),
-		Count:            hp.GetCountFloat(),
+		ZeroCount:        float64(hp.GetZeroCountInt()),
+		Count:            float64(hp.GetCountInt()),
 		Sum:              hp.Sum,
 		PositiveSpans:    spansProtoToSpans(hp.GetPositiveSpans()),
-		PositiveBuckets:  hp.GetPositiveCounts(),
+		PositiveBuckets:  deltasToCounts(hp.GetPositiveDeltas()),
 		NegativeSpans:    spansProtoToSpans(hp.GetNegativeSpans()),
-		NegativeBuckets:  hp.GetNegativeCounts(),
+		NegativeBuckets:  deltasToCounts(hp.GetNegativeDeltas()),
 	}
 }
 
-func spansToSpansProto(s []histogram.Span) []*BucketSpan {
-	spans := make([]*BucketSpan, len(s))
+func spansProtoToSpans(s []BucketSpan) []histogram.Span {
+	spans := make([]histogram.Span, len(s))
 	for i := 0; i < len(s); i++ {
-		spans[i] = &BucketSpan{Offset: s[i].Offset, Length: s[i].Length}
+		spans[i] = histogram.Span{Offset: s[i].Offset, Length: s[i].Length}
 	}
 
 	return spans
 }
 
-func spansProtoToSpans(s []*BucketSpan) []histogram.Span {
-	spans := make([]histogram.Span, len(s))
+func deltasToCounts(deltas []int64) []float64 {
+	counts := make([]float64, len(deltas))
+	var cur float64
+	for i, d := range deltas {
+		cur += float64(d)
+		counts[i] = cur
+	}
+	return counts
+}
+
+func HistogramToHistogramProto(timestamp int64, h *histogram.Histogram) Histogram {
+	return Histogram{
+		Count:          &Histogram_CountInt{CountInt: h.Count},
+		Sum:            h.Sum,
+		Schema:         h.Schema,
+		ZeroThreshold:  h.ZeroThreshold,
+		ZeroCount:      &Histogram_ZeroCountInt{ZeroCountInt: h.ZeroCount},
+		NegativeSpans:  spansToSpansProto(h.NegativeSpans),
+		NegativeDeltas: h.NegativeBuckets,
+		PositiveSpans:  spansToSpansProto(h.PositiveSpans),
+		PositiveDeltas: h.PositiveBuckets,
+		ResetHint:      Histogram_ResetHint(h.CounterResetHint),
+		Timestamp:      timestamp,
+	}
+}
+
+func FloatHistogramToHistogramProto(timestamp int64, fh *histogram.FloatHistogram) Histogram {
+	return Histogram{
+		Count:          &Histogram_CountFloat{CountFloat: fh.Count},
+		Sum:            fh.Sum,
+		Schema:         fh.Schema,
+		ZeroThreshold:  fh.ZeroThreshold,
+		ZeroCount:      &Histogram_ZeroCountFloat{ZeroCountFloat: fh.ZeroCount},
+		NegativeSpans:  spansToSpansProto(fh.NegativeSpans),
+		NegativeCounts: fh.NegativeBuckets,
+		PositiveSpans:  spansToSpansProto(fh.PositiveSpans),
+		PositiveCounts: fh.PositiveBuckets,
+		ResetHint:      Histogram_ResetHint(fh.CounterResetHint),
+		Timestamp:      timestamp,
+	}
+}
+
+func spansToSpansProto(s []histogram.Span) []BucketSpan {
+	spans := make([]BucketSpan, len(s))
 	for i := 0; i < len(s); i++ {
-		spans[i] = histogram.Span{Offset: s[i].Offset, Length: s[i].Length}
+		spans[i] = BucketSpan{Offset: s[i].Offset, Length: s[i].Length}
 	}
 
 	return spans
diff --git a/pkg/store/storepb/prompb/types.pb.go b/pkg/store/storepb/prompb/types.pb.go
index f5332f345ba..42c1b0fd9ce 100644
--- a/pkg/store/storepb/prompb/types.pb.go
+++ b/pkg/store/storepb/prompb/types.pb.go
@@ -367,14 +367,14 @@ type Histogram struct {
 	//	*Histogram_ZeroCountFloat
 	ZeroCount isHistogram_ZeroCount `protobuf_oneof:"zero_count"`
 	// Negative Buckets.
-	NegativeSpans []*BucketSpan `protobuf:"bytes,8,rep,name=negative_spans,json=negativeSpans,proto3" json:"negative_spans,omitempty"`
+	NegativeSpans []BucketSpan `protobuf:"bytes,8,rep,name=negative_spans,json=negativeSpans,proto3" json:"negative_spans"`
 	// Use either "negative_deltas" or "negative_counts", the former for
 	// regular histograms with integer counts, the latter for float
 	// histograms.
 	NegativeDeltas []int64   `protobuf:"zigzag64,9,rep,packed,name=negative_deltas,json=negativeDeltas,proto3" json:"negative_deltas,omitempty"`
 	NegativeCounts []float64 `protobuf:"fixed64,10,rep,packed,name=negative_counts,json=negativeCounts,proto3" json:"negative_counts,omitempty"`
 	// Positive Buckets.
-	PositiveSpans []*BucketSpan `protobuf:"bytes,11,rep,name=positive_spans,json=positiveSpans,proto3" json:"positive_spans,omitempty"`
+	PositiveSpans []BucketSpan `protobuf:"bytes,11,rep,name=positive_spans,json=positiveSpans,proto3" json:"positive_spans"`
 	// Use either "positive_deltas" or "positive_counts", the former for
 	// regular histograms with integer counts, the latter for float
 	// histograms.
@@ -510,7 +510,7 @@ func (m *Histogram) GetZeroCountFloat() float64 {
 	return 0
 }
 
-func (m *Histogram) GetNegativeSpans() []*BucketSpan {
+func (m *Histogram) GetNegativeSpans() []BucketSpan {
 	if m != nil {
 		return m.NegativeSpans
 	}
@@ -531,7 +531,7 @@ func (m *Histogram) GetNegativeCounts() []float64 {
 	return nil
 }
 
-func (m *Histogram) GetPositiveSpans() []*BucketSpan {
+func (m *Histogram) GetPositiveSpans() []BucketSpan {
 	if m != nil {
 		return m.PositiveSpans
 	}
@@ -988,79 +988,79 @@ func init() {
 func init() { proto.RegisterFile("store/storepb/prompb/types.proto", fileDescriptor_166e07899dab7c14) }
 
 var fileDescriptor_166e07899dab7c14 = []byte{
-	// 1139 bytes of a gzipped FileDescriptorProto
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x56, 0x4b, 0x8f, 0x1a, 0xc7,
-	0x13, 0x67, 0x66, 0x60, 0x60, 0x6a, 0x01, 0x8f, 0x5b, 0xfe, 0xdb, 0xe3, 0xfd, 0x27, 0x2c, 0x19,
-	0xe5, 0x81, 0xac, 0x04, 0x24, 0x7b, 0x95, 0x5c, 0x36, 0x51, 0x96, 0x0d, 0xfb, 0x50, 0x02, 0xc8,
-	0x0d, 0xab, 0xc4, 0xbe, 0xa0, 0x06, 0x7a, 0x99, 0xd1, 0x32, 0x0f, 0x4d, 0x37, 0xd6, 0x92, 0x4f,
-	0x91, 0x73, 0x6e, 0x51, 0x6e, 0xc9, 0x29, 0x1f, 0x21, 0x37, 0x9f, 0x22, 0x1f, 0xa3, 0x1c, 0xac,
-	0x68, 0xf7, 0x8b, 0x44, 0xdd, 0x33, 0xc3, 0xc0, 0x12, 0x4b, 0x39, 0xf9, 0x82, 0xaa, 0x7e, 0xf5,
-	0xfa, 0x4d, 0x57, 0x75, 0x35, 0x50, 0x67, 0x3c, 0x88, 0x68, 0x4b, 0xfe, 0x86, 0xe3, 0x56, 0x18,
-	0x05, 0x5e, 0x38, 0x6e, 0xf1, 0x65, 0x48, 0x59, 0x33, 0x8c, 0x02, 0x1e, 0xa0, 0x3b, 0x02, 0xa3,
-	0xdc, 0xa1, 0x0b, 0x36, 0x9a, 0x04, 0xe1, 0x72, 0xf7, 0xde, 0x2c, 0x98, 0x05, 0xd2, 0xd6, 0x12,
-	0x52, 0xec, 0xb6, 0xfb, 0x30, 0x4e, 0x34, 0x27, 0x63, 0x3a, 0xdf, 0xcc, 0x60, 0xff, 0xa4, 0x42,
-	0xb5, 0x4b, 0x79, 0xe4, 0x4e, 0xba, 0x94, 0x93, 0x29, 0xe1, 0x04, 0x7d, 0x01, 0x79, 0xe1, 0x61,
-	0x29, 0x75, 0xa5, 0x51, 0x7d, 0xfc, 0xa8, 0x79, 0xab, 0x46, 0x73, 0xd3, 0x3d, 0x51, 0x87, 0xcb,
-	0x90, 0x62, 0x19, 0x87, 0x3e, 0x06, 0xe4, 0x49, 0x6c, 0x74, 0x41, 0x3c, 0x77, 0xbe, 0x1c, 0xf9,
-	0xc4, 0xa3, 0x96, 0x5a, 0x57, 0x1a, 0x06, 0x36, 0x63, 0xcb, 0xb1, 0x34, 0xf4, 0x88, 0x47, 0x11,
-	0x82, 0xbc, 0x43, 0xe7, 0xa1, 0x95, 0x97, 0x76, 0x29, 0x0b, 0x6c, 0xe1, 0xbb, 0xdc, 0x2a, 0xc4,
-	0x98, 0x90, 0xed, 0x25, 0x40, 0x56, 0x09, 0xed, 0x40, 0xf1, 0xbc, 0xf7, 0x75, 0xaf, 0xff, 0x6d,
-	0xcf, 0xcc, 0x09, 0xe5, 0xa8, 0x7f, 0xde, 0x1b, 0x76, 0xb0, 0xa9, 0x20, 0x03, 0x0a, 0x27, 0x87,
-	0xe7, 0x27, 0x1d, 0x53, 0x45, 0x15, 0x30, 0x4e, 0xcf, 0x06, 0xc3, 0xfe, 0x09, 0x3e, 0xec, 0x9a,
-	0x1a, 0x42, 0x50, 0x95, 0x96, 0x0c, 0xcb, 0x8b, 0xd0, 0xc1, 0x79, 0xb7, 0x7b, 0x88, 0x9f, 0x99,
-	0x05, 0x54, 0x82, 0xfc, 0x59, 0xef, 0xb8, 0x6f, 0xea, 0xa8, 0x0c, 0xa5, 0xc1, 0xf0, 0x70, 0xd8,
-	0x19, 0x74, 0x86, 0x66, 0xd1, 0x3e, 0x00, 0x7d, 0x40, 0xbc, 0x70, 0x4e, 0xd1, 0x3d, 0x28, 0xbc,
-	0x20, 0xf3, 0x45, 0x7c, 0x36, 0x0a, 0x8e, 0x15, 0xf4, 0x0e, 0x18, 0xdc, 0xf5, 0x28, 0xe3, 0xc4,
-	0x0b, 0xe5, 0x77, 0x6a, 0x38, 0x03, 0xec, 0x9f, 0x15, 0x28, 0x75, 0xae, 0xa8, 0x17, 0xce, 0x49,
-	0x84, 0x26, 0xa0, 0xcb, 0x2e, 0x30, 0x4b, 0xa9, 0x6b, 0x8d, 0x9d, 0xc7, 0x95, 0x26, 0x77, 0x88,
-	0x1f, 0xb0, 0xe6, 0x37, 0x02, 0x6d, 0x1f, 0xbc, 0x7c, 0xbd, 0x97, 0xfb, 0xeb, 0xf5, 0xde, 0xfe,
-	0xcc, 0xe5, 0xce, 0x62, 0xdc, 0x9c, 0x04, 0x5e, 0x2b, 0x76, 0xf8, 0xc4, 0x0d, 0x12, 0xa9, 0x15,
-	0x5e, 0xce, 0x5a, 0x1b, 0x0d, 0x6d, 0x3e, 0x97, 0xd1, 0x38, 0x49, 0x9d, 0xb1, 0x54, 0xdf, 0xc8,
-	0x52, 0xbb, 0xcd, 0xf2, 0x8f, 0x02, 0x18, 0xa7, 0x2e, 0xe3, 0xc1, 0x2c, 0x22, 0x1e, 0x7a, 0x17,
-	0x8c, 0x49, 0xb0, 0xf0, 0xf9, 0xc8, 0xf5, 0xb9, 0xfc, 0xd6, 0xfc, 0x69, 0x0e, 0x97, 0x24, 0x74,
-	0xe6, 0x73, 0xf4, 0x1e, 0xec, 0xc4, 0xe6, 0x8b, 0x79, 0x40, 0x78, 0x5c, 0xe6, 0x34, 0x87, 0x41,
-	0x82, 0xc7, 0x02, 0x43, 0x26, 0x68, 0x6c, 0xe1, 0xc9, 0x3a, 0x0a, 0x16, 0x22, 0xba, 0x0f, 0x3a,
-	0x9b, 0x38, 0xd4, 0x23, 0xb2, 0xd5, 0x77, 0x71, 0xa2, 0xa1, 0x0f, 0xa0, 0xfa, 0x3d, 0x8d, 0x82,
-	0x11, 0x77, 0x22, 0xca, 0x9c, 0x60, 0x3e, 0x95, 0x6d, 0x57, 0x70, 0x45, 0xa0, 0xc3, 0x14, 0x44,
-	0x1f, 0x26, 0x6e, 0x19, 0x2f, 0x5d, 0xf2, 0x52, 0x70, 0x59, 0xe0, 0x47, 0x29, 0xb7, 0x47, 0x60,
-	0xae, 0xf9, 0xc5, 0x04, 0x8b, 0x92, 0xa0, 0x82, 0xab, 0x2b, 0xcf, 0x98, 0x64, 0x1b, 0xaa, 0x3e,
-	0x9d, 0x11, 0xee, 0xbe, 0xa0, 0x23, 0x16, 0x12, 0x9f, 0x59, 0x25, 0xd9, 0x95, 0xff, 0x6f, 0xcd,
-	0x7c, 0x7b, 0x31, 0xb9, 0xa4, 0x7c, 0x10, 0x12, 0x1f, 0x57, 0xd2, 0x10, 0xa1, 0x31, 0xf4, 0x11,
-	0xdc, 0x59, 0xe5, 0x98, 0xd2, 0x39, 0x27, 0xcc, 0x32, 0xea, 0x5a, 0x03, 0xe1, 0x55, 0xea, 0xaf,
-	0x24, 0xba, 0xe1, 0x28, 0xc9, 0x31, 0x0b, 0xea, 0x5a, 0x43, 0xc9, 0x1c, 0x25, 0x33, 0x26, 0x58,
-	0x85, 0x01, 0x73, 0xd7, 0x58, 0xed, 0xfc, 0x07, 0x56, 0x69, 0xc8, 0x8a, 0xd5, 0x2a, 0x47, 0xc2,
-	0xaa, 0x1c, 0xb3, 0x4a, 0xe1, 0x8c, 0xd5, 0xca, 0x31, 0x61, 0x55, 0x89, 0x59, 0xa5, 0x70, 0xc2,
-	0xea, 0x08, 0x20, 0xa2, 0x8c, 0xf2, 0x91, 0x23, 0xce, 0xbe, 0x2a, 0x77, 0xc3, 0xfb, 0x5b, 0x8c,
-	0x56, 0x23, 0xd4, 0xc4, 0xc2, 0xf9, 0xd4, 0xf5, 0x39, 0x36, 0xa2, 0x54, 0xdc, 0x9c, 0xc1, 0x3b,
-	0xb7, 0x67, 0x70, 0x1f, 0x8c, 0x55, 0xd4, 0xe6, 0x0d, 0x2f, 0x82, 0xf6, 0xac, 0x33, 0x30, 0x15,
-	0xa4, 0x83, 0xda, 0xeb, 0x9b, 0x6a, 0x76, 0xcb, 0xb5, 0x76, 0x11, 0x0a, 0x92, 0x78, 0xbb, 0x0c,
-	0x90, 0x75, 0xde, 0x3e, 0x00, 0xc8, 0x8e, 0x47, 0x0c, 0x5f, 0x70, 0x71, 0xc1, 0x68, 0x3c, 0xcd,
-	0x77, 0x71, 0xa2, 0x09, 0x7c, 0x4e, 0xfd, 0x19, 0x77, 0xe4, 0x10, 0x57, 0x70, 0xa2, 0xd9, 0xbf,
-	0xaa, 0x00, 0x43, 0xd7, 0xa3, 0x03, 0x1a, 0xb9, 0x94, 0xbd, 0x9d, 0x6b, 0xfb, 0x19, 0x14, 0x99,
-	0x5c, 0x33, 0xcc, 0x52, 0x65, 0x95, 0x07, 0x5b, 0xc7, 0x1b, 0xaf, 0xa1, 0x76, 0x5e, 0xd4, 0xc3,
-	0xa9, 0x37, 0xfa, 0x1c, 0x0c, 0x9a, 0x2c, 0x18, 0x66, 0x69, 0x32, 0xf4, 0xe1, 0x56, 0x68, 0xba,
-	0x82, 0x92, 0xe0, 0x2c, 0x02, 0x7d, 0x09, 0xe0, 0xa4, 0x6d, 0x63, 0x56, 0x5e, 0xc6, 0xef, 0xbe,
-	0xb9, 0xb3, 0x49, 0x82, 0xb5, 0x18, 0xfb, 0x47, 0x05, 0xca, 0xf2, 0x5b, 0xba, 0x84, 0x4f, 0x1c,
-	0x1a, 0xa1, 0x4f, 0x37, 0x9e, 0x10, 0x7b, 0x2b, 0xd9, 0xba, 0x73, 0x73, 0xed, 0xe9, 0x40, 0x90,
-	0x5f, 0x7b, 0x2c, 0xa4, 0x9c, 0x6d, 0x33, 0x4d, 0x82, 0xb1, 0x62, 0x37, 0x20, 0x2f, 0x1f, 0x02,
-	0x1d, 0xd4, 0xce, 0xd3, 0x78, 0x42, 0x7a, 0x9d, 0xa7, 0xf1, 0x84, 0x60, 0xb1, 0xfc, 0x05, 0x80,
-	0x3b, 0xa6, 0x66, 0xff, 0xa6, 0x88, 0xb1, 0x22, 0x53, 0x31, 0x55, 0x0c, 0x3d, 0x80, 0x22, 0xe3,
-	0x34, 0x1c, 0x79, 0x4c, 0x92, 0xd3, 0xb0, 0x2e, 0xd4, 0x2e, 0x13, 0xa5, 0x2f, 0x16, 0xfe, 0x24,
-	0x2d, 0x2d, 0x64, 0xf4, 0x10, 0x4a, 0x8c, 0x93, 0x88, 0x0b, 0xef, 0x78, 0x63, 0x16, 0xa5, 0xde,
-	0x65, 0xe8, 0x7f, 0xa0, 0x53, 0x7f, 0x3a, 0x92, 0x07, 0x26, 0x0c, 0x05, 0xea, 0x4f, 0xbb, 0x0c,
-	0xed, 0x42, 0x69, 0x16, 0x05, 0x8b, 0xd0, 0xf5, 0x67, 0x56, 0xa1, 0xae, 0x35, 0x0c, 0xbc, 0xd2,
-	0x51, 0x15, 0xd4, 0xf1, 0x52, 0x6e, 0xad, 0x12, 0x56, 0xc7, 0x4b, 0x91, 0x3d, 0x22, 0xfe, 0x8c,
-	0x8a, 0x24, 0xc5, 0x38, 0xbb, 0xd4, 0xbb, 0xcc, 0xfe, 0x5d, 0x81, 0xc2, 0x91, 0xb3, 0xf0, 0x2f,
-	0x51, 0x0d, 0x76, 0x3c, 0xd7, 0x1f, 0x89, 0x4b, 0x92, 0x71, 0x36, 0x3c, 0xd7, 0x17, 0xd3, 0xd9,
-	0x65, 0xd2, 0x4e, 0xae, 0x56, 0xf6, 0xe4, 0xf5, 0xf1, 0xc8, 0x55, 0x62, 0x7f, 0x92, 0x74, 0x42,
-	0x93, 0x9d, 0xd8, 0xdb, 0xea, 0x84, 0xac, 0xd2, 0xec, 0xf8, 0x93, 0x60, 0xea, 0xfa, 0xb3, 0xac,
-	0x0d, 0xe2, 0x69, 0x97, 0x9f, 0x56, 0xc6, 0x52, 0xb6, 0x5b, 0x50, 0x4a, 0xbd, 0xb6, 0xee, 0xe6,
-	0x77, 0x7d, 0xf1, 0xf2, 0x6e, 0x3c, 0xb7, 0xaa, 0xfd, 0x8b, 0x02, 0x15, 0x99, 0x9d, 0x4e, 0xdf,
-	0xe6, 0x2d, 0xda, 0x07, 0x7d, 0x22, 0xaa, 0xa6, 0x97, 0xe8, 0xfe, 0xbf, 0x7f, 0x72, 0x32, 0xc5,
-	0x89, 0x6f, 0xbb, 0xfe, 0xf2, 0xba, 0xa6, 0xbc, 0xba, 0xae, 0x29, 0x7f, 0x5f, 0xd7, 0x94, 0x1f,
-	0x6e, 0x6a, 0xb9, 0x57, 0x37, 0xb5, 0xdc, 0x9f, 0x37, 0xb5, 0xdc, 0x73, 0x3d, 0xfe, 0xdb, 0x35,
-	0xd6, 0xe5, 0xff, 0xa5, 0x27, 0xff, 0x04, 0x00, 0x00, 0xff, 0xff, 0x0e, 0x67, 0xfa, 0x2f, 0x95,
-	0x09, 0x00, 0x00,
+	// 1140 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x56, 0xcf, 0x8f, 0xda, 0xc6,
+	0x17, 0xc7, 0x36, 0x18, 0xfc, 0x16, 0x88, 0x33, 0xca, 0x37, 0x71, 0xf6, 0xdb, 0x12, 0x6a, 0xf5,
+	0x07, 0x8a, 0x5a, 0x90, 0x92, 0xa8, 0xbd, 0x6c, 0xab, 0x2e, 0x5b, 0x76, 0x59, 0xb5, 0x80, 0x32,
+	0xb0, 0x6a, 0x93, 0x0b, 0x1a, 0x60, 0x16, 0x5b, 0x8b, 0x7f, 0xc8, 0x33, 0x44, 0x4b, 0xff, 0x8a,
+	0x9e, 0x7b, 0xab, 0x7a, 0x6b, 0x4f, 0xfd, 0x13, 0x7a, 0xcb, 0x31, 0xc7, 0x2a, 0x87, 0xa8, 0xda,
+	0xfd, 0x47, 0xaa, 0x19, 0xdb, 0x18, 0x96, 0x46, 0xea, 0x29, 0x17, 0xf4, 0xde, 0xe7, 0xfd, 0xfa,
+	0x8c, 0xdf, 0x9b, 0x79, 0x40, 0x9d, 0xf1, 0x20, 0xa2, 0x2d, 0xf9, 0x1b, 0x4e, 0x5a, 0x61, 0x14,
+	0x78, 0xe1, 0xa4, 0xc5, 0x57, 0x21, 0x65, 0xcd, 0x30, 0x0a, 0x78, 0x80, 0x6e, 0x09, 0x8c, 0x72,
+	0x87, 0x2e, 0xd9, 0x78, 0x1a, 0x84, 0xab, 0xfd, 0x3b, 0xf3, 0x60, 0x1e, 0x48, 0x5b, 0x4b, 0x48,
+	0xb1, 0xdb, 0xfe, 0xfd, 0x38, 0xd1, 0x82, 0x4c, 0xe8, 0x62, 0x3b, 0x83, 0xfd, 0x8b, 0x0a, 0xd5,
+	0x1e, 0xe5, 0x91, 0x3b, 0xed, 0x51, 0x4e, 0x66, 0x84, 0x13, 0xf4, 0x15, 0xe4, 0x85, 0x87, 0xa5,
+	0xd4, 0x95, 0x46, 0xf5, 0xd1, 0xc3, 0xe6, 0x8d, 0x1a, 0xcd, 0x6d, 0xf7, 0x44, 0x1d, 0xad, 0x42,
+	0x8a, 0x65, 0x1c, 0xfa, 0x14, 0x90, 0x27, 0xb1, 0xf1, 0x39, 0xf1, 0xdc, 0xc5, 0x6a, 0xec, 0x13,
+	0x8f, 0x5a, 0x6a, 0x5d, 0x69, 0x18, 0xd8, 0x8c, 0x2d, 0xc7, 0xd2, 0xd0, 0x27, 0x1e, 0x45, 0x08,
+	0xf2, 0x0e, 0x5d, 0x84, 0x56, 0x5e, 0xda, 0xa5, 0x2c, 0xb0, 0xa5, 0xef, 0x72, 0xab, 0x10, 0x63,
+	0x42, 0xb6, 0x57, 0x00, 0x59, 0x25, 0xb4, 0x07, 0xc5, 0xb3, 0xfe, 0xb7, 0xfd, 0xc1, 0xf7, 0x7d,
+	0x33, 0x27, 0x94, 0xa3, 0xc1, 0x59, 0x7f, 0xd4, 0xc1, 0xa6, 0x82, 0x0c, 0x28, 0x9c, 0x1c, 0x9e,
+	0x9d, 0x74, 0x4c, 0x15, 0x55, 0xc0, 0xe8, 0x9e, 0x0e, 0x47, 0x83, 0x13, 0x7c, 0xd8, 0x33, 0x35,
+	0x84, 0xa0, 0x2a, 0x2d, 0x19, 0x96, 0x17, 0xa1, 0xc3, 0xb3, 0x5e, 0xef, 0x10, 0x3f, 0x33, 0x0b,
+	0xa8, 0x04, 0xf9, 0xd3, 0xfe, 0xf1, 0xc0, 0xd4, 0x51, 0x19, 0x4a, 0xc3, 0xd1, 0xe1, 0xa8, 0x33,
+	0xec, 0x8c, 0xcc, 0xa2, 0x7d, 0x00, 0xfa, 0x90, 0x78, 0xe1, 0x82, 0xa2, 0x3b, 0x50, 0x78, 0x41,
+	0x16, 0xcb, 0xf8, 0xdb, 0x28, 0x38, 0x56, 0xd0, 0x7b, 0x60, 0x70, 0xd7, 0xa3, 0x8c, 0x13, 0x2f,
+	0x94, 0xe7, 0xd4, 0x70, 0x06, 0xd8, 0xbf, 0x2a, 0x50, 0xea, 0x5c, 0x52, 0x2f, 0x5c, 0x90, 0x08,
+	0x4d, 0x41, 0x97, 0x5d, 0x60, 0x96, 0x52, 0xd7, 0x1a, 0x7b, 0x8f, 0x2a, 0x4d, 0xee, 0x10, 0x3f,
+	0x60, 0xcd, 0xef, 0x04, 0xda, 0x3e, 0x78, 0xf9, 0xe6, 0x41, 0xee, 0xf5, 0x9b, 0x07, 0x4f, 0xe6,
+	0x2e, 0x77, 0x96, 0x93, 0xe6, 0x34, 0xf0, 0x5a, 0xb1, 0xc3, 0x67, 0x6e, 0x90, 0x48, 0xad, 0xf0,
+	0x62, 0xde, 0xda, 0x6a, 0x68, 0xf3, 0xb9, 0x8c, 0xc6, 0x49, 0xea, 0x8c, 0xa5, 0xfa, 0x56, 0x96,
+	0xda, 0x4d, 0x96, 0xaf, 0x0b, 0x60, 0x74, 0x5d, 0xc6, 0x83, 0x79, 0x44, 0x3c, 0xf4, 0x3e, 0x18,
+	0xd3, 0x60, 0xe9, 0xf3, 0xb1, 0xeb, 0x73, 0x79, 0xd6, 0x7c, 0x37, 0x87, 0x4b, 0x12, 0x3a, 0xf5,
+	0x39, 0xfa, 0x00, 0xf6, 0x62, 0xf3, 0xf9, 0x22, 0x20, 0x3c, 0x2e, 0xd3, 0xcd, 0x61, 0x90, 0xe0,
+	0xb1, 0xc0, 0x90, 0x09, 0x1a, 0x5b, 0x7a, 0xb2, 0x8e, 0x82, 0x85, 0x88, 0xee, 0x82, 0xce, 0xa6,
+	0x0e, 0xf5, 0x88, 0x6c, 0xf5, 0x6d, 0x9c, 0x68, 0xe8, 0x23, 0xa8, 0xfe, 0x48, 0xa3, 0x60, 0xcc,
+	0x9d, 0x88, 0x32, 0x27, 0x58, 0xcc, 0x64, 0xdb, 0x15, 0x5c, 0x11, 0xe8, 0x28, 0x05, 0xd1, 0xc7,
+	0x89, 0x5b, 0xc6, 0x4b, 0x97, 0xbc, 0x14, 0x5c, 0x16, 0xf8, 0x51, 0xca, 0xed, 0x21, 0x98, 0x1b,
+	0x7e, 0x31, 0xc1, 0xa2, 0x24, 0xa8, 0xe0, 0xea, 0xda, 0x33, 0x26, 0xd9, 0x85, 0xaa, 0x4f, 0xe7,
+	0x84, 0xbb, 0x2f, 0xe8, 0x98, 0x85, 0xc4, 0x67, 0x56, 0x49, 0x76, 0xe5, 0xff, 0x3b, 0x33, 0xdf,
+	0x5e, 0x4e, 0x2f, 0x28, 0x1f, 0x86, 0xc4, 0x6f, 0xe7, 0x45, 0x8f, 0x70, 0x25, 0x0d, 0x14, 0x18,
+	0x43, 0x9f, 0xc0, 0xad, 0x75, 0xa6, 0x19, 0x5d, 0x70, 0xc2, 0x2c, 0xa3, 0xae, 0x35, 0x10, 0x5e,
+	0x17, 0xf8, 0x46, 0xa2, 0x5b, 0x8e, 0x92, 0x22, 0xb3, 0xa0, 0xae, 0x35, 0x94, 0xcc, 0x51, 0xf2,
+	0x63, 0x82, 0x5b, 0x18, 0x30, 0x77, 0x83, 0xdb, 0xde, 0x7f, 0xe6, 0x96, 0x06, 0xae, 0xb9, 0xad,
+	0x33, 0x25, 0xdc, 0xca, 0x31, 0xb7, 0x14, 0xce, 0xb8, 0xad, 0x1d, 0x13, 0x6e, 0x95, 0x98, 0x5b,
+	0x0a, 0x27, 0xdc, 0x8e, 0x00, 0x22, 0xca, 0x28, 0x1f, 0x3b, 0xa2, 0x0f, 0x55, 0xf9, 0x4e, 0x7c,
+	0xb8, 0xc3, 0x6b, 0x3d, 0x4e, 0x4d, 0x2c, 0x9c, 0xbb, 0xae, 0xcf, 0xb1, 0x11, 0xa5, 0xe2, 0xf6,
+	0x3c, 0xde, 0xba, 0x39, 0x8f, 0x4f, 0xc0, 0x58, 0x47, 0x6d, 0xdf, 0xf6, 0x22, 0x68, 0xcf, 0x3a,
+	0x43, 0x53, 0x41, 0x3a, 0xa8, 0xfd, 0x81, 0xa9, 0x66, 0x37, 0x5e, 0x6b, 0x17, 0xa1, 0x20, 0x89,
+	0xb7, 0xcb, 0x00, 0xd9, 0x14, 0xd8, 0x07, 0x00, 0xd9, 0x47, 0x12, 0x83, 0x18, 0x9c, 0x9f, 0x33,
+	0x1a, 0x4f, 0xf6, 0x6d, 0x9c, 0x68, 0x02, 0x5f, 0x50, 0x7f, 0xce, 0x1d, 0x39, 0xd0, 0x15, 0x9c,
+	0x68, 0xf6, 0xef, 0x2a, 0xc0, 0xc8, 0xf5, 0xe8, 0x90, 0x46, 0x2e, 0x65, 0xef, 0xe6, 0x0a, 0x7f,
+	0x01, 0x45, 0x26, 0x9f, 0x1c, 0x66, 0xa9, 0xb2, 0xca, 0xbd, 0x9d, 0xcf, 0x1b, 0x3f, 0x49, 0x49,
+	0xcb, 0x53, 0x6f, 0xf4, 0x25, 0x18, 0x34, 0x79, 0x6c, 0x98, 0xa5, 0xc9, 0xd0, 0xfb, 0x3b, 0xa1,
+	0xe9, 0x73, 0x94, 0x04, 0x67, 0x11, 0xe8, 0x6b, 0x00, 0x27, 0x6d, 0x1b, 0xb3, 0xf2, 0x32, 0x7e,
+	0xff, 0xed, 0x9d, 0x4d, 0x12, 0x6c, 0xc4, 0xd8, 0x3f, 0x2b, 0x50, 0x96, 0x67, 0xe9, 0x11, 0x3e,
+	0x75, 0x68, 0x84, 0x3e, 0xdf, 0x5a, 0x27, 0xf6, 0x4e, 0xb2, 0x4d, 0xe7, 0xe6, 0xc6, 0x1a, 0x41,
+	0x90, 0xdf, 0x58, 0x1c, 0x52, 0xce, 0x5e, 0x36, 0x4d, 0x82, 0xb1, 0x62, 0x37, 0x20, 0x2f, 0x97,
+	0x82, 0x0e, 0x6a, 0xe7, 0x69, 0x3c, 0x21, 0xfd, 0xce, 0xd3, 0x78, 0x42, 0xb0, 0x58, 0x04, 0x02,
+	0xc0, 0x1d, 0x53, 0xb3, 0xff, 0x50, 0xc4, 0x58, 0x91, 0x99, 0x98, 0x2a, 0x86, 0xee, 0x41, 0x91,
+	0x71, 0x1a, 0x8e, 0x3d, 0x26, 0xc9, 0x69, 0x58, 0x17, 0x6a, 0x8f, 0x89, 0xd2, 0xe7, 0x4b, 0x7f,
+	0x9a, 0x96, 0x16, 0x32, 0xba, 0x0f, 0x25, 0xc6, 0x49, 0xc4, 0x85, 0x77, 0xfc, 0x7a, 0x16, 0xa5,
+	0xde, 0x63, 0xe8, 0x7f, 0xa0, 0x53, 0x7f, 0x36, 0x96, 0x1f, 0x4c, 0x18, 0x0a, 0xd4, 0x9f, 0xf5,
+	0x18, 0xda, 0x87, 0xd2, 0x3c, 0x0a, 0x96, 0xa1, 0xeb, 0xcf, 0xad, 0x42, 0x5d, 0x6b, 0x18, 0x78,
+	0xad, 0xa3, 0x2a, 0xa8, 0x93, 0x95, 0x7c, 0xc1, 0x4a, 0x58, 0x9d, 0xac, 0x44, 0xf6, 0x88, 0xf8,
+	0x73, 0x2a, 0x92, 0x14, 0xe3, 0xec, 0x52, 0xef, 0x31, 0xfb, 0x4f, 0x05, 0x0a, 0x47, 0xce, 0xd2,
+	0xbf, 0x40, 0x35, 0xd8, 0xf3, 0x5c, 0x7f, 0x2c, 0x2e, 0x49, 0xc6, 0xd9, 0xf0, 0x5c, 0x5f, 0x4c,
+	0x67, 0x8f, 0x49, 0x3b, 0xb9, 0x5c, 0xdb, 0x93, 0x4d, 0xe4, 0x91, 0xcb, 0xc4, 0xfe, 0x38, 0xe9,
+	0x84, 0x26, 0x3b, 0xf1, 0x60, 0xa7, 0x13, 0xb2, 0x4a, 0xb3, 0xe3, 0x4f, 0x83, 0x99, 0xeb, 0xcf,
+	0xb3, 0x36, 0x88, 0x35, 0x2f, 0x8f, 0x56, 0xc6, 0x52, 0xb6, 0x5b, 0x50, 0x4a, 0xbd, 0x76, 0xee,
+	0xe6, 0x0f, 0x03, 0xb1, 0x85, 0xb7, 0x56, 0xaf, 0x6a, 0xff, 0xa6, 0x40, 0x45, 0x66, 0xa7, 0xb3,
+	0x77, 0x79, 0x8b, 0x9e, 0x80, 0x3e, 0x15, 0x55, 0xd3, 0x4b, 0x74, 0xf7, 0xdf, 0x8f, 0x9c, 0x4c,
+	0x71, 0xe2, 0xdb, 0xae, 0xbf, 0xbc, 0xaa, 0x29, 0xaf, 0xae, 0x6a, 0xca, 0xdf, 0x57, 0x35, 0xe5,
+	0xa7, 0xeb, 0x5a, 0xee, 0xd5, 0x75, 0x2d, 0xf7, 0xd7, 0x75, 0x2d, 0xf7, 0x5c, 0x8f, 0xff, 0x82,
+	0x4d, 0x74, 0xf9, 0xdf, 0xe9, 0xf1, 0x3f, 0x01, 0x00, 0x00, 0xff, 0xff, 0x98, 0x09, 0x9b, 0xd5,
+	0xa1, 0x09, 0x00, 0x00,
 }
 
 func (m *MetricMetadata) Marshal() (dAtA []byte, err error) {
@@ -2559,7 +2559,7 @@ func (m *Histogram) Unmarshal(dAtA []byte) error {
 			if postIndex > l {
 				return io.ErrUnexpectedEOF
 			}
-			m.NegativeSpans = append(m.NegativeSpans, &BucketSpan{})
+			m.NegativeSpans = append(m.NegativeSpans, BucketSpan{})
 			if err := m.NegativeSpans[len(m.NegativeSpans)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
 				return err
 			}
@@ -2725,7 +2725,7 @@ func (m *Histogram) Unmarshal(dAtA []byte) error {
 			if postIndex > l {
 				return io.ErrUnexpectedEOF
 			}
-			m.PositiveSpans = append(m.PositiveSpans, &BucketSpan{})
+			m.PositiveSpans = append(m.PositiveSpans, BucketSpan{})
 			if err := m.PositiveSpans[len(m.PositiveSpans)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
 				return err
 			}
diff --git a/pkg/store/storepb/prompb/types.proto b/pkg/store/storepb/prompb/types.proto
index 0fea825508b..bf00b62e8fc 100644
--- a/pkg/store/storepb/prompb/types.proto
+++ b/pkg/store/storepb/prompb/types.proto
@@ -94,9 +94,9 @@ message Histogram {
     uint64 zero_count_int     = 6;
     double zero_count_float   = 7;
   }
-  
+
   // Negative Buckets.
-  repeated BucketSpan negative_spans =  8;
+  repeated BucketSpan negative_spans =  8 [(gogoproto.nullable) = false];
   // Use either "negative_deltas" or "negative_counts", the former for
   // regular histograms with integer counts, the latter for float
   // histograms.
@@ -104,7 +104,7 @@ message Histogram {
   repeated double negative_counts    = 10; // Absolute count of each bucket.
 
   // Positive Buckets.
-  repeated BucketSpan positive_spans = 11;
+  repeated BucketSpan positive_spans = 11 [(gogoproto.nullable) = false];
   // Use either "positive_deltas" or "positive_counts", the former for
   // regular histograms with integer counts, the latter for float
   // histograms.
diff --git a/pkg/store/storepb/types.pb.go b/pkg/store/storepb/types.pb.go
index a87a135ba0a..401dcad2dc9 100644
--- a/pkg/store/storepb/types.pb.go
+++ b/pkg/store/storepb/types.pb.go
@@ -63,18 +63,21 @@ func (PartialResponseStrategy) EnumDescriptor() ([]byte, []int) {
 type Chunk_Encoding int32
 
 const (
-	Chunk_XOR       Chunk_Encoding = 0
-	Chunk_HISTOGRAM Chunk_Encoding = 1
+	Chunk_XOR             Chunk_Encoding = 0
+	Chunk_HISTOGRAM       Chunk_Encoding = 1
+	Chunk_FLOAT_HISTOGRAM Chunk_Encoding = 2
 )
 
 var Chunk_Encoding_name = map[int32]string{
 	0: "XOR",
 	1: "HISTOGRAM",
+	2: "FLOAT_HISTOGRAM",
 }
 
 var Chunk_Encoding_value = map[string]int32{
-	"XOR":       0,
-	"HISTOGRAM": 1,
+	"XOR":             0,
+	"HISTOGRAM":       1,
+	"FLOAT_HISTOGRAM": 2,
 }
 
 func (x Chunk_Encoding) String() string {
@@ -290,42 +293,43 @@ func init() {
 func init() { proto.RegisterFile("store/storepb/types.proto", fileDescriptor_121fba57de02d8e0) }
 
 var fileDescriptor_121fba57de02d8e0 = []byte{
-	// 553 bytes of a gzipped FileDescriptorProto
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0x93, 0xcf, 0x6e, 0xd3, 0x4e,
-	0x10, 0xc7, 0xbd, 0xb6, 0xe3, 0x24, 0xf3, 0x6b, 0x7f, 0x32, 0xab, 0x0a, 0xdc, 0x1e, 0x9c, 0xc8,
-	0x08, 0x11, 0x55, 0xaa, 0x2d, 0x15, 0x8e, 0x5c, 0x12, 0x14, 0x01, 0x12, 0x6d, 0xe8, 0x26, 0x12,
-	0xa8, 0x17, 0xb4, 0x71, 0x57, 0xb6, 0xd5, 0xf8, 0x8f, 0xbc, 0x6b, 0x48, 0x1e, 0x80, 0x3b, 0x88,
-	0x3b, 0xcf, 0x93, 0x63, 0x8f, 0x88, 0x43, 0x04, 0xc9, 0x8b, 0x20, 0xaf, 0x1d, 0x20, 0x52, 0x2e,
-	0xd6, 0x78, 0x3e, 0xdf, 0x99, 0xd9, 0x99, 0x9d, 0x85, 0x63, 0x2e, 0xd2, 0x9c, 0x79, 0xf2, 0x9b,
-	0x4d, 0x3d, 0xb1, 0xc8, 0x18, 0x77, 0xb3, 0x3c, 0x15, 0x29, 0x36, 0x44, 0x48, 0x93, 0x94, 0x9f,
-	0x1c, 0x05, 0x69, 0x90, 0x4a, 0x97, 0x57, 0x5a, 0x15, 0x3d, 0xa9, 0x03, 0x67, 0x74, 0xca, 0x66,
-	0xbb, 0x81, 0xce, 0x27, 0x04, 0x8d, 0xe7, 0x61, 0x91, 0xdc, 0xe2, 0x53, 0xd0, 0x4b, 0x60, 0xa1,
-	0x2e, 0xea, 0xfd, 0x7f, 0x7e, 0xdf, 0xad, 0x32, 0xba, 0x12, 0xba, 0xc3, 0xc4, 0x4f, 0x6f, 0xa2,
-	0x24, 0x20, 0x52, 0x83, 0x31, 0xe8, 0x37, 0x54, 0x50, 0x4b, 0xed, 0xa2, 0xde, 0x01, 0x91, 0x36,
-	0xb6, 0x40, 0x0f, 0x29, 0x0f, 0x2d, 0xad, 0x8b, 0x7a, 0xfa, 0x40, 0x5f, 0xae, 0x3a, 0x88, 0x48,
-	0x8f, 0xe3, 0x40, 0x6b, 0x1b, 0x8f, 0x9b, 0xa0, 0xbd, 0x1b, 0x11, 0x53, 0xc1, 0x87, 0xd0, 0x7e,
-	0xf9, 0x6a, 0x3c, 0x19, 0xbd, 0x20, 0xfd, 0x0b, 0x13, 0x39, 0xdf, 0x10, 0x18, 0x63, 0x96, 0x47,
-	0x8c, 0x63, 0x1f, 0x0c, 0x79, 0x52, 0x6e, 0xa1, 0xae, 0xd6, 0xfb, 0xef, 0xfc, 0x70, 0x7b, 0x94,
-	0xd7, 0xa5, 0x77, 0xf0, 0x6c, 0xb9, 0xea, 0x28, 0x3f, 0x56, 0x9d, 0xa7, 0x41, 0x24, 0xc2, 0x62,
-	0xea, 0xfa, 0x69, 0xec, 0x55, 0x82, 0xb3, 0x28, 0xad, 0x2d, 0x2f, 0xbb, 0x0d, 0xbc, 0x9d, 0xa6,
-	0xdd, 0x6b, 0x19, 0x4d, 0xea, 0xd4, 0xd8, 0x03, 0xc3, 0x2f, 0x3b, 0xe3, 0x96, 0x2a, 0x8b, 0xdc,
-	0xdb, 0x16, 0xe9, 0x07, 0x41, 0x2e, 0x7b, 0x96, 0x2d, 0x28, 0xa4, 0x96, 0x39, 0x5f, 0x55, 0x68,
-	0xff, 0x61, 0xf8, 0x18, 0x5a, 0x71, 0x94, 0xbc, 0x17, 0x51, 0x5c, 0x0d, 0x4c, 0x23, 0xcd, 0x38,
-	0x4a, 0x26, 0x51, 0xcc, 0x24, 0xa2, 0xf3, 0x0a, 0xa9, 0x35, 0xa2, 0x73, 0x89, 0x3a, 0xa0, 0xe5,
-	0xf4, 0xa3, 0x9c, 0xd0, 0x3f, 0x6d, 0xc9, 0x8c, 0xa4, 0x24, 0xf8, 0x21, 0x34, 0xfc, 0xb4, 0x48,
-	0x84, 0xa5, 0xef, 0x93, 0x54, 0xac, 0xcc, 0xc2, 0x8b, 0xd8, 0x6a, 0xec, 0xcd, 0xc2, 0x8b, 0xb8,
-	0x14, 0xc4, 0x51, 0x62, 0x19, 0x7b, 0x05, 0x71, 0x94, 0x48, 0x01, 0x9d, 0x5b, 0xcd, 0xfd, 0x02,
-	0x3a, 0xc7, 0x8f, 0xa1, 0x29, 0x6b, 0xb1, 0xdc, 0x6a, 0xed, 0x13, 0x6d, 0xa9, 0xf3, 0x05, 0xc1,
-	0x81, 0x1c, 0xec, 0x05, 0x15, 0x7e, 0xc8, 0x72, 0x7c, 0xb6, 0xb3, 0x45, 0xc7, 0x3b, 0x57, 0x57,
-	0x6b, 0xdc, 0xc9, 0x22, 0x63, 0x7f, 0x17, 0x29, 0xa1, 0xf5, 0xa0, 0xda, 0x44, 0xda, 0xf8, 0x08,
-	0x1a, 0x1f, 0xe8, 0xac, 0x60, 0x72, 0x4e, 0x6d, 0x52, 0xfd, 0x38, 0x3d, 0xd0, 0xcb, 0x38, 0x6c,
-	0x80, 0x3a, 0xbc, 0x32, 0x95, 0x72, 0x91, 0x2e, 0x87, 0x57, 0x26, 0x2a, 0x1d, 0x64, 0x68, 0xaa,
-	0xd2, 0x41, 0x86, 0xa6, 0x76, 0xea, 0xc2, 0x83, 0x37, 0x34, 0x17, 0x11, 0x9d, 0x11, 0xc6, 0xb3,
-	0x34, 0xe1, 0x6c, 0x2c, 0x72, 0x2a, 0x58, 0xb0, 0xc0, 0x2d, 0xd0, 0xdf, 0xf6, 0xc9, 0xa5, 0xa9,
-	0xe0, 0x36, 0x34, 0xfa, 0x83, 0x11, 0x99, 0x98, 0x68, 0xf0, 0x68, 0xf9, 0xcb, 0x56, 0x96, 0x6b,
-	0x1b, 0xdd, 0xad, 0x6d, 0xf4, 0x73, 0x6d, 0xa3, 0xcf, 0x1b, 0x5b, 0xb9, 0xdb, 0xd8, 0xca, 0xf7,
-	0x8d, 0xad, 0x5c, 0x37, 0xeb, 0xe7, 0x36, 0x35, 0xe4, 0x83, 0x79, 0xf2, 0x3b, 0x00, 0x00, 0xff,
-	0xff, 0x44, 0x9d, 0x95, 0xa2, 0x86, 0x03, 0x00, 0x00,
+	// 565 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0x53, 0x4d, 0x6f, 0xd3, 0x40,
+	0x10, 0xf5, 0xda, 0x8e, 0x93, 0x0c, 0x2d, 0x98, 0xa5, 0x02, 0xb7, 0x07, 0x27, 0x32, 0x42, 0x44,
+	0x95, 0x6a, 0x4b, 0x05, 0x89, 0x0b, 0x97, 0x04, 0x85, 0x0f, 0xa9, 0x6d, 0xe8, 0x26, 0x12, 0xa8,
+	0x97, 0x6a, 0xe3, 0xae, 0x6c, 0xab, 0xf1, 0x87, 0xec, 0x35, 0x24, 0xff, 0x02, 0xc4, 0x8d, 0x03,
+	0xbf, 0x27, 0xc7, 0x1e, 0x11, 0x87, 0x08, 0x92, 0x3f, 0x82, 0xbc, 0x76, 0x28, 0x91, 0x72, 0xb1,
+	0xc6, 0xef, 0xbd, 0x99, 0xd9, 0x79, 0x3b, 0x0b, 0xfb, 0x19, 0x8f, 0x53, 0xe6, 0x88, 0x6f, 0x32,
+	0x76, 0xf8, 0x2c, 0x61, 0x99, 0x9d, 0xa4, 0x31, 0x8f, 0xb1, 0xc6, 0x7d, 0x1a, 0xc5, 0xd9, 0xc1,
+	0x9e, 0x17, 0x7b, 0xb1, 0x80, 0x9c, 0x22, 0x2a, 0xd9, 0x83, 0x2a, 0x71, 0x42, 0xc7, 0x6c, 0xb2,
+	0x99, 0x68, 0x7d, 0x47, 0x50, 0x7b, 0xe5, 0xe7, 0xd1, 0x35, 0x3e, 0x04, 0xb5, 0x20, 0x0c, 0xd4,
+	0x46, 0x9d, 0xbb, 0xc7, 0x0f, 0xed, 0xb2, 0xa2, 0x2d, 0x48, 0xbb, 0x1f, 0xb9, 0xf1, 0x55, 0x10,
+	0x79, 0x44, 0x68, 0x30, 0x06, 0xf5, 0x8a, 0x72, 0x6a, 0xc8, 0x6d, 0xd4, 0xd9, 0x21, 0x22, 0xc6,
+	0x06, 0xa8, 0x3e, 0xcd, 0x7c, 0x43, 0x69, 0xa3, 0x8e, 0xda, 0x53, 0xe7, 0x8b, 0x16, 0x22, 0x02,
+	0xb1, 0x5e, 0x40, 0x63, 0x9d, 0x8f, 0xeb, 0xa0, 0x7c, 0x1c, 0x10, 0x5d, 0xc2, 0xbb, 0xd0, 0x7c,
+	0xfb, 0x6e, 0x38, 0x1a, 0xbc, 0x21, 0xdd, 0x53, 0x1d, 0xe1, 0x07, 0x70, 0xef, 0xf5, 0xc9, 0xa0,
+	0x3b, 0xba, 0xbc, 0x05, 0x65, 0xeb, 0x07, 0x02, 0x6d, 0xc8, 0xd2, 0x80, 0x65, 0xd8, 0x05, 0x4d,
+	0x1c, 0x3f, 0x33, 0x50, 0x5b, 0xe9, 0xdc, 0x39, 0xde, 0x5d, 0x9f, 0xef, 0xa4, 0x40, 0x7b, 0x2f,
+	0xe7, 0x8b, 0x96, 0xf4, 0x6b, 0xd1, 0x7a, 0xee, 0x05, 0xdc, 0xcf, 0xc7, 0xb6, 0x1b, 0x87, 0x4e,
+	0x29, 0x38, 0x0a, 0xe2, 0x2a, 0x72, 0x92, 0x6b, 0xcf, 0xd9, 0x70, 0xc2, 0xbe, 0x10, 0xd9, 0xa4,
+	0x2a, 0x8d, 0x1d, 0xd0, 0xdc, 0x62, 0xdc, 0xcc, 0x90, 0x45, 0x93, 0xfb, 0xeb, 0x26, 0x5d, 0xcf,
+	0x4b, 0x85, 0x11, 0x62, 0x2e, 0x89, 0x54, 0x32, 0xeb, 0x9b, 0x0c, 0xcd, 0x7f, 0x1c, 0xde, 0x87,
+	0x46, 0x18, 0x44, 0x97, 0x3c, 0x08, 0x4b, 0x17, 0x15, 0x52, 0x0f, 0x83, 0x68, 0x14, 0x84, 0x4c,
+	0x50, 0x74, 0x5a, 0x52, 0x72, 0x45, 0xd1, 0xa9, 0xa0, 0x5a, 0xa0, 0xa4, 0xf4, 0xb3, 0xb0, 0xed,
+	0xbf, 0xb1, 0x44, 0x45, 0x52, 0x30, 0xf8, 0x31, 0xd4, 0xdc, 0x38, 0x8f, 0xb8, 0xa1, 0x6e, 0x93,
+	0x94, 0x5c, 0x51, 0x25, 0xcb, 0x43, 0xa3, 0xb6, 0xb5, 0x4a, 0x96, 0x87, 0x85, 0x20, 0x0c, 0x22,
+	0x43, 0xdb, 0x2a, 0x08, 0x83, 0x48, 0x08, 0xe8, 0xd4, 0xa8, 0x6f, 0x17, 0xd0, 0x29, 0x7e, 0x0a,
+	0x75, 0xd1, 0x8b, 0xa5, 0x46, 0x63, 0x9b, 0x68, 0xcd, 0x5a, 0x5f, 0x11, 0xec, 0x08, 0x63, 0x4f,
+	0x29, 0x77, 0x7d, 0x96, 0xe2, 0xa3, 0x8d, 0xd5, 0xda, 0xdf, 0xb8, 0xba, 0x4a, 0x63, 0x8f, 0x66,
+	0x09, 0xbb, 0xdd, 0xae, 0x88, 0x56, 0x46, 0x35, 0x89, 0x88, 0xf1, 0x1e, 0xd4, 0x3e, 0xd1, 0x49,
+	0xce, 0x84, 0x4f, 0x4d, 0x52, 0xfe, 0x58, 0x1d, 0x50, 0x8b, 0x3c, 0xac, 0x81, 0xdc, 0x3f, 0xd7,
+	0xa5, 0x62, 0xbb, 0xce, 0xfa, 0xe7, 0x3a, 0x2a, 0x00, 0xd2, 0xd7, 0x65, 0x01, 0x90, 0xbe, 0xae,
+	0x1c, 0xda, 0xf0, 0xe8, 0x3d, 0x4d, 0x79, 0x40, 0x27, 0x84, 0x65, 0x49, 0x1c, 0x65, 0x6c, 0xc8,
+	0x53, 0xca, 0x99, 0x37, 0xc3, 0x0d, 0x50, 0x3f, 0x74, 0xc9, 0x99, 0x2e, 0xe1, 0x26, 0xd4, 0xba,
+	0xbd, 0x01, 0x19, 0xe9, 0xa8, 0xf7, 0x64, 0xfe, 0xc7, 0x94, 0xe6, 0x4b, 0x13, 0xdd, 0x2c, 0x4d,
+	0xf4, 0x7b, 0x69, 0xa2, 0x2f, 0x2b, 0x53, 0xba, 0x59, 0x99, 0xd2, 0xcf, 0x95, 0x29, 0x5d, 0xd4,
+	0xab, 0x37, 0x38, 0xd6, 0xc4, 0x2b, 0x7a, 0xf6, 0x37, 0x00, 0x00, 0xff, 0xff, 0x9e, 0x6d, 0x25,
+	0xf3, 0x9b, 0x03, 0x00, 0x00,
 }
 
 func (m *Chunk) Marshal() (dAtA []byte, err error) {
diff --git a/pkg/store/storepb/types.proto b/pkg/store/storepb/types.proto
index 67c93fa52ed..840d3c51881 100644
--- a/pkg/store/storepb/types.proto
+++ b/pkg/store/storepb/types.proto
@@ -24,6 +24,7 @@ message Chunk {
   enum Encoding {
     XOR = 0;
     HISTOGRAM = 1;
+    FLOAT_HISTOGRAM = 2;
   }
   Encoding type  = 1;
   bytes data     = 2;
diff --git a/test/e2e/native_histograms_test.go b/test/e2e/native_histograms_test.go
index dc8b4a0c7a2..7dae51d42de 100644
--- a/test/e2e/native_histograms_test.go
+++ b/test/e2e/native_histograms_test.go
@@ -19,6 +19,7 @@ import (
 	"github.com/prometheus/prometheus/prompb"
 	"github.com/prometheus/prometheus/storage/remote"
 	"github.com/prometheus/prometheus/tsdb/tsdbutil"
+
 	"github.com/thanos-io/thanos/pkg/promclient"
 	"github.com/thanos-io/thanos/pkg/queryfrontend"
 	"github.com/thanos-io/thanos/pkg/receive"
@@ -50,19 +51,19 @@ func TestQueryNativeHistograms(t *testing.T) {
 	histograms := tsdbutil.GenerateTestHistograms(4)
 	now := time.Now()
 
-	_, err = writeHistograms(ctx, now, histograms, rawRemoteWriteURL1)
+	_, err = writeHistograms(ctx, now, testHistogramMetricName, histograms, nil, rawRemoteWriteURL1)
 	testutil.Ok(t, err)
-	_, err = writeHistograms(ctx, now, histograms, rawRemoteWriteURL2)
+	_, err = writeHistograms(ctx, now, testHistogramMetricName, histograms, nil, rawRemoteWriteURL2)
 	testutil.Ok(t, err)
 
 	ts := func() time.Time { return now }
 
 	// Make sure we can query histogram from both Prometheus instances.
-	queryAndAssert(t, ctx, prom1.Endpoint("http"), func() string { return testHistogramMetricName }, ts, promclient.QueryOptions{}, expectedHistogramModelVector(histograms[len(histograms)-1], nil))
-	queryAndAssert(t, ctx, prom2.Endpoint("http"), func() string { return testHistogramMetricName }, ts, promclient.QueryOptions{}, expectedHistogramModelVector(histograms[len(histograms)-1], nil))
+	queryAndAssert(t, ctx, prom1.Endpoint("http"), func() string { return testHistogramMetricName }, ts, promclient.QueryOptions{}, expectedHistogramModelVector(testHistogramMetricName, histograms[len(histograms)-1], nil, nil))
+	queryAndAssert(t, ctx, prom2.Endpoint("http"), func() string { return testHistogramMetricName }, ts, promclient.QueryOptions{}, expectedHistogramModelVector(testHistogramMetricName, histograms[len(histograms)-1], nil, nil))
 
 	t.Run("query deduplicated histogram", func(t *testing.T) {
-		queryAndAssert(t, ctx, querier.Endpoint("http"), func() string { return testHistogramMetricName }, ts, promclient.QueryOptions{Deduplicate: true}, expectedHistogramModelVector(histograms[len(histograms)-1], map[string]string{
+		queryAndAssert(t, ctx, querier.Endpoint("http"), func() string { return testHistogramMetricName }, ts, promclient.QueryOptions{Deduplicate: true}, expectedHistogramModelVector(testHistogramMetricName, histograms[len(histograms)-1], nil, map[string]string{
 			"prometheus": "prom-ha",
 		}))
 	})
@@ -123,14 +124,22 @@ func TestWriteNativeHistograms(t *testing.T) {
 	ctx, cancel := context.WithTimeout(context.Background(), 1*time.Minute)
 	t.Cleanup(cancel)
 
+	timeNow := time.Now()
+
 	histograms := tsdbutil.GenerateTestHistograms(1)
-	now := time.Now()
-	_, err = writeHistograms(ctx, now, histograms, rawRemoteWriteURL)
+	_, err = writeHistograms(ctx, timeNow, testHistogramMetricName, histograms, nil, rawRemoteWriteURL)
 	testutil.Ok(t, err)
 
-	ts := func() time.Time { return now }
+	testFloatHistogramMetricName := testHistogramMetricName + "_float"
+	floatHistograms := tsdbutil.GenerateTestFloatHistograms(1)
+	_, err = writeHistograms(ctx, timeNow, testFloatHistogramMetricName, nil, floatHistograms, rawRemoteWriteURL)
+	testutil.Ok(t, err)
+
+	queryAndAssert(t, ctx, querier.Endpoint("http"), func() string { return testHistogramMetricName }, time.Now, promclient.QueryOptions{Deduplicate: true}, expectedHistogramModelVector(testHistogramMetricName, histograms[0], nil, map[string]string{
+		"tenant_id": "default-tenant",
+	}))
 
-	queryAndAssert(t, ctx, querier.Endpoint("http"), func() string { return testHistogramMetricName }, ts, promclient.QueryOptions{Deduplicate: true}, expectedHistogramModelVector(histograms[0], map[string]string{
+	queryAndAssert(t, ctx, querier.Endpoint("http"), func() string { return testFloatHistogramMetricName }, time.Now, promclient.QueryOptions{Deduplicate: true}, expectedHistogramModelVector(testFloatHistogramMetricName, nil, floatHistograms[0], map[string]string{
 		"tenant_id": "default-tenant",
 	}))
 }
@@ -166,9 +175,9 @@ func TestQueryFrontendNativeHistograms(t *testing.T) {
 
 	histograms := tsdbutil.GenerateTestHistograms(4)
 	now := time.Now()
-	_, err = writeHistograms(ctx, now, histograms, rawRemoteWriteURL1)
+	_, err = writeHistograms(ctx, now, testHistogramMetricName, histograms, nil, rawRemoteWriteURL1)
 	testutil.Ok(t, err)
-	startTime, err := writeHistograms(ctx, now, histograms, rawRemoteWriteURL2)
+	startTime, err := writeHistograms(ctx, now, testHistogramMetricName, histograms, nil, rawRemoteWriteURL2)
 	testutil.Ok(t, err)
 
 	// Ensure we can get the result from Querier first so that it
@@ -181,10 +190,8 @@ func TestQueryFrontendNativeHistograms(t *testing.T) {
 		},
 	})
 
-	vals, err := querier.SumMetrics(
-		[]string{"http_requests_total"},
-		e2emon.WithLabelMatchers(matchers.MustNewMatcher(matchers.MatchEqual, "handler", "query")),
-	)
+	vals, err := querier.SumMetrics([]string{"http_requests_total"})
+	e2emon.WithLabelMatchers(matchers.MustNewMatcher(matchers.MatchEqual, "handler", "query"))
 
 	testutil.Ok(t, err)
 	testutil.Equals(t, 1, len(vals))
@@ -193,7 +200,7 @@ func TestQueryFrontendNativeHistograms(t *testing.T) {
 	ts := func() time.Time { return now }
 
 	t.Run("query frontend works for instant query", func(t *testing.T) {
-		queryAndAssert(t, ctx, queryFrontend.Endpoint("http"), func() string { return testHistogramMetricName }, ts, promclient.QueryOptions{Deduplicate: true}, expectedHistogramModelVector(histograms[len(histograms)-1], map[string]string{
+		queryAndAssert(t, ctx, queryFrontend.Endpoint("http"), func() string { return testHistogramMetricName }, ts, promclient.QueryOptions{Deduplicate: true}, expectedHistogramModelVector(testHistogramMetricName, histograms[len(histograms)-1], nil, map[string]string{
 			"prometheus": "prom-ha",
 		}))
 
@@ -211,7 +218,7 @@ func TestQueryFrontendNativeHistograms(t *testing.T) {
 	})
 
 	t.Run("query range query, all but last histogram", func(t *testing.T) {
-		expectedRes := expectedHistogramModelMatrix(histograms[:len(histograms)-1], startTime, map[string]string{
+		expectedRes := expectedHistogramModelMatrix(testHistogramMetricName, histograms[:len(histograms)-1], nil, startTime, map[string]string{
 			"prometheus": "prom-ha",
 		})
 
@@ -247,7 +254,7 @@ func TestQueryFrontendNativeHistograms(t *testing.T) {
 	})
 
 	t.Run("query range, all histograms", func(t *testing.T) {
-		expectedRes := expectedHistogramModelMatrix(histograms, startTime, map[string]string{
+		expectedRes := expectedHistogramModelMatrix(testHistogramMetricName, histograms, nil, startTime, map[string]string{
 			"prometheus": "prom-ha",
 		})
 
@@ -280,7 +287,7 @@ func TestQueryFrontendNativeHistograms(t *testing.T) {
 	})
 
 	t.Run("query range, all histograms again", func(t *testing.T) {
-		expectedRes := expectedHistogramModelMatrix(histograms, startTime, map[string]string{
+		expectedRes := expectedHistogramModelMatrix(testHistogramMetricName, histograms, nil, startTime, map[string]string{
 			"prometheus": "prom-ha",
 		})
 
@@ -314,18 +321,25 @@ func TestQueryFrontendNativeHistograms(t *testing.T) {
 	})
 }
 
-func writeHistograms(ctx context.Context, now time.Time, histograms []*histogram.Histogram, rawRemoteWriteURL string) (time.Time, error) {
+func writeHistograms(ctx context.Context, now time.Time, name string, histograms []*histogram.Histogram, floatHistograms []*histogram.FloatHistogram, rawRemoteWriteURL string) (time.Time, error) {
 	startTime := now.Add(time.Duration(len(histograms)-1) * -30 * time.Second).Truncate(30 * time.Second)
 	prompbHistograms := make([]prompb.Histogram, 0, len(histograms))
 
-	for i, h := range histograms {
-		ts := startTime.Add(time.Duration(i) * 30 * time.Second).UnixMilli()
-		prompbHistograms = append(prompbHistograms, remote.HistogramToHistogramProto(ts, h))
+	if len(floatHistograms) > 0 {
+		for i, fh := range floatHistograms {
+			ts := startTime.Add(time.Duration(i) * 30 * time.Second).UnixMilli()
+			prompbHistograms = append(prompbHistograms, remote.FloatHistogramToHistogramProto(ts, fh))
+		}
+	} else {
+		for i, h := range histograms {
+			ts := startTime.Add(time.Duration(i) * 30 * time.Second).UnixMilli()
+			prompbHistograms = append(prompbHistograms, remote.HistogramToHistogramProto(ts, h))
+		}
 	}
 
 	timeSeriespb := prompb.TimeSeries{
 		Labels: []prompb.Label{
-			{Name: "__name__", Value: testHistogramMetricName},
+			{Name: "__name__", Value: name},
 			{Name: "foo", Value: "bar"},
 		},
 		Histograms: prompbHistograms,
@@ -336,45 +350,60 @@ func writeHistograms(ctx context.Context, now time.Time, histograms []*histogram
 	})
 }
 
-func expectedHistogramModelVector(histogram *histogram.Histogram, externalLabels map[string]string) model.Vector {
+func expectedHistogramModelVector(name string, histogram *histogram.Histogram, floatHistogram *histogram.FloatHistogram, externalLabels map[string]string) model.Vector {
 	metrics := model.Metric{
-		"__name__": testHistogramMetricName,
+		"__name__": model.LabelValue(name),
 		"foo":      "bar",
 	}
 	for labelKey, labelValue := range externalLabels {
 		metrics[model.LabelName(labelKey)] = model.LabelValue(labelValue)
 	}
 
+	var sampleHistogram *model.SampleHistogram
+
+	if histogram != nil {
+		sampleHistogram = histogramToSampleHistogram(histogram)
+	} else {
+		sampleHistogram = floatHistogramToSampleHistogram(floatHistogram)
+	}
+
 	return model.Vector{
 		&model.Sample{
 			Metric:    metrics,
-			Histogram: histogramToSampleHistogram(histogram),
+			Histogram: sampleHistogram,
 		},
 	}
 }
 
-func expectedHistogramModelMatrix(histograms []*histogram.Histogram, startTime time.Time, externalLabels map[string]string) model.Matrix {
+func expectedHistogramModelMatrix(name string, histograms []*histogram.Histogram, floatHistograms []*histogram.FloatHistogram, startTime time.Time, externalLabels map[string]string) model.Matrix {
 	metrics := model.Metric{
-		"__name__": testHistogramMetricName,
+		"__name__": model.LabelValue(name),
 		"foo":      "bar",
 	}
 	for labelKey, labelValue := range externalLabels {
 		metrics[model.LabelName(labelKey)] = model.LabelValue(labelValue)
 	}
 
-	shp := make([]model.SampleHistogramPair, 0, len(histograms))
+	sampleHistogramPair := make([]model.SampleHistogramPair, 0, len(histograms))
 
 	for i, h := range histograms {
-		shp = append(shp, model.SampleHistogramPair{
+		sampleHistogramPair = append(sampleHistogramPair, model.SampleHistogramPair{
 			Timestamp: model.Time(startTime.Add(time.Duration(i) * 30 * time.Second).UnixMilli()),
 			Histogram: histogramToSampleHistogram(h),
 		})
 	}
 
+	for i, fh := range floatHistograms {
+		sampleHistogramPair = append(sampleHistogramPair, model.SampleHistogramPair{
+			Timestamp: model.Time(startTime.Add(time.Duration(i) * 30 * time.Second).UnixMilli()),
+			Histogram: floatHistogramToSampleHistogram(fh),
+		})
+	}
+
 	return model.Matrix{
 		&model.SampleStream{
 			Metric:     metrics,
-			Histograms: shp,
+			Histograms: sampleHistogramPair,
 		},
 	}
 }
@@ -401,7 +430,29 @@ func histogramToSampleHistogram(h *histogram.Histogram) *model.SampleHistogram {
 	}
 }
 
-func bucketToSampleHistogramBucket(bucket histogram.Bucket[uint64]) *model.HistogramBucket {
+func floatHistogramToSampleHistogram(fh *histogram.FloatHistogram) *model.SampleHistogram {
+	var buckets []*model.HistogramBucket
+
+	it := fh.NegativeBucketIterator()
+	for it.Next() {
+		buckets = append([]*model.HistogramBucket{bucketToSampleHistogramBucket(it.At())}, buckets...)
+	}
+
+	buckets = append(buckets, bucketToSampleHistogramBucket(fh.ZeroBucket()))
+
+	it = fh.PositiveBucketIterator()
+	for it.Next() {
+		buckets = append(buckets, bucketToSampleHistogramBucket(it.At()))
+	}
+
+	return &model.SampleHistogram{
+		Count:   model.FloatString(fh.Count),
+		Sum:     model.FloatString(fh.Sum),
+		Buckets: buckets,
+	}
+}
+
+func bucketToSampleHistogramBucket[BC histogram.BucketCount](bucket histogram.Bucket[BC]) *model.HistogramBucket {
 	return &model.HistogramBucket{
 		Lower:      model.FloatString(bucket.Lower),
 		Upper:      model.FloatString(bucket.Upper),
@@ -410,7 +461,7 @@ func bucketToSampleHistogramBucket(bucket histogram.Bucket[uint64]) *model.Histo
 	}
 }
 
-func boundaries(bucket histogram.Bucket[uint64]) int32 {
+func boundaries[BC histogram.BucketCount](bucket histogram.Bucket[BC]) int32 {
 	switch {
 	case bucket.UpperInclusive && !bucket.LowerInclusive:
 		return 0