Docs
DocumentationQuery ReferenceAPI Reference
Open Console→→
DocumentationQuery ReferenceAPI Reference

Introduction

Query reference overview

APL

IntroductionSample queriesAll features
Functions
Scalar functions
Array functions
Overview
array_concat
array_extract
array_iff
array_index_of
array_length
array_reverse
array_rotate_left
array_rotate_right
array_select_dict
array_shift_left
array_shift_right
array_slice
array_sort_asc
array_sort_desc
array_split
array_sum
bag_has_key
bag_keys
bag_pack
bag_zip
isarray
len
pack_array
pack_dictionary
strcat_array
Conditional functions
Overview
case
iff
Conversion functions
Overview
dynamic_to_json
ensure_field
isbool
toarray
tobool
todatetime
todouble, toreal
todynamic
tohex
toint, tolong
tostring
totimespan
Datetime functions
Overview
ago
datetime_add
datetime_diff
datetime_part
dayofmonth
dayofweek
dayofyear
endofday
endofmonth
endofweek
endofyear
getmonth
getyear
hourofday
monthofyear
now
startofday
startofmonth
startofweek
startofyear
unixtime_microseconds_todatetime
unixtime_milliseconds_todatetime
unixtime_nanoseconds_todatetime
unixtime_seconds_todatetime
week_of_year
GenAI functions
Overview
genai_concat_contents
genai_conversation_turns
genai_cost
genai_estimate_tokens
genai_extract_assistant_response
genai_extract_function_results
genai_extract_system_prompt
genai_extract_tool_calls
genai_extract_user_prompt
genai_get_content_by_index
genai_get_content_by_role
genai_get_pricing
genai_get_role
genai_has_tool_calls
genai_input_cost
genai_is_truncated
genai_message_roles
genai_output_cost
Hash functions
Overview
hash
hash_md5
hash_sha1
hash_sha256
hash_sha512
IP functions
Overview
format_ipv4
format_ipv4_mask
geo_info_from_ip_address
has_any_ipv4
has_any_ipv4_prefix
has_ipv4
has_ipv4_prefix
ipv4_compare
ipv4_is_in_range
ipv4_is_in_any_range
ipv4_is_match
ipv4_is_private
ipv4_netmask_suffix
ipv6_compare
ipv6_is_in_any_range
ipv6_is_in_range
ipv6_is_match
parse_ipv4
parse_ipv4_mask
Mathematical functions
Overview
abs
acos
asin
atan
atan2
cos
cot
degrees
exp
exp2
exp10
gamma
isfinite
isinf
isint
isnan
log
log2
log10
loggamma
max_of
min_of
not
pi
pow
radians
rand
range
round
set_difference
set_has_element
set_intersect
set_union
sign
sin
sqrt
tan
Metadata functions
Overview
column_ifexists
cursor_current
ingestion_time
Pair functions
Overview
find_pair
pair
parse_pair
Rounding functions
Overview
bin
bin_auto
ceiling
floor
String functions
Overview
base64_decode_toarray
base64_decode_tostring
base64_encode_fromarray
base64_encode_tostring
coalesce
countof
countof_regex
extract
extract_all
format_bytes
format_url
gettype
indexof
indexof_regex
isascii
isempty
isnotempty
isnotnull
isnull
parse_bytes
parse_csv
parse_json
parse_path
parse_url
parse_urlquery
quote
regex_quote
replace
replace_regex
replace_string
reverse
split
strcat
strcat_delim
strcmp
string_size
strlen
strrep
strip_ansi_escapes
substring
tolower
totitle
toupper
translate
trim
trim_end
trim_end_regex
trim_regex
trim_space
trim_start
trim_start_regex
unicode_codepoints_from_string
unicode_codepoints_to_string
url_decode
url_encode
SQL functions
Overview
parse_sql
format_sql
Time series functions
Overview
series_abs
series_acos
series_add
series_asin
series_atan
series_ceiling
series_cos
series_cosine_similarity
series_divide
series_dot_product
series_equals
series_exp
series_fft
series_fill_backward
series_fill_const
series_fill_forward
series_fill_linear
series_fir
series_floor
series_greater
series_greater_equals
series_ifft
series_iir
series_less
series_less_equals
series_log
series_magnitude
series_max
series_min
series_multiply
series_not_equals
series_pearson_correlation
series_pow
series_sign
series_sin
series_stats
series_stats_dynamic
series_subtract
series_sum
series_tan
Type functions
Overview
isimei
ismap
isreal
iscc
isstring
isutf8
Aggregation functions
Overview
arg_min
arg_max
avg
avgif
count
countif
dcount
dcountif
histogram
histogramif
make_list
make_list_if
make_set
make_set_if
max
maxif
min
minif
percentile
percentileif
percentiles_array
percentiles_arrayif
phrases
rate
spotlight
stdev
stdevif
sum
sumif
topk
topkif
variance
varianceif
Operators
Tabular operators
Overview
count
distinct
extend
extend-valid
externaldata
getschema
join
limit
lookup
make-series
mv-expand
order
parse
parse-kv
parse-where
project
project-away
project-keep
project-rename
project-reorder
redact
sample
search
sort
summarize
take
top
union
where
Scalar operators
Set membership operators
Overview
in
!in
in~
!in~
Logical
Numerical
String
Reference
Entity names
Map fields
Null values
Scalar data types
Set statement
Special field attributes
Migrate
Splunk SPL
SQL
Sumo Logic

