Shipeasy
Flags & ExperimentsMetrics

Query DSL grammar

The full grammar for the Shipeasy metric query DSL — aggregation functions, event selectors, label filters, and group-by — with worked examples.

Production readyOn this page · 5 min readUpdated · June 14, 2026Works with · Server SDK

Every metric is backed by a small query in the metric query DSL: one aggregation function over one event selector, with optional label filters and a group-by. This page is the complete grammar. It mirrors shipeasy metrics grammar exactly — that command prints the same reference in your terminal.

Grammar

Query         := AggFunc "(" Selector ("," Identifier)? ")" GroupBy?
AggFunc       := count_users | count | sum | avg | min | max | unique |
                 p50 | p75 | p90 | p95 | p99 | p999 |
                 retention_<N>d            (N in 1..90)
Selector      := Identifier ("{" Filter ("," Filter)* ","? "}")?
Filter        := Identifier MatchOp StringLiteral
MatchOp       := "=" | "!=" | "=~" | "!~"
StringLiteral := double-quoted, supports \" and \\
GroupBy       := ("by" | "without") "(" Identifier ("," Identifier)* ","? ")"

Pieces

PieceWhat it is
AggFuncThe per-user reducer. count_users is uniq-by-user; count is per-row count (count_events).
SelectorThe source event, optionally narrowed by { ... } label filters.
Filterlabel OP "value" — values are always quoted strings, even numeric ones (they are coerced).
MatchOp= equals · != not-equals · =~ regex match · !~ regex not-match.
GroupByby (...) keeps only those labels; without (...) drops them. Ignored for experiment analysis.
retention_NdReturns true for users active again N days after the selector event (N in 1–90).

Examples

count_users(checkout_completed)
sum(purchase{country="US"}, amount)
p99(req_dur{route=~"/api/.*"}, ms) by (route, status)
retention_7d(session_start)
avg(req_dur{tier!="free"}, ms) without (region)

Notes

  • One event selector per query — no formulas or cross-event math.
  • count maps to count_events (per-row count); count_users is uniq-by-user.
  • For experiments, by (label) is ignored — the per-user reducer is applied instead.
  • Filter values must be quoted strings, even for numeric labels (they are coerced).
  • Filter labels and value labels must be declared on the source event.

Use it from the CLI

The --query flag on metrics create takes a DSL string directly:

shipeasy metrics create checkout_rate --event checkout_completed \
  --query 'count_users(checkout_completed)'

Run shipeasy metrics grammar any time to print this grammar locally.

On this page