make-series
This page explains how to use the make-series operator in APL.
Introduction
The make-series operator transforms event data into array-based time series. Instead of producing one row per time bucket, make-series encodes the values and corresponding timestamps into arrays stored in table fields. This makes it possible to apply series_* functions for advanced manipulations such as moving averages, smoothing, anomaly detection, or other time-series computations.
You find this operator useful when you want to:
- Turn event data into array-encoded time series for further analysis.
- Apply
series_*functions (for example,series_fir,series_stats) to aggregated data. - Postprocess and then expand arrays back into rows with
mv-expandfor visualization or downstream queries.
Unlike summarize, which produces row-based aggregations, make-series is designed specifically for creating and manipulating array-based time series.
Usage
Syntax
Parameters
| Parameter | Description |
|---|---|
Aggregation | One or more aggregation functions (for example, avg(), count(), sum()) applied to each time bin, producing arrays of values. |
default | A value to use when no records exist in a time bin. |
TimeField | The field containing timestamps used for binning. |
Range | An optional range expression specifying the start and end of the series (for example, from ago(1h) to now()). |
StepSize | The size of each time bin (for example, 1m, 5m, 1h). |
GroupingField | Optional fields to split the series by, producing parallel arrays for each group. |
Returns
The operator returns a table where each aggregation produces an array of values aligned with an array of time bins. Each row represents a group (if specified), with arrays that encode the entire time series.
Use case examples
You want to create an array-based time series of request counts, then compute a rolling average using a series_* function, and finally expand back into rows for visualization.
Query
Output
| _time | count_ | moving_avg_count |
|---|---|---|
| 2025-09-29T10:00:00 | 120 | 118 |
| 2025-09-29T10:05:00 | 130 | 122 |
| 2025-09-29T10:10:00 | 110 | 121 |
The query turns request counts into arrays, applies a smoothing function, and then expands the arrays back into rows for analysis.
You want to analyze span durations per service, storing them as arrays for later manipulation.
Query
Output
| service.name | avg_duration | time |
|---|---|---|
| frontend | [20ms, 18ms, 22ms, 19ms, ...] | [2025-09-29T08:00, ...] |
| checkout | [35ms, 40ms, 33ms, 37ms, ...] | [2025-09-29T08:00, ...] |
The query produces array-encoded time series per service, which you can further process with series_* functions.
You want to analyze the rate of HTTP 500 errors in your logs per minute.
Query
Output
| count_ | _time |
|---|---|
| [1489, 1428, 1517, 1462, 1509, ...] | ["2025-09-30T09:08:14.921301725Z", "2025-09-30T09:09:14.921301725Z", ...] |
The query generates a time series of HTTP 500 error counts as an array-based time series for further analysis with series_* functions.
List of related operators
- extend: Creates new calculated fields, often as preparation before
make-series. Useextendwhen you want to preprocess data for time series analysis. - mv-expand: Expands arrays into multiple rows. Use
mv-expandto work with the arrays returned bymake-series. - summarize: Aggregates rows into groups but doesn't generate continuous time bins. Use
summarizewhen you want flexible grouping without forcing evenly spaced intervals. - top: Returns the top rows by a specified expression, not time series. Use
topwhen you want to focus on the most significant values instead of trends over time.