Skip to main content
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.
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:
Run in Playground 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:

Supported directives

The following directives are currently supported in Axiom’s MPL implementation: Use string values for custom_unit. Set it to "1" to render values as unitless numbers. Examples:

Source

Specify the dataset, the metric, and optional time bounds. Syntax:
  • 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:

Filter

Use where to filter series based on tag values. Syntax:
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:

Map

Use map to transform individual values. Available functions: Examples:

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. Example:

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. Example:

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:
Available aggregation functions: Examples:

Group

Use group by to combine series by tags. Syntax:
If you don’t specify tags, Axiom aggregates all series into one group. Available aggregation functions: Examples:

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:
Available functions:
interpolate_cumulative_histogram works on histogram metrics using cumulative temporality. interpolate_delta_histogram works on histogram metrics using delta temporality.
Examples:

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:
  • 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:

Other operations

Compute

Combine multiple metrics in one query block. Syntax:
Available operators: 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.
Example:
Run in Playground

Language features

Data types

  • Strings: "string"
    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: Example:

Time ranges

Syntax:
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: