MetricFlow¶
MetricFlow is dbt's semantic-layer query engine. It lets Dataface ask for metrics and dimensions by name instead of embedding SQL in every board.
Use it when your dbt project already defines shared metrics and you want boards to reuse those definitions.
Why Use MetricFlow?¶
Traditionally, BI tools require you to write SQL queries for every chart, or model data specifically for the tool. This leads to: - Inconsistent metrics: "Revenue" might be calculated differently in two different charts. - Maintenance headaches: Changing a metric definition requires updating SQL in 20 different places. - Rigid querying: Hard to drill down or change time grains on the fly.
MetricFlow solves this by letting you define metrics once in your dbt project. Dataface then asks for "revenue by month," and MetricFlow generates the SQL.
Benefits¶
- Define metrics in dbt and reuse them in Dataface.
- Write shorter board YAML for standard metric queries.
- Change time grains or dimensions without rewriting SQL.
- Keep metric definitions consistent across boards.
How It Works¶
A metrics:/dimensions: query lowers to plain SQL at compile time: Dataface
calls MetricFlow's own compiler (MetricFlowEngine.explain) against your dbt
project's semantic manifest and gets back a finished SELECT statement. That SQL
then runs through the query's dbt_profile source exactly like a hand-written SQL
query — caching, variable substitution in the rest of the board, and the
compile-time SQL guard all apply for free. There is no MetricFlow call at render
or execute time, and no live connection to MetricFlow needed in production.
One consequence of compiling at build time: MetricFlow bakes filter literals
directly into the generated SQL, so a metricflow query's shape (metrics,
dimensions, time grain) can't react to a {{ variable }} at render time the way
a sql: query can — see Filters and Variables below.
Install the optional extra to compile metricflow queries:
1. Define Metrics in dbt¶
First, define metrics in your dbt project.
# dbt_project.yml or schema.yml metrics: - name: total_revenue type: simple type_params: measure: revenue
See dbt's MetricFlow documentation for details on defining metrics.
Then generate the semantic manifest MetricFlow compiles against:
This writes target/semantic_manifest.json, which Dataface reads at compile
time. Re-run dbt parse whenever metrics, dimensions, or entities change —
Dataface does not invoke dbt itself, it only reads the manifest dbt already
produces. A dbt Cloud–hosted project (no local dbt_project.yml/manifest on
disk) is not supported by this source; run dbt parse locally or in CI and
ship the resulting target/ directory alongside the dbt project.
2. Configure the Source¶
A metricflow query's source: is an ordinary type: dbt_profile source — the
same source type plain dbt-model SQL queries use. There is no separate
type: metricflow source config.
# dataface.yml sources: analytics: type: dbt_profile profile: my_dbt_project target: dev
See Sources for profile resolution and connection setup.
3. Reference in Dataface¶
Reference the metric by name. No SELECT, FROM, or GROUP BY needed.
# dashboard.yml queries: revenue: source: analytics metrics: [total_revenue] dimensions: [order_id__region] time_grain: month
Dimension naming¶
Group-by names follow MetricFlow's own naming convention, not the bare column name:
- Non-time dimensions are entity-qualified:
order_id__region, notregion, because the semantic model keysregionoff theorder_identity. time_grain: monthis Dataface's own field — it expands automatically to the reserved group-by namemetric_time__month. Don't add a time dimension todimensions:yourself; usetime_grain:.
Chart x:/color:/etc. fields reference these same MetricFlow-native names
(metric_time__month, order_id__region), since they are the columns the
lowered SQL actually selects.
Flexible Time Grains¶
Want to see the same metric by week instead of month? Just change one line — each grain recompiles to its own SQL.
queries: revenue_weekly: source: analytics metrics: [total_revenue] dimensions: [order_id__region] time_grain: week
Multi-Metric Analysis¶
Combine multiple metrics in a single query to see correlations.
queries: overview: source: analytics metrics: [total_revenue, order_count, average_order_value] time_grain: month
Filters and Variables¶
MetricFlow queries don't support declarative filters: — MetricFlow bakes
filter literals into the SQL it generates, so there's no WHERE clause left in
the output for Dataface to parameterize with a {{ variable }} at render time.
A metricflow query with filters: set fails to compile.
If a board needs the underlying data filtered by a user-facing control, point a
plain sql: query's source at the same dbt_profile source and write the
metric's SQL directly with a runtime-variable WHERE clause.
Best Practices¶
To get the most out of this pairing:
- Name metrics clearly in dbt, such as
total_revenue_usdoractive_users_7d. - Define common dimensions, such as
regionandcustomer_segment, in dbt. - Test metrics in dbt (
mf query --metrics ...) before wiring them into a board. - Re-run
dbt parseafter any semantic-layer change — Dataface compiles against whatever manifest is on disk, stale or not.