series_less
You use series_less when you want to evaluate trends across sequences of numeric values. It’s especially useful in time series analysis, anomaly detection, or comparing metrics side by side. For example, you can check if response times are decreasing compared to a baseline or if one service consistently performs faster than another.
Usage#
Syntax#
series_less(array1, array2)Parameters#
| Parameter | Type | Description |
|---|---|---|
array1 |
array | The first array of numeric values. |
array2 |
array | The second array of numeric values. Must have the same length as array1. |
Returns#
An array of Boolean values. Each element is true if the corresponding element in array1 is less than the element in array2, otherwise false.
Use case examples#
You want to check whether the average request duration in each city is less than a fixed threshold of 150 milliseconds.
Query
['sample-http-logs']
| take 50
| make-series city_avg = avg(req_duration_ms) on _time step 1h by ['geo.city']
| extend threshold = dynamic([150, 150, 150])
| extend is_less = series_less(city_avg, threshold)Output
| geo.city | city_avg | threshold | is_less |
|---|---|---|---|
| London | [120, 90, 100] | [150, 150, 150] | [true, true, true] |
| Paris | [180, 200, 190] | [150, 150, 150] | [false, false, false] |
This query shows whether each city’s request duration stays below a 150 ms threshold at each time step.
You want to detect if failed requests in each country are consistently less than successful requests.
Query
['sample-http-logs']
| take 50
| summarize success = countif(status == '200'), failure = countif(status != '200') by ['geo.country'], bin(_time, 1h)
| make-series success_series = avg(success), failure_series = avg(failure) on _time step 1h by ['geo.country']
| extend failures_less = series_less(failure_series, success_series)Output
| geo.country | success_series | failure_series | failures_less |
|---|---|---|---|
| US | [300, 280, 310] | [10, 20, 15] | [true, true, true] |
| UK | [150, 140, 160] | [20, 25, 30] | [true, true, true] |
This query checks whether failures stay consistently lower than successful requests across time intervals.
List of related functions#
- series_greater_equals: Compares two arrays and returns
truewhen elements in the first array are greater than or equal to the second array. - series_greater: Compares two arrays and returns
truewhere the first array element is greater than the second. - series_less_equals: Compares two arrays and returns
truewhere the first array element is less than or equal to the second. - series_not_equals: Compares two arrays and returns
truewhere elements aren’t equal.
Other query languages#
Splunk SPL users
In Splunk SPL, comparisons across series typically rely on eval with conditional expressions or custom logic in combination with timechart. In contrast, APL provides specialized series_* functions like series_less to directly compare arrays element by element.
Splunk example
... | timechart avg(req_duration_ms) as avg_dur
| eval faster = if(avg_dur < 200, true, false)APL equivalent
['sample-http-logs']
| make-series avg(req_duration_ms) on _time step 1m
| extend is_less = series_less(avg_req_duration_ms, array_concat(dynamic([200])))ANSI SQL users
In ANSI SQL, you normally compare scalar values rather than arrays. To compare sequences, you need to join tables with offsets or use window functions. In APL, series_less simplifies this by applying the comparison across arrays in a single step.
SQL example
SELECT t1._time,
CASE WHEN t1.req_duration_ms < t2.req_duration_ms THEN true ELSE false END AS is_less
FROM logs t1
JOIN logs t2
ON t1._time = t2._timeAPL equivalent
['sample-http-logs']
| make-series avg(req_duration_ms) on _time step 1m
| extend compare = series_less(avg_req_duration_ms, avg_req_duration_ms[1:])