Available: readPersistedAggregation() v1.252.0

The readPersistedAggregation() function is available from version 1.252.

Available: Rollup Support in readPersistedAggregation() v1.263.0

Rollup Support for Persisted Aggregations is available from version 1.263.0.

The readPersistedAggregation() function reads an existing persisted aggregation (PA) and returns its contents as rows in a table. A PA without rollup support stores result events, and those events are returned by the function. In contrast, a PA with rollup support stores the state of the first aggregator. When you read a PA with rollup support, the function reads the stored aggregator state, performs the rollup operation at the requested span and timezone, and then runs the remainder of the PA query on the rolled-up first aggregator state.

Persisted aggregations allow query results to be stored and retrieved efficiently without re-executing the full query over raw data each time. The readPersistedAggregation() function provides access to those stored results as a table, optionally filtered by time range and grouped by a specified interval.

For Persisted Aggregation with Rollup Support, the readPersistedAggregation() function rolls up the stored aggregation state to the span that you specify. With this rollup, you can query results at a coarser time resolution than the schedule interval. For more information, see Persisted Aggregation with Rollup Support.

Use readPersistedAggregation() in queries when:

  • Dashboard queries โ€” Pre-calculated metrics for dashboards that refresh frequently avoid repeated expensive aggregations. Query persisted results instead of recalculating from raw logs each time the dashboard loads.

  • Baseline analysis โ€” Compare current metrics against historical trends by querying pre-aggregated historical data. Establish baselines from long-term aggregated metrics without storing raw events.

  • Alert queries โ€” Run alerts against pre-aggregated data for faster evaluation and reduced resource consumption. Alerts trigger based on stored metrics rather than real-time aggregation.

  • Long-term trend analysis โ€” Maintain aggregated metrics over extended time periods without storing raw events. Query historical trends from stored aggregations rather than archival logs.

For more information about persisted aggregations, see Persisted Aggregations Syntax. For information about Persisted Aggregation with Rollup Support syntax, see Persisted Aggregation with Rollup Support.

Note

It is recommended to use the readPersistedAggregation() function at the beginning of the query. Using the function later in the query will always discard anything before it, and only return the content of the referenced persisted aggregation.

Function Summary
SignaturereadPersistedAggregation([end], [span], [start], tag, [timezone], [view])
Compatible ContextQuery, Live Query, Aggregate Alert, Filter Alert, Legacy Alert, Parser, Non-aggregate Query
Parameters for readPersistedAggregation()
ParameterTypeInterpreted TypeRequiredDefault ValueDescription
endstringstringoptional[a] Same as the primary query The end of the time interval for reading the persisted aggregation, expressed as a time-point string. When specified, this value is validated against the start value, against the current time, and against the PA time interval. When not specified, the end time of the primary query is used.
spanstringstringoptional[a] ย  The target span for the rollup of the aggregation. There is no default value; you must provide this parameter when reading a Persisted Aggregation with Rollup Support. The value must equal or exceed the scheduled interval of the persisted aggregation. For a Persisted Aggregation with Rollup Support, the value must be a positive multiple of the scheduled interval. Omit this parameter for persisted aggregations without rollup support. (added in 1.263)
startstringstringoptional[a] Same as the primary query The start of the time interval for reading the persisted aggregation, expressed as a time-point string. When specified, this value is validated against the end value, against the current time, and against the PA time interval. When not specified, the start time of the primary query is used.
tag[b]stringstringrequired ย  The tag that identifies the persisted aggregation to read. The tag must correspond to an existing PA in the specified or default view.
timezonestringstringoptional[a] ย  The timezone in which to perform the rollup. There is no default value; you must provide this parameter when reading a Persisted Aggregation with Rollup Support. Currently, only UTC is supported. See Supported Time Zones for the list of timezone values supported by LogScale. (added in 1.263)
viewstringstringoptional[a] Same as the primary query The view in which to locate the persisted aggregation. When not specified, the view of the primary query is used. The specified view must contain a PA matching the provided tag value.

[a] Optional parameters use their default value unless explicitly set.

[b] The parameter name tag can be omitted.

Hide omitted argument names for this function

Show omitted argument names for this function

readPersistedAggregation() Function Operation

readPersistedAggregation() reads events from a repository (view) with tags that match the tag parameter. The function then filters the events by the specified time range and outputs the results.

  • The readPersistedAggregation() function locates the persisted aggregation identified by the tag parameter within the specified or default view.

  • When start and end are not specified, the function uses the same time interval as the primary query. When specified, these values are validated against each other, against the current time, and against the PA time interval.

  • The view parameter identifies the view in which the PA is located. When not specified, the view of the primary query is used.

  • The span parameter sets the time resolution for rollup retrieval. The specified value must be equal to or coarser than the PA schedule interval.

  • The timezone parameter specifies the timezone for the rollup operation. There is no default value; you must provide this parameter when reading a Persisted Aggregation with Rollup Support. Currently, only UTC is supported.

Note

The readPersistedAggregation() function is permitted only in static queries. It is not permitted in cross-products such as sequence functions.

Persisted Aggregation with Rollup Support

Persisted Aggregation with Rollup Support is a variant of persisted aggregation. At read time, you can retrieve the aggregation at a coarser time resolution than the schedule interval provides. This flexibility is especially helpful for persisted aggregations that store metrics.

For example, you create a Persisted Aggregation with Rollup Support that stores average incoming bytes on an hourly schedule. From that same persisted aggregation, you can retrieve daily, weekly, and monthly average incoming bytes. To do so, pass 1d, 1w, or 1month as the span parameter. For a detailed explanation, see readPersistedAggregation() Syntax Examples.

For a Persisted Aggregation with Rollup Support, readPersistedAggregation() completes these actions in order:

  1. Reads the stored first aggregator states within the search time range.

  2. Rolls up the first aggregator states to the span that you specify in the span parameter. A rollup operation merges smaller aggregation states, such as an hourly count, into larger aggregation states, such as a daily count.

  3. Runs the remainder of the query from the rolled-up aggregator.

This behavior resumes the persisted aggregation query from the first aggregator at the time resolution that you request.

Basic Usage

This example demonstrates basic usage of readPersistedAggregation(), reading all events from a persisted aggregation by specifying a tag and view.

In this scenario, a persisted aggregation exists with the tag myTag in the view myView. The query retrieves all events stored under that tag. Only events matching the specified tag are returned; events from other tags in the same view are excluded.

logscale
readPersistedAggregation("myTag", view="myView")

If event data looks like this:

field1field2@timestamp
value1value21451606301001
value3<no value>1451606301003

it would return:

field1field2@timestamp
value1value21451606301001
value3<no value>1451606301003
Absolute Time Interval

This example demonstrates filtering events using an absolute time interval specified as Unix millisecond timestamps. Only events with a @timestamp value in the range [start, end) are returned.

In this scenario, the persisted aggregation contains four events with timestamps spread across a short interval. The query specifies an absolute start of 1451606301002 and an absolute end of 1451606301010. Events with timestamps before start or at and after end are excluded from the result.

logscale
readPersistedAggregation("myTag", view="myView", start=1451606301002, end=1451606301010)

If event data looks like this:

field1@timestamp
11451606301001
21451606301003
31451606301008
41451606301015

it would return:

field1@timestamp
21451606301003
31451606301008
Relative Time Interval

This example demonstrates filtering events using relative durations for start and end. Relative values are interpreted as offsets back from the outer query's end time.

In this scenario, the outer query has an end time of 1451606301020. Specifying start=17ms and end=3ms translates to the absolute range [1451606301003, 1451606301017), that is, from 17 milliseconds before the query end time up to 3 milliseconds before the query end time. Events outside this range are excluded.

logscale
readPersistedAggregation("myTag", view="myView", start=17ms, end=3ms)

If event data looks like this:

field1@timestamp
11451606301001
21451606301003
31451606301008
41451606301015
51451606301018

it would return:

field1@timestamp
21451606301003
31451606301008
41451606301015
Empty Persisted Aggregation

This example demonstrates the behaviour of readPersistedAggregation() when the specified persisted aggregation contains no events.

When the persisted aggregation identified by tag myTag in view myView has no stored events, the function returns an empty result set. No error is raised; the query simply produces no output rows.

logscale
readPersistedAggregation("myTag", view="myView")

If the persisted aggregation contains no events, the query returns an empty result set with no rows.

Enriching Results with match()

This example enriches the results of a persisted aggregation using a lookup file.

In this scenario, the persisted aggregation has the tag myTag in the view myView, and stores one row per service and humio_cluster_id. Because readPersistedAggregation() emits ordinary events, those rows can be enriched from a lookup file before being processed further. A per-cluster cost rate is looked up with match(), the strict parameter is set to false so that rows whose cluster is absent from the file are kept, default() supplies a fallback rate for those rows, and the costs are then summed per service.

The lookup file search_cost_rates.csv contains the following:

csv
"humio_cluster_id","cost_per_cpu_hour"
"cluster-a","0.01"
logscale
readPersistedAggregation("myTag", view="myView")
| match(file="search_cost_rates.csv", field=humio_cluster_id, column=humio_cluster_id, include=[cost_per_cpu_hour], strict=false)
| default(value="0.004", field=cost_per_cpu_hour)
| total_cost_usd := total_cpu_ms / 3600000 * cost_per_cpu_hour
| groupBy(service, function=sum(total_cost_usd, as=cost_usd))

If event data looks like this:

servicehumio_cluster_idtotal_cpu_ms@timestamp
searchcluster-a72000001451606400000
ingestcluster-b36000001451606400000

it would return:

servicecost_usd
ingest0.004
search0.02

The search service ran for two CPU hours on cluster-a at the rate from the file, which is 0.01, giving 0.02. The cluster cluster-b is not in the file, so the ingest service is priced at the default rate of 0.004 for its single CPU hour. Without the strict parameter set to false, the ingest result would have been dropped instead.

Persisted Aggregation with Rollup Support: Rolling Up avg()

This example rolls up an avg() aggregate to a coarser span.

In this scenario, a persisted aggregation with rollup support has the tag myTag in the view myView, runs on an hourly schedule, and stores avg(x). One event arrives at 00:01, in the first hour, and three events arrive at 01:01, 01:02 and 01:03, in the second hour. A span of 2h merges both hourly states into a single result. A rollup is not a plain addition of the results of each scheduled run: every aggregate is merged by its own rule, so that the rolled-up result is the same as the one the query would have produced had it been scheduled at the coarser interval. For avg(), this means that the rolled-up average is weighted by how many events each run saw. It is not an average of averages.

logscale
readPersistedAggregation("myTag", view="myView", span="2h", timezone="UTC")

If event data looks like this:

x@timestamp
101451606460000
11451610060000
21451610120000
31451610180000

it would return:

_avg@timestamp
41451606400000

Each scheduled run stored the following state, which is what a span of 1h would return:

csv
"_avg","@timestamp"
"10","1451606400000"
"2","1451610000000"

The two hours hold four events with a total sum of 16, so the rolled-up average is 4. An average of the two hourly averages would instead have returned 6.

Persisted Aggregation with Rollup Support: Rolling Up groupBy()

This example rolls up a groupBy() aggregate to a coarser span.

In this scenario, a persisted aggregation with rollup support has the tag myTag in the view myView, runs on a 10-minute schedule, and stores groupBy(x, function=count()). Events arrive at 00:01, 00:02 and 00:03 in the first run, at 00:11 and 00:12 in the second run, and at 00:21 and 00:22 in the third run, so the value alpha appears in the first two runs but not in the third. A span of 30m merges all three runs. Groups are merged by key, and keys that only some of the runs saw are carried through as they are.

logscale
readPersistedAggregation("myTag", view="myView", span="30m", timezone="UTC")

If event data looks like this:

x@timestamp
alpha1451606460000
alpha1451606520000
beta1451606580000
alpha1451607060000
beta1451607120000
beta1451607660000
beta1451607720000

it would return:

x_count@timestamp
alpha31451606400000
beta41451606400000

Each scheduled run stored the following state, which is what a span of 10m would return:

csv
"x","_count","@timestamp"
"alpha","2","1451606400000"
"beta","1","1451606400000"
"alpha","1","1451607000000"
"beta","1","1451607000000"
"beta","2","1451607600000"

The value alpha was not seen in the last run, but it is still part of the rolled-up result.

Persisted Aggregation with Rollup Support: Rolling Up stats()

This example rolls up a stats() aggregate to a coarser span.

In this scenario, a persisted aggregation with rollup support has the tag myTag in the view myView, runs on a 10-minute schedule, and stores stats([count(), sum(x)]). Events arrive at 00:01 and 00:02 in the first run, at 00:11 in the second run, and at 00:21 and 00:22 in the third run. A span of 30m merges all three runs into a single result. Each aggregate is merged by its own rule, at every level of nesting.

logscale
readPersistedAggregation("myTag", view="myView", span="30m", timezone="UTC")

If event data looks like this:

x@timestamp
101451606460000
201451606520000
51451607060000
11451607660000
21451607720000

it would return:

_count_sum@timestamp
5381451606400000

Each scheduled run stored the following state, which is what a span of 10m would return:

csv
"_count","_sum","@timestamp"
"2","30","1451606400000"
"1","5","1451607000000"
"2","3","1451607600000"

The _count aggregate is merged by addition and the _sum aggregate is merged by addition, giving 5 and 38 respectively. Aggregates may also be nested, as in groupBy(x, function=stats([count(), sum(y)])) or groupBy(x, function=groupBy(y, function=count())). Nested results are merged the same way, and group keys must match at every level for their results to be merged.

Persisted Aggregation with Rollup Support: Post Processing

This example post-processes a rolled-up result in the reading query.

In this scenario, a persisted aggregation with rollup support has the tag myTag in the view myView, runs on a 10-minute schedule, and stores groupBy(x, function=count()), with events arriving at 00:01, 00:02 and 00:03 in the first run, at 00:11 and 00:12 in the second run, and at 00:21 and 00:22 in the third run. Everything after the first aggregate is re-run from the rolled-up result, so a persisted aggregation whose query continues past the first aggregate is post-processed at the requested span rather than at the schedule interval. Post-processing can also be done in the reading query, since readPersistedAggregation() emits ordinary events. Here, the rolled-up groups are sorted by count in descending order.

logscale
readPersistedAggregation("myTag", view="myView", span="30m", timezone="UTC")
| sort(_count, order=desc)

If event data looks like this:

x@timestamp
alpha1451606460000
alpha1451606520000
beta1451606580000
alpha1451607060000
beta1451607120000
beta1451607660000
beta1451607720000

it would return:

x_count@timestamp
beta41451606400000
alpha31451606400000

The sort() function is applied to the merged 30-minute result, not to the individual 10-minute runs.

This example reads a persisted aggregation for a time range in which no events were seen.

In this scenario, the persisted aggregation has the tag myTag in the view myView, runs on an hourly schedule, and stores count(). There are no events in the requested time range, so there is no event data. When the persisted aggregation saw no events in the requested time range, the query still runs on the empty state.

logscale
readPersistedAggregation("myTag", view="myView", span="1h", timezone="UTC")

it would return:

_count@timestamp
00

Note

In the absence of a bucket to derive the start time, the system stamps the output with a @timestamp value of 0.

Persisted Aggregation with Rollup Support: Enriching a Rolled-Up Result with match()

This example enriches a rolled-up result with a lookup file.

In this scenario, a persisted aggregation with rollup support has the tag myTag in the view myView, runs on an hourly schedule, and stores groupBy([service, humio_cluster_id], function=sum(cpu_ms, as=total_cpu_ms)). Events arrive at 00:01 and 00:02 in the first hour, and at 01:01 and 01:02 in the second hour. A span of 2h merges both hourly states before the match() enrichment is applied. Enrichment works on a rolled-up result too. The match() function here runs after the first aggregate, which is allowed in the reading query even though it is not allowed after the first aggregate inside the persisted aggregation itself.

The lookup file search_cost_rates.csv contains the following:

csv
"humio_cluster_id","cost_per_cpu_hour"
"cluster-a","0.01"
logscale
readPersistedAggregation("myTag", view="myView", span="2h", timezone="UTC")
| match(file="search_cost_rates.csv", field=humio_cluster_id, column=humio_cluster_id, include=[cost_per_cpu_hour], strict=false)
| default(value="0.004", field=cost_per_cpu_hour)
| total_cost_usd := total_cpu_ms / 3600000 * cost_per_cpu_hour
| groupBy(service, function=sum(total_cost_usd, as=cost_usd))

If event data looks like this:

servicehumio_cluster_idcpu_ms@timestamp
searchcluster-a36000001451606460000
ingestcluster-b18000001451606520000
searchcluster-a36000001451610060000
ingestcluster-b18000001451610120000

it would return:

servicecost_usd
ingest0.004
search0.02

Each scheduled run stored the following state, which is what a span of 1h would return:

csv
"service","humio_cluster_id","total_cpu_ms","@timestamp"
"search","cluster-a","3600000","1451606400000"
"ingest","cluster-b","1800000","1451606400000"
"search","cluster-a","3600000","1451610000000"
"ingest","cluster-b","1800000","1451610000000"

Rolled up to two hours, the search service on cluster-a accounts for 7200000 ms and the ingest service on cluster-b for 3600000 ms, so the costs are the same as in the first example above. Enriching a rolled-up result therefore produces the same figures as enriching an equivalent pre-aggregated total.

Timezone Support for Persisted Aggregations with Rollup Support

Persisted aggregations are saved in the UTC timezone by default. Timezone conversion is not supported when reading persisted aggregations. The rollup operation therefore operates on UTC. Rolling data up to a day is equivalent to rolling up to a UTC day.

When you read a Persisted Aggregation with Rollup Support, you must explicitly provide timezone. Currently, only UTC is supported.

Calendar Time for Persisted Aggregations with Rollup Support

The span parameter currently accepts only fixed-duration time values. This means a day is always 24 hours, a week is always 7 days, a month is always 30 days, and a year is always 365 days, as described in Relative Time Syntax.

Calendar time is not supported when rolling up persisted aggregations.

Click + next to an example below to get the full details.

Retrieve Events from a Persisted Aggregation

Reading events stored in a persisted aggregation from a specific view using the readPersistedAggregation() function

Query
logscale
readPersistedAggregation("myTag", view="myView")
Introduction

In this example, the readPersistedAggregation() function is used to retrieve all events stored under the tag myTag in the view myView. Only events matching the specified tag are returned; events from other tags in the same view are excluded.

In this scenario, a persisted aggregation has been set up to periodically aggregate web server access log data โ€” counting requests per HTTP status code and endpoint โ€” and store the results under the tag myTag in the view myView. The readPersistedAggregation() function is then used to read back those stored results for further analysis or visualization without re-running the original aggregation query.

Example incoming data might look like this:

