The readPersistedAggregation() function
reads an existing persisted aggregation (PA) and returns its
contents as rows in a table. A PA persists as the state of the
first aggregator in a query pipeline. Reading a PA requires
reading that state after validation, then executing the
remainder of the PA query before returning the resulting events.
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 more information about persisted aggregations, see Persisted Aggregations.
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.
| Parameter | Type | Required | Default Value | Description |
|---|---|---|---|---|
end | string | optional[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. |
start | string | optional[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 | string | required | Â | The tag that identifies the persisted aggregation to read. The tag must correspond to an existing PA in the specified or default view. |
view | string | optional[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. | ||||
The argument name for function can be omitted.
readPersistedAggregation() Function Operation
The readPersistedAggregation() function
has specific implementation and operational considerations,
outlined below.
The
readPersistedAggregation()function simply reads the events from a Persisted Aggregation Repository (view) with matching tag as provided in the parameter (tag) and then outputs these.The
readPersistedAggregation()function locates the persisted aggregation identified by thetagparameter within the specified or default view.When
startandendare 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
viewparameter identifies the view in which the PA is located. When not specified, the view of the primary query is used.
Note
The readPersistedAggregation() function
is permitted only in static queries. It is not permitted in
cross-products such as sequence functions.
readPersistedAggregation() Syntax Examples
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.
readPersistedAggregation("myTag", view="myView")If event data looks like this:
| field1 | field2 | @timestamp |
|---|---|---|
| value1 | value2 | 1451606301001 |
| value3 | <no value> | 1451606301003 |
it would return:
| field1 | field2 | @timestamp |
|---|---|---|
| value1 | value2 | 1451606301001 |
| value3 | <no value> | 1451606301003 |
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.
readPersistedAggregation("myTag", view="myView", start=1451606301002, end=1451606301010)If event data looks like this:
| field1 | @timestamp |
|---|---|
| 1 | 1451606301001 |
| 2 | 1451606301003 |
| 3 | 1451606301008 |
| 4 | 1451606301015 |
it would return:
| field1 | @timestamp |
|---|---|
| 2 | 1451606301003 |
| 3 | 1451606301008 |
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.
readPersistedAggregation("myTag", view="myView", start=17ms, end=3ms)If event data looks like this:
| field1 | @timestamp |
|---|---|
| 1 | 1451606301001 |
| 2 | 1451606301003 |
| 3 | 1451606301008 |
| 4 | 1451606301015 |
| 5 | 1451606301018 |
it would return:
| field1 | @timestamp |
|---|---|
| 2 | 1451606301003 |
| 3 | 1451606301008 |
| 4 | 1451606301015 |
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.
readPersistedAggregation("myTag", view="myView")If the persisted aggregation contains no events, the query returns an empty result set with no rows.
readPersistedAggregation() Examples
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
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:
| @timestamp | status_code | endpoint | request_count | avg_response_ms | error_rate |
|---|---|---|---|---|---|
| 2026-03-15T08:00:00Z | 200 | /api/users | 1523 | 142 | 0.00 |
| 2026-03-15T08:00:00Z | 200 | /api/products | 987 | 98 | 0.00 |
| 2026-03-15T08:00:00Z | 200 | /api/orders | 654 | 210 | 0.00 |
| 2026-03-15T08:00:00Z | 301 | /api/legacy | 45 | 12 | 0.00 |
| 2026-03-15T08:00:00Z | 400 | /api/users | 78 | 55 | 1.00 |
| 2026-03-15T08:00:00Z | 400 | /api/products | 34 | 48 | 1.00 |
| 2026-03-15T08:00:00Z | 401 | /api/orders | 112 | 33 | 1.00 |
| 2026-03-15T08:00:00Z | 403 | /api/admin | 29 | 28 | 1.00 |
| 2026-03-15T08:00:00Z | 404 | /api/users | 56 | 22 | 1.00 |
| 2026-03-15T08:00:00Z | 404 | /api/products | 41 | 19 | 1.00 |
| 2026-03-15T08:00:00Z | 500 | /api/orders | 18 | 890 | 1.00 |
| 2026-03-15T08:00:00Z | 500 | /api/users | 7 | 1240 | 1.00 |
| 2026-03-15T08:00:00Z | 503 | /api/products | 3 | 2100 | 1.00 |
| 2026-03-15T09:00:00Z | 200 | /api/users | 1789 | 138 | 0.00 |
| 2026-03-15T09:00:00Z | 200 | /api/products | 1102 | 95 | 0.00 |
| 2026-03-15T09:00:00Z | 200 | /api/orders | 723 | 205 | 0.00 |
| 2026-03-15T09:00:00Z | 301 | /api/legacy | 38 | 11 | 0.00 |
| 2026-03-15T09:00:00Z | 400 | /api/users | 91 | 52 | 1.00 |
| 2026-03-15T09:00:00Z | 401 | /api/orders | 98 | 31 | 1.00 |
| 2026-03-15T09:00:00Z | 404 | /api/products | 63 | 20 | 1.00 |
| 2026-03-15T09:00:00Z | 500 | /api/orders | 22 | 910 | 1.00 |
| 2026-03-15T09:00:00Z | 503 | /api/users | 5 | 1980 | 1.00 |
Step-by-Step
Starting with the source repository events.
- logscale
readPersistedAggregation("myTag", view="myView")The
readPersistedAggregation()function retrieves all events previously stored in the persisted aggregation identified by the tagmyTag. Theviewparameter specifies that the aggregation is read from the view namedmyView. If theviewparameter is omitted, the function defaults to reading from the current view in which the query is executed. Only events associated with the tagmyTagare returned; any other persisted aggregations stored under different tags withinmyVieware 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. 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:
| @timestamp | status_code | endpoint | request_count | avg_response_ms | error_rate |
|---|---|---|---|---|---|
| 2026-03-15T08:00:00Z | 200 | /api/users | 1523 | 142 | 0.00 |
| 2026-03-15T08:00:00Z | 200 | /api/products | 987 | 98 | 0.00 |
| 2026-03-15T08:00:00Z | 200 | /api/orders | 654 | 210 | 0.00 |
| 2026-03-15T08:00:00Z | 301 | /api/legacy | 45 | 12 | 0.00 |
| 2026-03-15T08:00:00Z | 400 | /api/users | 78 | 55 | 1.00 |
| 2026-03-15T08:00:00Z | 400 | /api/products | 34 | 48 | 1.00 |
| 2026-03-15T08:00:00Z | 401 | /api/orders | 112 | 33 | 1.00 |
| 2026-03-15T08:00:00Z | 403 | /api/admin | 29 | 28 | 1.00 |
| 2026-03-15T08:00:00Z | 404 | /api/users | 56 | 22 | 1.00 |
| 2026-03-15T08:00:00Z | 404 | /api/products | 41 | 19 | 1.00 |
| 2026-03-15T08:00:00Z | 500 | /api/orders | 18 | 890 | 1.00 |
| 2026-03-15T08:00:00Z | 500 | /api/users | 7 | 1240 | 1.00 |
| 2026-03-15T08:00:00Z | 503 | /api/products | 3 | 2100 | 1.00 |
| 2026-03-15T09:00:00Z | 200 | /api/users | 1789 | 138 | 0.00 |
| 2026-03-15T09:00:00Z | 200 | /api/products | 1102 | 95 | 0.00 |
| 2026-03-15T09:00:00Z | 200 | /api/orders | 723 | 205 | 0.00 |
| 2026-03-15T09:00:00Z | 301 | /api/legacy | 38 | 11 | 0.00 |
| 2026-03-15T09:00:00Z | 400 | /api/users | 91 | 52 | 1.00 |
| 2026-03-15T09:00:00Z | 401 | /api/orders | 98 | 31 | 1.00 |
| 2026-03-15T09:00:00Z | 404 | /api/products | 63 | 20 | 1.00 |
| 2026-03-15T09:00:00Z | 500 | /api/orders | 22 | 910 | 1.00 |
| 2026-03-15T09:00:00Z | 503 | /api/users | 5 | 1980 | 1.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.