From 165e9a2303ca69492603138dba34b786b7c4819d Mon Sep 17 00:00:00 2001 From: Florent LB Date: Fri, 31 Jul 2026 11:20:48 +0200 Subject: [PATCH 1/8] docs: Vega ES|QL data sources respect the dashboard time range (#7620) Co-Authored-By: Claude Opus 4.8 --- .../visualize/custom-visualizations-with-vega.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/explore-analyze/visualize/custom-visualizations-with-vega.md b/explore-analyze/visualize/custom-visualizations-with-vega.md index 1739bbc823..961b8c668e 100644 --- a/explore-analyze/visualize/custom-visualizations-with-vega.md +++ b/explore-analyze/visualize/custom-visualizations-with-vega.md @@ -1426,13 +1426,15 @@ The `url` object supports the following parameters: | `"%type%"` | Set to `"esql"` to use the {{esql}} parser. | | `"query"` | The {{esql}} query to run. Required. | | `"%context%"` | When set to `true`, applies the dashboard filters to the query. | -| `"%timefield%"` | When set, enables the `?_tstart` and `?_tend` named parameters in the query. These parameters are replaced with the start and end of the dashboard time range. | +| `"%timefield%"` | {applies_to}`stack: ga 9.4` Enables the `?_tstart` and `?_tend` named parameters in the query, which are replaced with the start and end of the dashboard time range. {applies_to}`stack: ga 9.5` {applies_to}`serverless: ga` Sets the field that {{kib}} uses to apply the dashboard time range to the query. | | `"dropNullColumns"` | Defaults to `true`. When `true`, columns that contain only `null` values are excluded from the response. | | `"params"` | An array of named parameter objects to substitute into the query. | +{applies_to}`stack: ga 9.5` {applies_to}`serverless: ga` The dashboard time range applies to {{esql}} data sources automatically, the same way it does in Lens and Discover. {{kib}} adds a range filter on the resolved time field, and it also binds the `?_tstart` and `?_tend` parameters whenever they appear in the query. The time field resolves in this order: the explicit `"%timefield%"` value, then the query's default time field, then no time filtering if neither is available. Time filtering works independently of `"%context%"` and of whether the query uses `?_tstart` and `?_tend`. + The response is converted from the {{esql}} columnar format into the row-based format that **Vega** expects, with one object per row keyed by column name. -The following example creates a metric that counts documents over time, using the dashboard filters and time range through `"%context%"`, `"%timefield%"`, and the `?_tstart` and `?_tend` parameters. To try it, [install the sample web logs data set](/manage-data/ingest/sample-data.md), open a new custom visualization on a dashboard, and paste the spec: +The following example creates a line chart that counts documents over time. It uses `"%context%"` to apply the dashboard filters, `"%timefield%"` to integrate with the dashboard time range, and the `?_tstart` and `?_tend` parameters to bound the histogram buckets to that range. To try it, [install the sample web logs data set](/manage-data/ingest/sample-data.md), open a new custom visualization on a dashboard, and paste the spec: ```json { From 81f92d13a89223b048477088e3278bff677d15cd Mon Sep 17 00:00:00 2001 From: Florent LB Date: Fri, 31 Jul 2026 16:16:10 +0200 Subject: [PATCH 2/8] Correct time-field resolution: %timefield% -> ?_tstart/?_tend field -> @timestamp Co-Authored-By: Claude Opus 4.8 --- explore-analyze/visualize/custom-visualizations-with-vega.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/explore-analyze/visualize/custom-visualizations-with-vega.md b/explore-analyze/visualize/custom-visualizations-with-vega.md index 961b8c668e..1a9342a7a6 100644 --- a/explore-analyze/visualize/custom-visualizations-with-vega.md +++ b/explore-analyze/visualize/custom-visualizations-with-vega.md @@ -1430,7 +1430,7 @@ The `url` object supports the following parameters: | `"dropNullColumns"` | Defaults to `true`. When `true`, columns that contain only `null` values are excluded from the response. | | `"params"` | An array of named parameter objects to substitute into the query. | -{applies_to}`stack: ga 9.5` {applies_to}`serverless: ga` The dashboard time range applies to {{esql}} data sources automatically, the same way it does in Lens and Discover. {{kib}} adds a range filter on the resolved time field, and it also binds the `?_tstart` and `?_tend` parameters whenever they appear in the query. The time field resolves in this order: the explicit `"%timefield%"` value, then the query's default time field, then no time filtering if neither is available. Time filtering works independently of `"%context%"` and of whether the query uses `?_tstart` and `?_tend`. +{applies_to}`stack: ga 9.5` {applies_to}`serverless: ga` The dashboard time range applies to {{esql}} data sources automatically, the same way it does in Lens and Discover. {{kib}} adds a range filter for the resolved time field, and it still binds the `?_tstart` and `?_tend` parameters when they appear in the query. The time field resolves in this order: the explicit `"%timefield%"` value, then the field the query compares against `?_tstart` and `?_tend`, then a field named `@timestamp` on the queried index. If none of these apply, the query isn't filtered by time, so set `"%timefield%"` when your data's time field isn't named `@timestamp`. Time filtering applies whether or not `"%context%"` is set. The response is converted from the {{esql}} columnar format into the row-based format that **Vega** expects, with one object per row keyed by column name. From 989a07b73ab3886e9d270e4a6e7f45865e91376d Mon Sep 17 00:00:00 2001 From: Florent LB Date: Fri, 31 Jul 2026 16:49:17 +0200 Subject: [PATCH 3/8] Reword %timefield% cell in plainer language --- explore-analyze/visualize/custom-visualizations-with-vega.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/explore-analyze/visualize/custom-visualizations-with-vega.md b/explore-analyze/visualize/custom-visualizations-with-vega.md index 1a9342a7a6..79c293c39d 100644 --- a/explore-analyze/visualize/custom-visualizations-with-vega.md +++ b/explore-analyze/visualize/custom-visualizations-with-vega.md @@ -1426,7 +1426,7 @@ The `url` object supports the following parameters: | `"%type%"` | Set to `"esql"` to use the {{esql}} parser. | | `"query"` | The {{esql}} query to run. Required. | | `"%context%"` | When set to `true`, applies the dashboard filters to the query. | -| `"%timefield%"` | {applies_to}`stack: ga 9.4` Enables the `?_tstart` and `?_tend` named parameters in the query, which are replaced with the start and end of the dashboard time range. {applies_to}`stack: ga 9.5` {applies_to}`serverless: ga` Sets the field that {{kib}} uses to apply the dashboard time range to the query. | +| `"%timefield%"` | {applies_to}`stack: ga 9.4` Lets your query use the `?_tstart` and `?_tend` parameters, which {{kib}} replaces with the start and end of the dashboard time range. {applies_to}`stack: ga 9.5` {applies_to}`serverless: ga` The date field that {{kib}} filters on to apply the dashboard time range to the query. | | `"dropNullColumns"` | Defaults to `true`. When `true`, columns that contain only `null` values are excluded from the response. | | `"params"` | An array of named parameter objects to substitute into the query. | From 818ea4ae6b8923ec55bbbe027fcac63b9bd0ac52 Mon Sep 17 00:00:00 2001 From: Florent LB Date: Fri, 31 Jul 2026 17:04:37 +0200 Subject: [PATCH 4/8] Simplify %timefield% cell; move version behavior to tagged bullets --- .../visualize/custom-visualizations-with-vega.md | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/explore-analyze/visualize/custom-visualizations-with-vega.md b/explore-analyze/visualize/custom-visualizations-with-vega.md index 79c293c39d..8883797e42 100644 --- a/explore-analyze/visualize/custom-visualizations-with-vega.md +++ b/explore-analyze/visualize/custom-visualizations-with-vega.md @@ -1426,11 +1426,16 @@ The `url` object supports the following parameters: | `"%type%"` | Set to `"esql"` to use the {{esql}} parser. | | `"query"` | The {{esql}} query to run. Required. | | `"%context%"` | When set to `true`, applies the dashboard filters to the query. | -| `"%timefield%"` | {applies_to}`stack: ga 9.4` Lets your query use the `?_tstart` and `?_tend` parameters, which {{kib}} replaces with the start and end of the dashboard time range. {applies_to}`stack: ga 9.5` {applies_to}`serverless: ga` The date field that {{kib}} filters on to apply the dashboard time range to the query. | +| `"%timefield%"` | The timestamp field to use for the dashboard time range. | | `"dropNullColumns"` | Defaults to `true`. When `true`, columns that contain only `null` values are excluded from the response. | | `"params"` | An array of named parameter objects to substitute into the query. | -{applies_to}`stack: ga 9.5` {applies_to}`serverless: ga` The dashboard time range applies to {{esql}} data sources automatically, the same way it does in Lens and Discover. {{kib}} adds a range filter for the resolved time field, and it still binds the `?_tstart` and `?_tend` parameters when they appear in the query. The time field resolves in this order: the explicit `"%timefield%"` value, then the field the query compares against `?_tstart` and `?_tend`, then a field named `@timestamp` on the queried index. If none of these apply, the query isn't filtered by time, so set `"%timefield%"` when your data's time field isn't named `@timestamp`. Time filtering applies whether or not `"%context%"` is set. +{{kib}} applies the dashboard time range to your {{esql}} query as follows: + +* {applies_to}`stack: ga 9.4` Reference the time field with the `?_tstart` and `?_tend` parameters in your query, for example in a `WHERE` clause, and set `"%timefield%"`. {{kib}} replaces the parameters with the start and end of the time range. Both are required for the time range to apply. +* {applies_to}`stack: ga 9.5` {applies_to}`serverless: ga` {{kib}} applies the time range automatically, the same way it does in Lens and Discover. It filters on the field set in `"%timefield%"`. If you don't set one, it uses the field your query references with `?_tstart` and `?_tend`, or a field named `@timestamp`. Set `"%timefield%"` when your time field has another name. + +Time filtering works independently of `"%context%"`. The response is converted from the {{esql}} columnar format into the row-based format that **Vega** expects, with one object per row keyed by column name. From 4288d8669deb6b87b7821f813a442007cb7069f2 Mon Sep 17 00:00:00 2001 From: Florent LB Date: Fri, 31 Jul 2026 18:31:09 +0200 Subject: [PATCH 5/8] Add 'Apply the dashboard time range' section with applies-switch and annotated samples --- .../custom-visualizations-with-vega.md | 72 ++++++++++++++++--- 1 file changed, 64 insertions(+), 8 deletions(-) diff --git a/explore-analyze/visualize/custom-visualizations-with-vega.md b/explore-analyze/visualize/custom-visualizations-with-vega.md index 8883797e42..781e551dfa 100644 --- a/explore-analyze/visualize/custom-visualizations-with-vega.md +++ b/explore-analyze/visualize/custom-visualizations-with-vega.md @@ -1426,18 +1426,76 @@ The `url` object supports the following parameters: | `"%type%"` | Set to `"esql"` to use the {{esql}} parser. | | `"query"` | The {{esql}} query to run. Required. | | `"%context%"` | When set to `true`, applies the dashboard filters to the query. | -| `"%timefield%"` | The timestamp field to use for the dashboard time range. | +| `"%timefield%"` | The timestamp field to use for the dashboard time range. See [Apply the dashboard time range](#vega-esql-time-range). | | `"dropNullColumns"` | Defaults to `true`. When `true`, columns that contain only `null` values are excluded from the response. | | `"params"` | An array of named parameter objects to substitute into the query. | -{{kib}} applies the dashboard time range to your {{esql}} query as follows: +The response is converted from the {{esql}} columnar format into the row-based format that **Vega** expects, with one object per row keyed by column name. -* {applies_to}`stack: ga 9.4` Reference the time field with the `?_tstart` and `?_tend` parameters in your query, for example in a `WHERE` clause, and set `"%timefield%"`. {{kib}} replaces the parameters with the start and end of the time range. Both are required for the time range to apply. -* {applies_to}`stack: ga 9.5` {applies_to}`serverless: ga` {{kib}} applies the time range automatically, the same way it does in Lens and Discover. It filters on the field set in `"%timefield%"`. If you don't set one, it uses the field your query references with `?_tstart` and `?_tend`, or a field named `@timestamp`. Set `"%timefield%"` when your time field has another name. +{applies_to}`stack: preview 9.5` {applies_to}`serverless: preview` **Vega** and **Vega-Lite** panels that use an {{esql}} data source are subject to the {icon}`bolt` [**Fast mode**](../query-filter/languages/esql-kibana.md#approximation-fast-mode) dashboard option. When this option is active on a dashboard, these panels return faster, estimated results for `STATS` aggregations. -Time filtering works independently of `"%context%"`. -The response is converted from the {{esql}} columnar format into the row-based format that **Vega** expects, with one object per row keyed by column name. +#### Apply the dashboard time range to {{esql}} data sources [vega-esql-time-range] +```{applies_to} +stack: ga 9.4 +serverless: ga +``` + +How the dashboard time range reaches an {{esql}} data source depends on your version. + +:::::{applies-switch} + +::::{applies-item} { stack: ga 9.5+, serverless: ga } +{{kib}} applies the dashboard time range automatically, the same way it does in Lens and Discover. It filters on the field set in `"%timefield%"`. If you don't set one, it uses the field the query references with `?_tstart` and `?_tend`, or a field named `@timestamp`. Set `"%timefield%"` when your time field has another name. + +The `?_tstart` and `?_tend` parameters remain available for queries that use them, such as a `BUCKET` on a time series. + +For example, this metric counts documents within the dashboard time range, with no time configuration in the spec: + +```json +{ + "$schema": "https://vega.github.io/schema/vega-lite/v6.json", + "data": { + "url": { + "%type%": "esql", + "query": "FROM kibana_sample_data_logs | STATS count = COUNT(*)" <1> + } + }, + "mark": { "type": "text", "fontSize": 48 }, + "encoding": { "text": { "field": "count", "type": "quantitative" } } +} +``` + +1. No `WHERE` clause, `?_tstart` or `?_tend` parameters, or `"%timefield%"` are needed. {{kib}} filters on `@timestamp` automatically. +:::: + +::::{applies-item} { stack: ga =9.4 } +{{kib}} applies the dashboard time range only through the `?_tstart` and `?_tend` parameters. Reference your time field with these parameters in the query, for example in a `WHERE` clause, and set `"%timefield%"` to turn them on. {{kib}} replaces the parameters with the start and end of the time range. Both the parameters and `"%timefield%"` are required. + +For example, this metric counts documents within the dashboard time range: + +```json +{ + "$schema": "https://vega.github.io/schema/vega-lite/v6.json", + "data": { + "url": { + "%type%": "esql", + "%timefield%": "@timestamp", <1> + "query": "FROM kibana_sample_data_logs | WHERE @timestamp >= ?_tstart AND @timestamp <= ?_tend | STATS count = COUNT(*)" <2> + } + }, + "mark": { "type": "text", "fontSize": 48 }, + "encoding": { "text": { "field": "count", "type": "quantitative" } } +} +``` + +1. Turns on the `?_tstart` and `?_tend` parameters. Set it to your time field so the spec keeps working in 9.5 and later. +2. Filters with the parameters. {{kib}} replaces `?_tstart` and `?_tend` with the start and end of the dashboard time range. +:::: + +::::: + +Time filtering works independently of `"%context%"`. The following example creates a line chart that counts documents over time. It uses `"%context%"` to apply the dashboard filters, `"%timefield%"` to integrate with the dashboard time range, and the `?_tstart` and `?_tend` parameters to bound the histogram buckets to that range. To try it, [install the sample web logs data set](/manage-data/ingest/sample-data.md), open a new custom visualization on a dashboard, and paste the spec: @@ -1469,8 +1527,6 @@ The following example creates a line chart that counts documents over time. It u } ``` -{applies_to}`stack: preview 9.5` {applies_to}`serverless: preview` **Vega** and **Vega-Lite** panels that use an {{esql}} data source are subject to the {icon}`bolt` [**Fast mode**](../query-filter/languages/esql-kibana.md#approximation-fast-mode) dashboard option. When this option is active on a dashboard, these panels return faster, estimated results for `STATS` aggregations. - #### Access Elastic Map Service files [vega-esmfiles] ```{applies_to} From 5186de2ce0c606385eb97856b0880070cc15fd51 Mon Sep 17 00:00:00 2001 From: Florent LB Date: Fri, 31 Jul 2026 18:54:38 +0200 Subject: [PATCH 6/8] Clarify 9.5+ time-field resolution as a numbered list; note date-field requirement --- .../visualize/custom-visualizations-with-vega.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/explore-analyze/visualize/custom-visualizations-with-vega.md b/explore-analyze/visualize/custom-visualizations-with-vega.md index 781e551dfa..391eedb70b 100644 --- a/explore-analyze/visualize/custom-visualizations-with-vega.md +++ b/explore-analyze/visualize/custom-visualizations-with-vega.md @@ -1446,9 +1446,13 @@ How the dashboard time range reaches an {{esql}} data source depends on your ver :::::{applies-switch} ::::{applies-item} { stack: ga 9.5+, serverless: ga } -{{kib}} applies the dashboard time range automatically, the same way it does in Lens and Discover. It filters on the field set in `"%timefield%"`. If you don't set one, it uses the field the query references with `?_tstart` and `?_tend`, or a field named `@timestamp`. Set `"%timefield%"` when your time field has another name. +{{kib}} applies the dashboard time range automatically, the same way it does in Lens and Discover. It filters on a date field, chosen in this order: -The `?_tstart` and `?_tend` parameters remain available for queries that use them, such as a `BUCKET` on a time series. +1. The field set in `"%timefield%"`. +2. The field the query compares against `?_tstart` and `?_tend`. +3. A field named `@timestamp`. + +If none of these apply, the query isn't filtered by time. When the query uses `?_tstart` and `?_tend`, {{kib}} also replaces them with the start and end of the time range. For example, this metric counts documents within the dashboard time range, with no time configuration in the spec: From fb3205e803fcc5ecb814d75bac3eaa6fdc1a34c2 Mon Sep 17 00:00:00 2001 From: Florent LB Date: Fri, 31 Jul 2026 19:22:53 +0200 Subject: [PATCH 7/8] Frame 9.5+ time-field resolution as an explicit fallback chain --- .../visualize/custom-visualizations-with-vega.md | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/explore-analyze/visualize/custom-visualizations-with-vega.md b/explore-analyze/visualize/custom-visualizations-with-vega.md index 391eedb70b..f78d532387 100644 --- a/explore-analyze/visualize/custom-visualizations-with-vega.md +++ b/explore-analyze/visualize/custom-visualizations-with-vega.md @@ -1446,13 +1446,15 @@ How the dashboard time range reaches an {{esql}} data source depends on your ver :::::{applies-switch} ::::{applies-item} { stack: ga 9.5+, serverless: ga } -{{kib}} applies the dashboard time range automatically, the same way it does in Lens and Discover. It filters on a date field, chosen in this order: +{{kib}} applies the dashboard time range automatically, the same way it does in Lens and Discover. It filters on a date field, which it determines in the following order: -1. The field set in `"%timefield%"`. -2. The field the query compares against `?_tstart` and `?_tend`. -3. A field named `@timestamp`. +1. The field set in `"%timefield%"`, if you set one. No `WHERE` clause is required. +2. Otherwise, the field your query compares against `?_tstart` and `?_tend`, for example in a `WHERE` clause. +3. Otherwise, a field named `@timestamp`, if one exists. -If none of these apply, the query isn't filtered by time. When the query uses `?_tstart` and `?_tend`, {{kib}} also replaces them with the start and end of the time range. +If none of these apply, the query isn't filtered by time. + +You can use the `?_tstart` and `?_tend` parameters whether or not you set `"%timefield%"`. {{kib}} replaces them with the start and end of the time range wherever they appear. For example, this metric counts documents within the dashboard time range, with no time configuration in the spec: From 5e6a52a20d9fe6fa56ddf660b28d493a5d5a398d Mon Sep 17 00:00:00 2001 From: Florent LB Date: Fri, 31 Jul 2026 19:29:46 +0200 Subject: [PATCH 8/8] Lead 9.5+ section with default @timestamp behavior; two override options --- .../visualize/custom-visualizations-with-vega.md | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/explore-analyze/visualize/custom-visualizations-with-vega.md b/explore-analyze/visualize/custom-visualizations-with-vega.md index f78d532387..483a32f780 100644 --- a/explore-analyze/visualize/custom-visualizations-with-vega.md +++ b/explore-analyze/visualize/custom-visualizations-with-vega.md @@ -1446,15 +1446,16 @@ How the dashboard time range reaches an {{esql}} data source depends on your ver :::::{applies-switch} ::::{applies-item} { stack: ga 9.5+, serverless: ga } -{{kib}} applies the dashboard time range automatically, the same way it does in Lens and Discover. It filters on a date field, which it determines in the following order: +{{kib}} applies the dashboard time range automatically, the same way it does in Lens and Discover. By default, it looks for a field named `@timestamp` in your data and filters on it, so no configuration is needed when your time field has that name. -1. The field set in `"%timefield%"`, if you set one. No `WHERE` clause is required. -2. Otherwise, the field your query compares against `?_tstart` and `?_tend`, for example in a `WHERE` clause. -3. Otherwise, a field named `@timestamp`, if one exists. +To filter on a different date field, specify it in one of the following ways: -If none of these apply, the query isn't filtered by time. +* Set `"%timefield%"` to the field. No `WHERE` clause is required in the query. +* Compare the field against `?_tstart` and `?_tend` in the query, for example in a `WHERE` clause. -You can use the `?_tstart` and `?_tend` parameters whether or not you set `"%timefield%"`. {{kib}} replaces them with the start and end of the time range wherever they appear. +If your data has no `@timestamp` field and you don't specify one, the query isn't filtered by time. + +Wherever you use `?_tstart` and `?_tend`, {{kib}} replaces them with the start and end of the time range, even if you also set `"%timefield%"`. For example, this metric counts documents within the dashboard time range, with no time configuration in the spec: