﻿---
title: ES|QL TBUCKET function
description: 
url: https://www.elastic.co/elastic/docs-builder/docs/3028/reference/query-languages/esql/functions-operators/grouping-functions/tbucket
products:
  - Elasticsearch
---

# ES|QL TBUCKET function
<applies-to>
  - Elastic Stack: Generally available since 9.2
</applies-to>


## Syntax

![Embedded](https://www.elastic.co/elastic/docs-builder/docs/3028/reference/query-languages/esql/images/functions/tbucket.svg)


## Parameters

<definitions>
  <definition term="buckets">
    Target number of buckets, or desired bucket size. When a number is provided, the actual bucket size is derived from `from`/`to` or the `@timestamp` range in the query filter <applies-to>Elastic Stack: Planned</applies-to>. When a duration or period is provided, it is used as the explicit bucket size.
  </definition>
  <definition term="from">
    Start of the range. Required with a numeric `buckets` when no `@timestamp` range is in the query filter <applies-to>Elastic Stack: Planned</applies-to>.
  </definition>
  <definition term="to">
    End of the range. Required with a numeric `buckets` when no `@timestamp` range is in the query filter <applies-to>Elastic Stack: Planned</applies-to>.
  </definition>
</definitions>


## Description

Creates groups of values - buckets - out of a `@timestamp` attribute. The size of the buckets can be provided directly as a duration or period. Alternatively, the bucket size can be chosen based on a recommended count and a range <applies-to>Elastic Stack: Planned</applies-to>.  When using ES|QL in Kibana, the range can be derived automatically from the [`@timestamp` filter](https://docs-v3-preview.elastic.dev/elastic/docs-builder/docs/3028/explore-analyze/query-filter/languages/esql-kibana#_standard_time_filter) that Kibana adds to the query.

## Supported types


| buckets       | from    | to      | result     |
|---------------|---------|---------|------------|
| date_period   |         |         | date       |
| date_period   |         |         | date_nanos |
| integer       | date    | date    | date       |
| integer       | date    | date    | date_nanos |
| integer       | date    | keyword | date       |
| integer       | date    | keyword | date_nanos |
| integer       | date    | text    | date       |
| integer       | date    | text    | date_nanos |
| integer       | keyword | date    | date       |
| integer       | keyword | date    | date_nanos |
| integer       | keyword | keyword | date       |
| integer       | keyword | keyword | date_nanos |
| integer       | keyword | text    | date       |
| integer       | keyword | text    | date_nanos |
| integer       | text    | date    | date       |
| integer       | text    | date    | date_nanos |
| integer       | text    | keyword | date       |
| integer       | text    | keyword | date_nanos |
| integer       | text    | text    | date       |
| integer       | text    | text    | date_nanos |
| time_duration |         |         | date       |
| time_duration |         |         | date_nanos |


## Examples

`TBUCKET` can work in two modes: one in which the size of the bucket is computed
based on a buckets count recommendation and a range, and
another in which the bucket size is provided directly as a duration or period.
Using a target number of buckets, a start of a range, and an end of a range,
`TBUCKET` picks an appropriate bucket size to generate the target number of buckets or fewer.
For example, asking for at most 3 buckets over a 2 hour range results in hourly buckets
<applies-to>Elastic Stack: Planned</applies-to>:
```esql
FROM sample_data
| STATS count = COUNT(*) BY bucket = TBUCKET(3, "2023-10-23T12:00:00Z", "2023-10-23T14:00:00Z")
| SORT bucket
```


| count:long | bucket:datetime          |
|------------|--------------------------|
| 2          | 2023-10-23T12:00:00.000Z |
| 5          | 2023-10-23T13:00:00.000Z |

The goal isn't to provide **exactly** the target number of buckets,
it's to pick a range that people are comfortable with that provides at most the target number of buckets.
Asking for more buckets can result in a finer granularity.
For example, asking for at most 20 buckets in the same range results in 10-minute buckets
<applies-to>Elastic Stack: Planned</applies-to>:
```esql
FROM sample_data
| STATS count = COUNT(*) BY bucket = TBUCKET(20, "2023-10-23T12:00:00Z", "2023-10-23T14:00:00Z")
| SORT bucket
```


| count:long | bucket:datetime          |
|------------|--------------------------|
| 1          | 2023-10-23T12:10:00.000Z |
| 1          | 2023-10-23T12:20:00.000Z |
| 1          | 2023-10-23T13:30:00.000Z |
| 4          | 2023-10-23T13:50:00.000Z |

<note>
  `TBUCKET` does not filter any rows. It only uses the provided range to pick a good bucket size.
  For rows with a value outside of the range, it returns a bucket value that corresponds to a bucket
  outside the range. Combine `TBUCKET` with [`WHERE`](https://www.elastic.co/elastic/docs-builder/docs/3028/reference/query-languages/esql/commands/where)
  to filter rows.
</note>

If the desired bucket size is known in advance, simply provide it as the first argument,
leaving the range out:
```esql
FROM sample_data
| STATS min = MIN(@timestamp), max = MAX(@timestamp) BY bucket = TBUCKET(1 hour)
| SORT min
```


| min:datetime             | max:datetime             | bucket:datetime          |
|--------------------------|--------------------------|--------------------------|
| 2023-10-23T12:15:03.360Z | 2023-10-23T12:27:28.948Z | 2023-10-23T12:00:00.000Z |
| 2023-10-23T13:33:34.937Z | 2023-10-23T13:55:01.543Z | 2023-10-23T13:00:00.000Z |

<note>
  When providing the bucket size, it must be a time duration or date period.
  Also the reference is epoch, which starts at `0001-01-01T00:00:00Z`.
</note>

The bucket size can also be provided as a string:
```esql
FROM sample_data
| STATS min = MIN(@timestamp), max = MAX(@timestamp) BY bucket = TBUCKET("1 hour")
| SORT min
```


| min:datetime             | max:datetime             | bucket:datetime          |
|--------------------------|--------------------------|--------------------------|
| 2023-10-23T12:15:03.360Z | 2023-10-23T12:27:28.948Z | 2023-10-23T12:00:00.000Z |
| 2023-10-23T13:33:34.937Z | 2023-10-23T13:55:01.543Z | 2023-10-23T13:00:00.000Z |