MPL

Language featuresHistograms and summariesSample queriesMigrate
MPL

Introduction to MPL

This page explains how to use MPL (Metrics Processing Language) to query metrics.

MPL is a metric-focused query language that combines the simplicity of APL with the expressive power of PromQL. It enables effective querying, transformation, and aggregation of metric data, supporting diverse observability use cases.

If you use PromQL, your existing expressions can be translated to MPL for quick onboarding and greater flexibility. For more information, see Migrate PromQL queries to Axiom.

Info

Support for MPL (Metrics Processing Language) is currently in public preview. For more information, see Feature states.

Limitations

The current implementation of MPL comes with the following limitations:

  • You can only query one dataset in a query.

Concepts

  • Dataset: A group of related metrics.
  • Metric: Two-dimensional time series data with a metric name and a set of tags.
  • Tag: Key-value pair identifying a series.
  • Series: A unique combination of a metric and tag set.

Query structure

A typical MPL query contains the following:

  1. Source: Defines dataset, metric, and optional time range
  2. Filter: Applies conditions to series via tags
  3. Transformation can be the following:
    • Map: Maps the data to a new value.
    • Align: Aggregates the data over time to align to a given time interval.
    • Group: Aggregates the data over tag values.
    • Bucket: A two-dimensional transformation that aggregates along both the time and tag dimensions.

Example:

MPLRun in Playground
`otel-demo-metrics`:`go.memory.used`
| where `k8s.deployment.name` == "checkout"
| align to 5m using avg

This example queries the otel-demo-metrics dataset's go.memory.used metric one hour before the current time. It filters results to the frontend service and aggregates values over 5-minute time windows into their average.

Elements of queries

The following explains each element of an MPL query.

To learn more about the language features of MPL, see Language features.

Directives

Use set directives at the start of a query to control query behavior and visualization settings.

Directives must appear before the query body.

Syntax:

APL
set <directive_name> = <directive_value>;

Supported directives

The following directives are currently supported in Axiom's MPL implementation:

DirectiveDescription
custom_unitSets the unit used when visualizing query results in Axiom.

Use string values for custom_unit. Set it to "1" to render values as unitless numbers.

Examples:

MPL
set custom_unit = "ms";
`otel-demo-metrics`:`http.server.request.duration`
| align to 5m using avg
MPL
set custom_unit = "1";
`otel-demo-metrics`:`http.server.request.duration`
| align to 5m using avg

Source

Specify the dataset, the metric, and optional time bounds.

Syntax:

APL
<dataset>:<metric>[<time range>][ as <alias>]
  • dataset: Name of the dataset.
  • metric: Name of the metric.
  • time range: Optional: The time range of the query. For more information, see Time ranges.
  • alias: Optional: Renames the metric for later use.

Examples:

MPL
`otel-demo-metrics`:`go.memory.used`[1h..]
`otel-demo-metrics`:`go.memory.used`[2h..5m]
`otel-demo-metrics`:`go.memory.used`[2025-03-01T13:00:00Z..+1h] as mem_usage

Filter

Use where to filter series based on tag values.

Syntax:

APL
| where <filter-expression>

A filter expression can be one of the following:

  • <tag> <operator> <value> — a single tag filter
  • <filter-expression> and <filter-expression> — logical AND of two expressions
  • <filter-expression> or <filter-expression> — logical OR of two expressions
  • not <filter-expression> — negation of an expression
  • (<filter-expression>) — parentheses to control order of evaluation

Available operators for single tag filters:

  • Equality: ==, !=
  • Comparisons: <, <=, >, >=

The value must be one of the supported data types.

Examples:

APL
| where environment == "production" and status_code >= 200 and status_code < 300

| where (environment == "production" or environment == "staging") and not status_code == 500

Map

Use map to transform individual values.

Available functions:

FunctionDescription
rateComputes the per-second rate of change for a metric.
increaseCalculates the increase between the data point and the previous one.
min(arg)Returns the minimum between the argument and the value.
max(arg)Returns the maximum between the argument and the value.
absReturns the absolute value of each data point.
fill::prevFills missing values using the previous non-null value.
fill::const(arg)Fills missing values with a constant.
interpolate::linearLinear interpolation of missing values.
+, -, *, /Performs the respective mathematical calculation on each value.

Examples:

APL
// Calculate rate per second for the metric
| map rate

// Add 5 to each value
| map + 5

// Fill empty values with the latest value
| map fill::prev

// Fill empty values with zeros
| map fill::const(0)

filter:: functions

Use filter:: functions to remove data points that don't match a condition. Data points that don't match are removed from the series entirely. Unlike where, which filters series based on tag values, filter:: operates on the numeric values of data points within a series.

FunctionDescription
filter::eq(v)Keeps only data points equal to v.
filter::neq(v)Keeps only data points not equal to v.
filter::gt(v)Keeps only data points greater than v.
filter::gte(v)Keeps only data points greater than or equal to v.
filter::lt(v)Keeps only data points less than v.
filter::lte(v)Keeps only data points less than or equal to v.

Example:

APL
// Remove data points where latency exceeds 400ms
| map filter::lt(0.4)

is:: functions

Use is:: functions to test data points against a condition. Matching data points are set to 1.0 and non-matching data points are set to 0.0. The series retains all its data points.

Use is:: instead of filter:: when you need to preserve the shape of the time series, for example in SLO calculations where gaps in data would produce incorrect results.

FunctionDescription
is::eq(v)Sets data points equal to v to 1.0, all others to 0.0.
is::neq(v)Sets data points not equal to v to 1.0, all others to 0.0.
is::gt(v)Sets data points greater than v to 1.0, all others to 0.0.
is::gte(v)Sets data points greater than or equal to v to 1.0, all others to 0.0.
is::lt(v)Sets data points less than v to 1.0, all others to 0.0.
is::lte(v)Sets data points less than or equal to v to 1.0, all others to 0.0.

Example:

APL
// Set to 1.0 where latency is within SLO (below 400ms), 0.0 otherwise
| map is::lt(0.4)

Align

Use align to aggregate over time windows. You can specify the time window and the aggregation function to apply. If you omit to <time_window>, align aggregates over the full query range and returns a single value per series.

Syntax:

APL
| align to <time_window> using <aggregation_function>
| align using <aggregation_function>

Available aggregation functions:

FunctionDescription
avgAverages values in each interval.
countCounts non-null values per interval.
maxTakes the maximum value per interval.
minTakes the minimum value per interval.
prom::ratePromQL-style rate calculation.
sumSums values in each interval.
lastTakes the last value in each interval.

Examples:

APL
// Calculate the average over 5-minute time windows
| align to 5m using avg

// Count the data points in the last hour
| align to 1h using count

// Sum over the full query range
| align using sum

Group

Use group by to combine series by tags.

Syntax:

APL
| group [by <tag1>, <tag2>] using <aggregation_function>

If you don't specify tags, Axiom aggregates all series into one group.

Available aggregation functions:

FunctionDescription
avgAverages values in each interval.
sumSums values in each interval.
minTakes the minimum value per interval.
maxTakes the maximum value per interval.
countCounts non-null values per interval.

Examples:

APL
// Calculate the number of series
| group using count

// Sum all series into a single total
| group using sum

// Group data by the `service` and `namespace` tags using the `sum` aggregation
| group by service, namespace using sum

Bucket

Use bucket to aggregate over time and tag dimensions simultaneously. If you omit to <time_window>, bucket aggregates over the full query range and returns a single value per series.

Syntax:

APL
| bucket [by <tags>] to <window> using <function>
| bucket [by <tags>] using <function>

Available functions:

FunctionDescription
histogram(specs)Aggregates non-histogram series into buckets. specs is one or more quantile values between 0 and 1, or aggregation functions (count, avg, sum, min, max).
interpolate_cumulative_histogram(mode, specs)Aggregates cumulative-temporality histogram series. mode is rate or increase. specs is one or more quantile values or aggregation functions.
interpolate_delta_histogram(specs)Aggregates delta-temporality histogram series. specs is one or more quantile values or aggregation functions.
Info

interpolate_cumulative_histogram works on histogram metrics using cumulative temporality. interpolate_delta_histogram works on histogram metrics using delta temporality.

MPL has no equivalent function for summary metrics. For more information, see Query histogram and summary metrics.

Examples:

APL
// Bucket over the `service` and `endpoint` tags using the histogram aggregation
| bucket by service, endpoint to 5m using histogram(max)

// Compute the 50th and 99th percentiles of request duration for histogram data stored using cumulative temporality
| bucket by service to 1m using interpolate_cumulative_histogram(rate, 0.50, 0.99)

