Query language
Several Query API fields take short expressions instead of structured messages:
| Field | Expression | Used by |
|---|---|---|
seriesSummaries |
series summary selector with a function | ListRuns, ListRLEnvironments |
filter |
resource filter | ListRuns, ListProjects, ListExperiments, ListDirectories, ListRLEnvironments, ListSpans, AggregateRLEnvironmentSeries, RunsFilter |
orderBy |
ordering | the same listings |
seriesFilters |
series filter | ListSeriesDefinitions |
summaryQueries |
series summary query | ListSeriesSummaries |
seriesQueries |
series query | ListFloatSeries, ListFloatSeriesBuckets, ListFloatSeriesTimestampBuckets, ListHistogramSeries, ListScatterSeries, ListRLEnvironmentFloatSeriesBuckets |
seriesExpression, groupings |
selector and conditions | AggregateRLEnvironmentSeries — see RL environments |
Syntax basics
Section titled “Syntax basics”- Names are bare. Metric names, attribute paths and label keys are written as-is, never quoted — which is why
ingestion rejects names containing whitespace or
( ) [ ] , = < > ! ~ " |. - Values are bare (
gpu0,0.5) or double-quoted ("adam w", with\escapes). Quote any value containing whitespace or one of those characters. - Numbers are written plainly:
107,56.2,1e5,-3. - Booleans are
TrueandFalse. - Timestamps are unquoted:
2026-09-30T09:00:00or2026-09-30T09:00:00.250. - Keywords (
AND,OR,IN,NOT,EXISTS,CONTAINS,ANY,ALL,ASC,DESC, and option names such asscaleandfilter) may be written in upper case, lower case or capitalized:AND,and,And. Function names (last,avg, …) are lower case. - Whitespace between tokens is ignored.
Series summary selectors
Section titled “Series summary selectors”A selector picks series of a run (or of an environment) and, usually, a statistic of them:
METRIC(OPTIONS):FUNCTIONStrain/loss():lasttrain/loss(scale=ML_STEP, filter=(gpu="0")):mineval/accuracy(filter=(split IN ["val", "test"], seed != 0)):maxweights/layer4(value_kind=histogram):last_avgtrain/loss(aggregate=(keys=[host])):last_avgThe parentheses are required, even when empty. Options, in any order:
| Option | Meaning |
|---|---|
scale=S |
The series’ scale. Defaults to ML_STEP when omitted. |
filter=(CONDITIONS) |
Label conditions the series must match. |
aggregate=(keys=[K, …]) |
Address a pre-aggregated series produced by an aggregation rule; keys lists the labels it kept. |
value_kind=K |
The series’ value kind: float (default), histogram, density_histogram, scatter or scatter_3d. |
value_reducer=R |
In series queries on the float endpoints, read a histogram series as floats by reducing each histogram: min, max, avg, std, quantile(Q) (Q from 0 to 1) or fraction_above(X). Requires value_kind=histogram or density_histogram. |
Functions
Section titled “Functions”| Series | Functions |
|---|---|
| Float (regular) | first, last, min, max, sum, avg, count, std — over all of the series’ points. last_min, last_max, last_avg, last_std, last_sum reduce across several matched series at each one’s last point. |
Aggregated (aggregate=) |
min, max, sum, avg, count, std, plus the value across sub-series at the first or last step: first_min, first_max, first_avg, first_std, last_min, last_max, last_avg, last_std. |
| Counting histogram | The last point only: last_count, last_min, last_max, last_sum, last_avg, last_std. |
| Density histogram | last_min, last_max, last_avg, last_std. |
| Scatter | None. Scatter selectors are only valid where no function is needed: EXISTS conditions and series summary queries. |
Where a single value is needed — filters and orderings — give exactly one function. std is the population
standard deviation.
Label conditions
Section titled “Label conditions”filter=(…) takes comma-separated conditions, all of which must hold:
| Condition | Matches series whose label… |
|---|---|
key=value or key==value |
equals the value |
key!=value |
differs from the value |
key IN [v1, v2] |
is one of the values |
key NOT IN [v1, v2] |
is none of the values |
key~="regex" |
matches the regular expression |
key CONTAINS value |
contains the value as a substring |
Conditions need not mention every label a series has; how many series a selector ends up matching decides how its function is computed, as described next.
Label resolution and across-series aggregation
Section titled “Label resolution and across-series aggregation”A selector’s conditions are resolved against the series each run (or environment) actually logged:
- Exactly one series matches — the function is computed on it. This is the case when equality conditions pin every label the series was logged with.
- Several series match — because a label was left unconstrained or a non-equality operator was used. The
function is then computed across them, giving one value per run (per environment for the RL RPCs). The
combination is exact:
min,max,sumandcountcombine directly, andavgandstdare recomputed from the combined raw moments rather than averaged. - No series matches — the selector contributes nothing: a filter excludes the resource, an ordering leaves it in natural order, and a summary returns no value.
Two consequences:
firstandlasthave no meaning across series and are rejected when a selector matches several. Pin every label, or use thelast_avg/last_min/ … family, which reduces across series at each one’s last point.- If a metric was logged both at exactly the requested label shape and at wider shapes (say,
loss{host}andloss{host, worker}), a run holding the exact shape uses it alone — it already summarizes the wider ones — while runs with only wider shapes aggregate across them.
ListSeriesSummaries is the exception: it returns one row per matching series instead of combining them.
aggregate=(…) selectors are unaffected too: their labels must be equalities naming the full kept label set.
Resource filters
Section titled “Resource filters”A filter is a condition, or conditions combined with AND, OR and parentheses. AND binds tighter than OR:
attr(config/optimizer) == "adamw" AND (attr(config/lr) < 0.001 OR attr(sys/tags) CONTAINS "promising")Attribute conditions
Section titled “Attribute conditions”attr(PATH) OPERATOR VALUEattr(PATH) EXISTS| Operator | Meaning |
|---|---|
= == |
equal |
!= |
not equal |
< <= > >= |
ordering comparisons, for numbers, strings and timestamps |
~= |
matches a regular expression (strings) |
IN [v, …] / NOT IN [v, …] |
is / is not one of the values |
CONTAINS v |
a string set contains the value |
CONTAINS ANY [v, …] / CONTAINS ALL [v, …] |
a string set contains any / all of the values |
EXISTS |
the resource has the attribute |
Numbers are compared according to the attribute’s stored type. Integer attributes compare exactly: a range
comparison with a non-integer literal is rounded to the equivalent integer bound, while ==, !=, IN and
NOT IN reject non-integer literals.
attr(sys/creation_time) >= 2026-09-01T00:00:00attr(config/batch_size) IN [128, 256]attr(sys/tags) CONTAINS ALL ["baseline", "v2"]attr(notes) ~= "^ablation-"Series conditions
Section titled “Series conditions”ListRuns, ListRLEnvironments and AggregateRLEnvironmentSeries also filter on series, using
selectors:
SELECTOR EXISTSSELECTOR:FUNCTION OPERATOR NUMBERtrain/loss():last < 0.5eval/accuracy(filter=(split="val")):max >= 0.9weights/layer4(value_kind=histogram) EXISTSThe operators are =, ==, !=, <, <=, >, >=; the value is a number. A selector matching several series of
a run compares their combined value.
What each listing accepts
Section titled “What each listing accepts”| RPC | Attribute conditions | Series conditions | Special fields |
|---|---|---|---|
ListRuns, RunsFilter |
yes | yes | — |
ListProjects, ListExperiments, ListDirectories |
yes | — | — |
ListRLEnvironments |
environment attributes | yes | attr(environment_id), attr(latest_episode), attr(latest_rl_step) — see RL environments |
ListSpans |
span attributes | — | attr(op_name), attr(step), attr(status) and more — see Agentic traces |
Ordering
Section titled “Ordering”An orderBy holds one ordering:
attr(PATH) [ASC|DESC]SELECTOR:FUNCTION [ASC|DESC]attr(sys/creation_time) DESCattr(config/lr, float) ASCtrain/loss():minThe direction defaults to ASC. An attribute ordering may name the type to sort as — float, int, bool,
timestamp or string — after the path. Selector orderings are accepted where series conditions are (ListRuns,
ListRLEnvironments); resources without a value keep their natural order.
Series filters
Section titled “Series filters”ListSeriesDefinitions narrows the definitions it returns with selectors that have no function:
train/loss(filter=(gpu IN ["0", "1"]))train/loss(aggregate=(keys=[host]))Label conditions may use any operator and need not be complete. Include aggregate=(keys=[…]) to return only
aggregated series with that label set.
Series summary queries
Section titled “Series summary queries”ListSeriesSummaries takes selectors with one or more functions and returns one row per matching series:
train/loss(filter=(gpu~="^[0-3]$")):last,min,maxtrain/loss(aggregate=(keys=[host])):last_avg,last_stdeval/embedding(value_kind=scatter)Conditions may be partial and use any operator. Aggregated series are only returned when aggregate=(…) is
given. Scatter selectors take no functions and return the skeleton summary: the last step and its timestamp.
Series queries
Section titled “Series queries”The series point RPCs take selectors with no function, optionally followed by transformations:
train/loss()train/loss(filter=(gpu="0"))train/loss(filter=(host="a")) | group_by(keys=[gpu], reducer=avg)train/loss(aggregate=(keys=[host], reducer=avg))weights/layer4(value_kind=histogram, value_reducer=quantile(0.9))- Every series matching the conditions is returned, each with its full definition.
aggregate=(keys=[…], reducer=R)reads a pre-aggregated series;reducer(min,max,avgorstd) picks which of its aggregates to return as points.| group_by(keys=[…], reducer=R)merges the matching series at query time, grouping by the listed labels and combining points at each step withmin,max,avgorstd. It is flexible but costs more than a pre-aggregated series, especially across many series. OnlyListFloatSeriesaccepts transformations.value_reducer=…turns histogram points into floats, so histogram series can be read on the float endpoints.ListHistogramSeriesandListScatterSeriesaccept no transformations; queries there match only series of their own kind.
Smoothing (moving averages, exponential smoothing) is not offered server-side; apply it to the fetched points.