@timestampstatus_codeendpointrequest_countavg_response_mserror_rate
2026-03-15T08:00:00Z200/api/users15231420.00
2026-03-15T08:00:00Z200/api/products987980.00
2026-03-15T08:00:00Z200/api/orders6542100.00
2026-03-15T08:00:00Z301/api/legacy45120.00
2026-03-15T08:00:00Z400/api/users78551.00
2026-03-15T08:00:00Z400/api/products34481.00
2026-03-15T08:00:00Z401/api/orders112331.00
2026-03-15T08:00:00Z403/api/admin29281.00
2026-03-15T08:00:00Z404/api/users56221.00
2026-03-15T08:00:00Z404/api/products41191.00
2026-03-15T08:00:00Z500/api/orders188901.00
2026-03-15T08:00:00Z500/api/users712401.00
2026-03-15T08:00:00Z503/api/products321001.00
2026-03-15T09:00:00Z200/api/users17891380.00
2026-03-15T09:00:00Z200/api/products1102950.00
2026-03-15T09:00:00Z200/api/orders7232050.00
2026-03-15T09:00:00Z301/api/legacy38110.00
2026-03-15T09:00:00Z400/api/users91521.00
2026-03-15T09:00:00Z401/api/orders98311.00
2026-03-15T09:00:00Z404/api/products63201.00
2026-03-15T09:00:00Z500/api/orders229101.00
2026-03-15T09:00:00Z503/api/users519801.00
Step-by-Step
  1. Starting with the source repository events.

  2. logscale
    readPersistedAggregation("myTag", view="myView")

    The readPersistedAggregation() function retrieves all events previously stored in the persisted aggregation identified by the tag myTag. The view parameter specifies that the aggregation is read from the view named myView. If the view parameter is omitted, the function defaults to reading from the current view in which the query is executed. Only events associated with the tag myTag are returned; any other persisted aggregations stored under different tags within myView are excluded from the result set. The function acts as a source in the query pipeline, meaning it replaces the normal event stream with the stored aggregation results, making it suitable as the first and only statement when the goal is simply to retrieve the persisted data.

  3. Event Result set.

Summary and Results

The query is used to read back pre-aggregated web server access log data that was previously stored under the tag myTag in the view myView, returning all fields and events captured at the time the persisted aggregation was last written.

This query is useful, for example, to power dashboards or alerts that need to display aggregated HTTP traffic metrics โ€” such as request counts, average response times, and error rates per endpoint and status code โ€” without incurring the cost of re-running the full aggregation query over raw log data each time.

Sample output from the incoming example data:

@timestampstatus_codeendpointrequest_countavg_response_mserror_rate
2026-03-15T08:00:00Z200/api/users15231420.00
2026-03-15T08:00:00Z200/api/products987980.00
2026-03-15T08:00:00Z200/api/orders6542100.00
2026-03-15T08:00:00Z301/api/legacy45120.00
2026-03-15T08:00:00Z400/api/users78551.00
2026-03-15T08:00:00Z400/api/products34481.00
2026-03-15T08:00:00Z401/api/orders112331.00
2026-03-15T08:00:00Z403/api/admin29281.00
2026-03-15T08:00:00Z404/api/users56221.00
2026-03-15T08:00:00Z404/api/products41191.00
2026-03-15T08:00:00Z500/api/orders188901.00
2026-03-15T08:00:00Z500/api/users712401.00
2026-03-15T08:00:00Z503/api/products321001.00
2026-03-15T09:00:00Z200/api/users17891380.00
2026-03-15T09:00:00Z200/api/products1102950.00
2026-03-15T09:00:00Z200/api/orders7232050.00
2026-03-15T09:00:00Z301/api/legacy38110.00
2026-03-15T09:00:00Z400/api/users91521.00
2026-03-15T09:00:00Z401/api/orders98311.00
2026-03-15T09:00:00Z404/api/products63201.00
2026-03-15T09:00:00Z500/api/orders229101.00
2026-03-15T09:00:00Z503/api/users519801.00

