The Elasticsearch auto_date_histogram aggregation is a multi-bucket aggregation that groups documents into time intervals based on a target bucket count rather than a fixed interval. Elasticsearch picks an interval that yields approximately the requested number of buckets given the actual data range, then rounds bucket boundaries to a calendar unit (minute, hour, day, week, month, year). Use it for charts where you want roughly N points regardless of how much data the user filtered to.
Syntax
GET /metrics/_search
{
"size": 0,
"aggs": {
"messages_over_time": {
"auto_date_histogram": {
"field": "@timestamp",
"buckets": 20,
"minimum_interval": "minute",
"format": "yyyy-MM-dd HH:mm",
"time_zone": "UTC"
}
}
}
}
The chosen interval is reported in the response as interval. The actual bucket count can differ slightly from buckets because intervals are snapped to round calendar units.
Parameters
| Parameter | Default | Description |
|---|---|---|
field |
required | date or date_nanos field. |
buckets |
10 | Target number of buckets. Hard limit 10000. |
minimum_interval |
second |
Coarsest unit allowed: second, minute, hour, day, month, year. |
time_zone |
UTC | Time zone applied to bucket boundaries. |
format |
- | Java date format for bucket key strings. |
missing |
- | Substitute timestamp for documents missing the field. |
The aggregation picks one of the following intervals: 1s, 5s, 10s, 30s, 1m, 5m, 10m, 30m, 1h, 3h, 12h, 1d, 7d, 1M, 3M, 1y, 5y, 10y, 20y, 50y, 100y. It starts at the finest interval that yields no more than buckets and rounds up if needed.
Examples
Time chart with about 50 points across whatever range the user picked:
GET /logs/_search
{
"size": 0,
"query": { "range": { "@timestamp": { "gte": "now-7d" } } },
"aggs": {
"by_time": {
"auto_date_histogram": { "field": "@timestamp", "buckets": 50 }
}
}
}
Floor the resolution at one hour (no second/minute buckets even if buckets would justify them):
"auto_date_histogram": {
"field": "@timestamp",
"buckets": 100,
"minimum_interval": "hour"
}
Pair with a sum sub-aggregation for total bytes per auto-sized bucket:
"aggs": {
"traffic": {
"auto_date_histogram": { "field": "@timestamp", "buckets": 30 },
"aggs": {
"bytes": { "sum": { "field": "response.bytes" } }
}
}
}
Behavior and Performance Notes
auto_date_histogram chooses the smallest interval from its fixed candidate list that produces at most the target bucket count, then merges adjacent buckets if memory pressure during execution suggests the chosen interval was too fine. This means the response can include fewer buckets than requested but rarely more. The final interval used is exposed via the response field interval.
Because the candidate intervals jump from 30m to 1h to 3h to 12h to 1d, the actual bucket count can be substantially below the target when the data range straddles those jumps - asking for 24 buckets across a 30-hour range may yield 10 (1h interval) or 30 (could not happen, since 30m would yield 60 buckets). Plan dashboards around the discrete interval set.
auto_date_histogram is the right default for user-controlled time ranges: a fixed date_histogram with fixed_interval: 1m over a year of data produces over 500,000 buckets and hits search.max_buckets. Pulse monitors Elasticsearch query patterns and surfaces dashboards whose time aggregations are pushing clusters toward bucket limits.
Common Mistakes
- Expecting exactly
bucketsbuckets. The aggregation hits the discrete interval list, so the actual count varies. - Forgetting
minimum_intervaland ending up with second-resolution buckets on tiny time ranges - meaningless for most dashboards. - Using auto_date_histogram inside a composite aggregation. Composite source must be
date_histogram, notauto_date_histogram. - Not surfacing the chosen
intervalin the UI - users get confused when the same chart shows different granularities. - Mixing time zones between query filters and the aggregation, producing off-by-one buckets at midnight.
Frequently Asked Questions
Q: How does auto_date_histogram differ from date_histogram?
A: The date_histogram aggregation takes a fixed interval (fixed_interval or calendar_interval). The auto_date_histogram aggregation takes a target bucket count and lets Elasticsearch pick the interval. Use auto_date_histogram when the time range is variable and you want stable chart point counts.
Q: How precise is the bucket count?
A: Approximate. Elasticsearch picks from a fixed list of candidate intervals and may merge buckets under memory pressure. Treat buckets as "up to this many", not "exactly this many".
Q: What is the maximum value for buckets?
A: 10000, subject also to search.max_buckets (default 65,536). Setting buckets very high largely defeats the purpose of automatic interval selection.
Q: How is minimum_interval enforced?
A: Elasticsearch never selects an interval finer than minimum_interval. This is the safety knob for dashboards that should never resolve sub-hour, for example.
Q: Does auto_date_histogram support date_nanos?
A: Yes, with the same candidate interval list. Nanosecond resolution requires minimum_interval: second or finer, which is only available against date_nanos fields.
Q: Can I use auto_date_histogram inside a composite aggregation?
A: No. The composite aggregation accepts date_histogram as a source type, not auto_date_histogram. Pre-compute the interval and use a regular date_histogram if you need pagination.
Related Reading
- Date Histogram Aggregation: fixed-interval counterpart.
- Date Range Aggregation: explicit, named date ranges.
- Composite Aggregation: paginated enumeration over time buckets.
- Sum Aggregation: typical metric inside an auto histogram.
- Elasticsearch Query Language: the DSL auto_date_histogram runs inside.