// Compute the 50th and 99th percentiles of request duration for histogram data stored using delta temporality
| bucket by service to 1m using interpolate_delta_histogram(0.50, 0.99)

Extend

Use extend to add new tags to every series in the query result. extend supports ${} interpolation to reference existing tag values or parameters.

extend can only be applied after aggregations (after align, group, bucket, and map).

Syntax:

APL
| extend <tag1> = <value1> [, <tag2> = <value2> ...]
  • The value must be a string, integer, float, or boolean literal.
  • The tag name must be net-new: if any input series already has a tag with the same name, the query fails. To overwrite an existing tag, first drop it with group by, then re-add it with extend.

Examples:

APL
// Add a constant string tag
| extend environment = "production"

// Reference existing tag values
`my-metrics`:http_latency
| where host is string and port is int
| align to 5m using avg
| extend url = "http://${host}:${port}"

Other operations

Compute

Combine multiple metrics in one query block.

Syntax:

APL
(
  <subquery1>,
  <subquery2>
)
| compute <name> using <operator>

Available operators:

OperatorDescription
+Adds subquery results.
-Subtracts one subquery from another.
*Multiplies subquery results.
/Divides one subquery by another.
minMinimum across result series.
maxMaximum across result series.
avgAverage across result series.

compute uses strict intersection semantics. It only combines series with matching tag sets, and it only emits values for timestamps present on both sides. If you want results for timestamps where only one side has a value, fill missing values using map functions.

APL
// Use 0 as the default for addition
(
  <subquery1> | map fill::const(0),
  <subquery2> | map fill::const(0)
)
| compute total using +

// Use 1 as the default for multiplication
(
  <subquery1> | map fill::const(1),
  <subquery2> | map fill::const(1)
)
| compute product using *

Example:

APLRun in Playground
// Return the average error rate over the past 5 minutes
(
  `otel-demo-metrics`:`http.server.request.duration`
  | where `http.response.status_code` >= 500
  | map rate
  | align to 5m using avg
  | group using sum,
  `otel-demo-metrics`:`http.server.request.duration`
  | map rate
  | align to 5m using avg
  | group using sum
)
| compute error_rate using /

Language features

Data types

  • Strings: "string"
    Idea

    Use double quotes (") to enclose the string. Don't use single quotes (').

  • Integers: 42
  • Floats: 3.14
  • Booleans: true, false
  • Regex: #/.*metrics.*/

Identifier naming rules

Identifiers represent fields, metrics, datasets, function names, and other named entities in your query.

Valid identifier names are case-sensitive and follow these rules:

  • Start with an ASCII letter.
  • Followed by zero or more ASCII letters, digits, or underscores (_).

Quote identifiers

Quote an identifier in your MPL query if any of the following is true:

  • The identifier name doesn't match the rules for valid identifier names.
  • The identifier name is identical to one of the reserved keywords of the MPL query language. For example, by or where.

If any of the above is true, you must quote the identifier by enclosing it in backticks (`). For example, `my-field`.

If none of the above is true, you don't need to quote the identifier in your MPL query. For example, myfield. In this case, quoting the identifier name is optional.

Built-in variables

MPL provides the following built-in variables that can be used in queries:

VariableTypeDescription
$__intervaldurationProvides a suitable interval size for charting, depending on the time range of the query.

Example:

MPL
`otel-demo-metrics`:`http.server.request.duration`
| align to $__interval using avg

Time ranges

Syntax:

APL
[<start>..<end>?]

Define time ranges with the following:

  • Start time: Inclusive beginning of the time range.
  • End time: Optional, exclusive end of the time range. If you don't specify the end time, Axiom uses the current time.

Separate the start and the end times with ...

Time can be defined in one of the following ways:

  • Relative time. The time unit can be one of the following:
    • ms for milliseconds (will be rounded to seconds)
    • s for seconds
    • m for minutes
    • h for hours
    • d for days
    • w for weeks
    • M for months
    • y for years Examples: -1h, +5m
  • Unix epoch timestamp in seconds. For example: 1723982394
  • An RFC3339 timestamp. For example: 2025-03-01T13:00:00Z

Examples:

APL
// One hour ago until the current time
[1h..]

// One hour after a Unix timestamp
[1747077736..+1h]

// One hour before a Unix timestamp
[-1h..1747077736]

// One hour before an RFC3339 date
[-1h..2025-03-01T13:00:00Z]
Was this page helpful?
Suggest edits on GitHub
PreviousMigrate from Sumo Logic Query Language to APLNextQuery histogram and summary metrics
On this page
LimitationsConceptsQuery structureElements of queriesDirectivesSupported directivesSourceFilterMapfilter:: functionsis:: functionsAlignGroupBucketExtendOther operationsComputeLanguage featuresData typesIdentifier naming rulesQuote identifiersBuilt-in variablesTime ranges