Note that the output is a direct reflection of the data stored in the persisted aggregation at the time it was last written โ€” no additional filtering, transformation, or re-aggregation is applied by the readPersistedAggregation() function itself.

Note also that events from other tags that may exist within myView are entirely absent from the results, confirming that the tag filter is applied strictly. Note that the error_rate field carries a value of 1.00 for all non-2xx and non-3xx status codes, reflecting that these were pre-computed and stored as part of the original aggregation logic, and their meaning depends entirely on how the persisted aggregation was defined.

Roll Up Persisted Aggregation Results

Reading hourly persisted average response times rolled up into two-hour spans using the readPersistedAggregation() function with avg()

Query
logscale
readPersistedAggregation("myTag", view="myView", span="2h", timezone="UTC")
Introduction

In this example, the readPersistedAggregation() function is used to read a persisted aggregation tagged myTag in the view myView, and to roll up its hourly results into two-hour spans.

The persisted aggregation is scheduled to run hourly and consists of this single aggregate query, which computes the average response time of the events seen in each run:

logscale
avg(responseTime)

The first scheduled run covers the hour starting at 00:00 and observes 4 events with the values 10, 8, 12 and 10, resulting in a _avg of 10. The second scheduled run covers the hour starting at 01:00 and observes 12 events, resulting in a _avg of 2.

Example incoming data might look like this:

@timestampendpointresponseTime
1767225660000/api/login10
1767226500000/api/search8
1767227520000/api/search12
1767228420000/api/login10
1767229260000/api/login1
1767229320000/api/search2
1767229380000/api/search3
1767229800000/api/login1
1767230100000/api/search2
1767230400000/api/search3
1767230700000/api/login2
1767231000000/api/search2
1767231300000/api/search2
1767231600000/api/login2
1767231900000/api/search2
1767232200000/api/search2
Step-by-Step
  1. Starting with the source repository events.

  2. logscale
    readPersistedAggregation("myTag", view="myView", span="2h", timezone="UTC")

    Reads the results already computed and saved by the persisted aggregation tagged myTag. The tag is given as the first, implicit parameter and identifies which persisted aggregation to read the results from.

    The view parameter specifies that the persisted aggregation belongs to the view named myView, which is the view in which the aggregation is scheduled to run.

    The span parameter requests the results in two-hour buckets. As the persisted aggregation is scheduled hourly, the values of two consecutive scheduled runs are merged into each bucket. The value of span must be a multiple of the schedule interval of the persisted aggregation.

    The timezone parameter specifies the timezone in which to perform the rollup. Only UTC is currently supported. A rollup to a day with timezone set to UTC means a calendar day in UTC, not in the local timezone of the user.

    Because the persisted aggregation uses avg() without the as parameter, the average is returned in the default output field named _avg. Each returned event also has a @timestamp field holding the start of the bucket that the value belongs to.

    The merge rule for avg() weights each scheduled run by the number of events it observed. The run starting at 00:00 contributes a sum of 40 over 4 events and the run starting at 01:00 contributes a sum of 24 over 12 events, giving a rolled-up average of 4 for the two-hour bucket starting at 00:00.

  3. Event Result set.

Summary and Results

The query is used to read the precomputed results of an hourly persisted aggregation and roll them up into coarser two-hour spans, returning a correctly weighted average response time per span.

This query is useful, for example, to report long-term response time trends at a lower resolution than the schedule interval of the persisted aggregation, without having to query the raw events again. Reading persisted results keeps such reporting queries cheap and allows them to cover periods that reach beyond the retention of the underlying events.

Sample output from the incoming example data:

@timestamp_avg
17672256000004

Note that the rolled-up value is 4 and not 6. A plain average of the two scheduled run results, 10 and 2, would have returned 6, but the roll up weights each run by the number of events it observed, so the 12 events of the second run count more than the 4 events of the first run. Note also that the returned @timestamp is the start of the two-hour bucket, 00:00, and that both scheduled runs fall into this single bucket, which is why only one result event is returned.