﻿---
title: Histogram field type
description: A field to store pre-aggregated numerical data representing a histogram. This data is defined using two paired arrays: A values array of double numbers,...
url: https://www.elastic.co/elastic/docs-builder/docs/3016/reference/elasticsearch/mapping-reference/histogram
products:
  - Elasticsearch
applies_to:
  - Elastic Cloud Serverless: Generally available
  - Elastic Stack: Generally available
---

# Histogram field type
A field to store pre-aggregated numerical data representing a histogram. This data is defined using two paired arrays:
- A `values` array of [`double`](https://www.elastic.co/elastic/docs-builder/docs/3016/reference/elasticsearch/mapping-reference/number) numbers, representing the buckets for the histogram. These values must be provided in ascending order.
- A corresponding `counts` array of [`long`](https://www.elastic.co/elastic/docs-builder/docs/3016/reference/elasticsearch/mapping-reference/number) numbers, representing how many values fall into each bucket. These numbers must be positive or zero.

Because the elements in the `values` array correspond to the elements in the same position of the `count` array, these two arrays must have the same length.
<important>
  - A `histogram` field can only store a single pair of `values` and `count` arrays per document. Nested arrays are not supported.
  - `histogram` fields do not support sorting.
</important>


## Uses

`histogram` fields are primarily intended for use with aggregations. To make it more readily accessible for aggregations, `histogram` field data is stored as a binary [doc values](https://www.elastic.co/elastic/docs-builder/docs/3016/reference/elasticsearch/mapping-reference/doc-values) and not indexed. Its size in bytes is at most `13 * numValues`, where `numValues` is the length of the provided arrays.
Because the data is not indexed, you only can use `histogram` fields for the following aggregations and queries:
- [min](/elastic/docs-builder/docs/3016/reference/aggregations/search-aggregations-metrics-min-aggregation#search-aggregations-metrics-min-aggregation-histogram-fields) aggregation
- [max](/elastic/docs-builder/docs/3016/reference/aggregations/search-aggregations-metrics-max-aggregation#search-aggregations-metrics-max-aggregation-histogram-fields) aggregation
- [sum](/elastic/docs-builder/docs/3016/reference/aggregations/search-aggregations-metrics-sum-aggregation#search-aggregations-metrics-sum-aggregation-histogram-fields) aggregation
- [value_count](/elastic/docs-builder/docs/3016/reference/aggregations/search-aggregations-metrics-valuecount-aggregation#search-aggregations-metrics-valuecount-aggregation-histogram-fields) aggregation
- [avg](/elastic/docs-builder/docs/3016/reference/aggregations/search-aggregations-metrics-avg-aggregation#search-aggregations-metrics-avg-aggregation-histogram-fields) aggregation
- [percentiles](https://www.elastic.co/elastic/docs-builder/docs/3016/reference/aggregations/search-aggregations-metrics-percentile-aggregation) aggregation
- [percentile ranks](https://www.elastic.co/elastic/docs-builder/docs/3016/reference/aggregations/search-aggregations-metrics-percentile-rank-aggregation) aggregation
- [boxplot](https://www.elastic.co/elastic/docs-builder/docs/3016/reference/aggregations/search-aggregations-metrics-boxplot-aggregation) aggregation
- [histogram](/elastic/docs-builder/docs/3016/reference/aggregations/search-aggregations-bucket-histogram-aggregation#search-aggregations-bucket-histogram-aggregation-histogram-fields) aggregation
- [range](/elastic/docs-builder/docs/3016/reference/aggregations/search-aggregations-bucket-range-aggregation#search-aggregations-bucket-range-aggregation-histogram-fields) aggregation
- [exists](https://www.elastic.co/elastic/docs-builder/docs/3016/reference/query-languages/query-dsl/query-dsl-exists-query) query


## Building a histogram

When using a histogram as part of an aggregation, the accuracy of the results will depend on how the histogram was constructed. It is important to consider the percentiles aggregation mode that will be used to build it. Some possibilities include:
- For the [T-Digest](https://www.elastic.co/elastic/docs-builder/docs/3016/reference/aggregations/search-aggregations-metrics-percentile-aggregation) mode, the `values` array represents the mean centroid positions and the `counts` array represents the number of values that are attributed to each centroid. If the algorithm has already started to approximate the percentiles, this inaccuracy is carried over in the histogram.
- For the [High Dynamic Range (HDR)](/elastic/docs-builder/docs/3016/reference/aggregations/search-aggregations-metrics-percentile-rank-aggregation#_hdr_histogram) histogram mode, the `values` array represents fixed upper limits of each bucket interval, and the `counts` array represents the number of values that are attributed to each interval. This implementation maintains a fixed worse-case percentage error (specified as a number of significant digits), therefore the value used when generating the histogram would be the maximum accuracy you can achieve at aggregation time.

The histogram field is "algorithm agnostic" and does not store data specific to either T-Digest or HDRHistogram. While this means the field can technically be aggregated with either algorithm, in practice the user should chose one algorithm and index data in that manner (e.g. centroids for T-Digest or intervals for HDRHistogram) to ensure best accuracy.

## Synthetic `_source`

`histogram` fields support [synthetic `_source`](/elastic/docs-builder/docs/3016/reference/elasticsearch/mapping-reference/mapping-source-field#synthetic-source) in their default configuration.
<note>
  To save space, zero-count buckets are not stored in the histogram doc values. As a result, when indexing a histogram field in an index with synthetic source enabled, indexing a histogram including zero-count buckets will result in missing buckets when fetching back the histogram.
</note>


## Examples

The following [create index](https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-indices-create) API request creates a new index with two field mappings:
- `my_histogram`, a `histogram` field used to store percentile data
- `my_text`, a `keyword` field used to store a title for the histogram

```json

{
  "mappings" : {
    "properties" : {
      "my_histogram" : {
        "type" : "histogram"
      },
      "my_text" : {
        "type" : "keyword"
      }
    }
  }
}
```

The following [index](https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-create) API requests store pre-aggregated for two histograms: `histogram_1` and `histogram_2`.
```json

{
  "my_text" : "histogram_1",
  "my_histogram" : {
      "values" : [0.1, 0.2, 0.3, 0.4, 0.5], <1>
      "counts" : [3, 7, 23, 12, 6] <2>
   }
}


{
  "my_text" : "histogram_2",
  "my_histogram" : {
      "values" : [0.1, 0.25, 0.35, 0.4, 0.45, 0.5], <1>
      "counts" : [8, 17, 8, 7, 6, 2] <2>
   }
}
```


## Coercion from exponential histogram

<applies-to>
  - Elastic Stack: Preview in 9.3
</applies-to>

To facilitate transitions and mixed inputs, `histogram` fields support coercion from the `exponential_histogram` field structure. When `coerce` is enabled (default), you can provide an exponential histogram payload and Elasticsearch will convert it to the `histogram` field's internal T-Digest representation during indexing.
```json

{
  "mappings" : {
    "properties" : {
      "my_histogram" : {
        "type" : "histogram"
      }
    }
  }
}


{
  "my_histogram" : {
    "scale": 12,
    "sum": 1234.0,
    "min": -123.456,
    "max": 456.456,
    "zero": { "threshold": 0.001, "count": 42 },
    "positive": { "indices": [-10, 25, 26], "counts": [2, 3, 4] },
    "negative": { "indices": [-5, 0], "counts": [10, 7] }
  }
}
```

To reject exponential histogram input, disable coercion on the field mapping or at the index level. See [coerce](https://www.elastic.co/elastic/docs-builder/docs/3016/reference/elasticsearch/mapping-reference/coerce).