Skip to content
Raw Markdown

Metrics

One file per metric at metrics/name.yml, named after the metric's name field. A metric is one governed expression, used exactly, never re-derived.

As with tables, the field is authoritative and the filename must match it.

Fields

FieldTypeNotes
namestring, requiredStable snake_case identifier, and the filename
display_namestring, requiredHuman name. Enforced by import validation: the check and the import both reject a metric without it
expressionstring, requiredThe SQL aggregate. Enforced like display_name. Identifiers quoted, stored case
filtersstringWHERE-clause fragment the expression assumes
table_schemastringSchema of the base table. Note the field name: table_schema, not schema_name
table_namestringBase table the expression runs over
domain_pathstringDomain the metric is listed under. Same rules as on tables
descriptionstringWhat the metric means in business terms
notesstringUsage guidance for the agent: edge cases, what not to substitute
precomputed_instringWhere the metric already exists materialized, if anywhere
synonymslist of stringsBusiness vocabulary that should route to this metric
unitstringEUR, %, sellers
description: Share of delivered orders that arrived on or before the estimated delivery
  date, as a percentage. Around 92%.
display_name: On-time delivery rate
domain_path: marketplace
expression: 100 * AVG(CASE WHEN "IS_ON_TIME" THEN 1 ELSE 0 END)
filters: '"IS_DELIVERED" = TRUE AND "ORDER_DELIVERED_CUSTOMER_DATE" IS NOT NULL'
name: on_time_delivery_rate
synonyms:
- on time rate
- punctual delivery rate
table_name: FCT_ORDERS
table_schema: STALLORA
unit: '%'

expression is the rule, not necessarily executable SQL. The agent composes the query from it, so it can carry what a bare aggregate cannot: a join requirement, a dedup key, a boundary rule. Evals gate the result against expected SQL, so prose in the expression stays checkable.

What earns its own metric

A metric exists so a phrase resolves to one definition instead of being re-derived per question. Two signals that a phrase needs one: people disagree about how to compute it, or the computation carries a filter that is easy to forget. “On-time delivery rate” qualifies on both counts, because the delivered-only filter is exactly what a hand-written query drops.

synonyms is what makes that work in practice: it is the list of things people actually say. notes is where you tell the agent what not to substitute when the metric does not apply.

The filters field is part of the definition, not a convenience. It is applied whenever the metric is used, so a metric plus its filters is the whole rule. Splitting the rule between expression and a domain README is how two answers end up disagreeing.

File naming and sanitization

Table and metric filenames derive from the object’s name, with every character outside ASCII letters, digits, _, -, and . replaced by _. A metric named revenue/total becomes metrics/revenue_total.yml. The name field keeps the original value; only the filename is sanitized.

Precomputed metrics

precomputed_in names a table where the metric already exists materialized, which lets the agent read it instead of recomputing the aggregate. Removing that table clears the pointer: a stale one would send generated SQL at a table that no longer exists.