How it works
When you runlightdash deploy (or lightdash compile / lightdash preview), the CLI reads your project’s compiled manifest.json, which contains everything MetricFlow knows about your project: the semantic_models (entities, dimensions, measures) and the metrics defined on top of them.
These metrics can then be used everywhere Lightdash metrics work (charts, dashboards, the API, AI agents).
Requirements
- dbt Core 1.6 or later (manifest schema
v10, the first version to include MetricFlow’s semantic layer). The legacy metrics format used by pre-1.6 dbt (calculation_method/expression/time_grains) is no longer read. - The Lightdash CLI. Translation happens in
lightdash compile,lightdash preview, andlightdash deploy. Server-side jobs (scheduled runs from a connected Git repo) don’t currently translate MetricFlow metrics — for now, deploy from the CLI.
If you define a metric with the same name in both MetricFlow and your model’s
meta.metrics, the meta.metrics (Lightdash YAML) definition will take precedence — so you can always override a translated metric by hand.Use the latest MetricFlow spec
Lightdash supports the latest and legacy spec, though it’s recommended to use the latest spec.- Legacy spec (dbt Core 1.6+): top-level
semantic_models:andmetrics:blocks withtype_params. - Latest spec (dbt Fusion engine, dbt platform, dbt Core 1.12+):
semantic_model:enabled inline on the model, with entities/dimensions on columns and metrics using top-levelagg/exprkeys.
Supported features
simple metrics, and measures flagged create_metric: true, translate into Lightdash:
Also carried over:
- Measure
expr: bare column references become the metric’s SQL, qualified with${TABLE}(for example,expr: amountbecomessql: ${TABLE}.amount). Full SQL expressions are used verbatim. - Labels and descriptions: from the metric, falling back to the measure’s.
- Percentile value: MetricFlow’s legacy spec authors percentile as a
0–1fraction (percentile: 0.95) and the latest spec authors it as0–100(percentile: 95). Both are normalized to Lightdash’s0–100scale automatically. config.meta.hiddenandconfig.meta.group_label: read from the metric first, falling back to the measure. Use them to hide translated helper metrics from the explore sidebar or group them alongside your other Lightdash metrics. Unknown keys underconfig.metaare ignored.
Notes on filters, ratio, and derived metrics
- Filters translate when every
{{ Dimension('entity__dim') }}reference resolves on the metric’s own semantic model. Cross-model dimension references, and other template functions (TimeDimension(),Entity(),Metric()), skip the metric with a warning. - Ratio and derived inputs must all resolve to metrics on the same dbt model. In MetricFlow, inputs can come from any semantic model because each input is aggregated in its own subquery; Lightdash compiles a single query per explore, so cross-model inputs are skipped with a warning. Join the relevant models in a Lightdash explore and author a
numbermetric by hand if you need that today. - Filtered inputs to a ratio or derived metric (for example, a ratio whose numerator has its own
filter:) compile the filter into a hidden helper metric that the visible metric references. - Time-offset inputs to a derived metric (
offset_windoworoffset_to_grain) are skipped with a warning.
What’s not supported yet
These are skipped with a warning on deploy (details under--verbose):
Cumulative and conversion metric translation, cross-model ratio/derived inputs, and server-side translation from a connected Git repo are on the roadmap.
And these parts of the semantic model are currently skipped:
- Entities / joins. MetricFlow joins semantic models implicitly at query time through shared entity keys. Lightdash joins are explicit and authored per-explore (joining tables).
- Dimensions and
agg_time_dimension. Lightdash generates dimensions from your model’s real columns, so all of your columns are already available as dimensions, and metrics can be grouped by any of them — the MetricFlow dimension definitions aren’t needed.
Example
A complete working example (both specs, with a reproducible test) lives in the Lightdash repo underexamples/metricflow-demo. The short version, in the legacy spec:
orders explore: total_revenue (sum on ${TABLE}.amount, grouped under “Order metrics”), unique_customers (count_distinct on ${TABLE}.customer_id, from the create_metric: true measure), completed_revenue (a sum over CASE WHEN ${TABLE}.status = 'completed' THEN ${TABLE}.amount END), and revenue_per_order (a number metric of (${total_revenue} * 1.0) / NULLIF(${order_count}, 0)) — all with no Lightdash-specific YAML.