Infra IT Consulting logo Infra ITC
Data Analytics & BI metrics-layerheadless-bidbt

The Metrics Layer Explained: Headless BI and Why It Matters

By Infra IT Consulting · · 9 min read

If you have worked in a data team for more than a few years, you have probably encountered the “metric inconsistency problem.” Finance says revenue was $4.2 million last quarter. Sales says it was $4.6 million. The CEO pulls a number from a legacy dashboard that says $3.9 million. Three tools, three different numbers, all claiming to measure the same thing. Nobody is necessarily wrong — they are just measuring different things and calling them the same name.

The metrics layer, also called headless BI, is the architectural pattern designed to solve this problem permanently. It separates metric definition from metric presentation: business logic lives in one place, and every BI tool, dashboard, and data product queries from that single source of truth. When the definition of “revenue” changes, you change it once and it propagates everywhere, automatically and consistently.

This post explains what the metrics layer is, how it works in a modern AWS stack, and how to implement it using dbt’s Semantic Layer.

The Root Cause of Metric Inconsistency

The inconsistency problem has a structural cause. In most organisations, metric definitions live inside individual BI tool reports. When an analyst builds a Tableau report showing revenue, they write the SQL logic — which filters to include, how to handle refunds, what currency conversion to use — inside the Tableau workbook. When a different analyst builds a QuickSight dashboard, they write similar but subtly different logic. When a data scientist pulls revenue data for a model, they write it again in a notebook.

The same business concept is now defined in three places, maintained by three different people, with three different interpretations of edge cases. When a new requirement appears — “exclude inter-company transactions” — it must be found and updated in every place, and inevitably some definitions are missed.

The metrics layer moves these definitions upstream, into the transformation layer, where they are version-controlled, tested, and computed once.

What the Metrics Layer Actually Does

A metrics layer is a semantic translation layer that sits between your data warehouse (Amazon Redshift, Athena, Snowflake) and your BI tools. It exposes:

  • Metrics — calculated measures with defined business logic (e.g., net_revenue, monthly_active_users, customer_acquisition_cost)
  • Dimensions — the attributes by which metrics can be sliced (e.g., region, product_category, channel)
  • Entities — the business objects that dimensions belong to (e.g., customer, product, order)

BI tools and analytics consumers query the metrics layer using its API rather than writing SQL directly against the warehouse. The metrics layer translates those requests into optimised SQL and returns consistent results.

The term “headless BI” reflects the fact that the semantic layer can serve multiple “heads” — multiple BI tools and interfaces — from the same business logic. QuickSight, Tableau, Power BI, Jupyter notebooks, and Slack bots can all pull from the same metric definitions.

dbt Semantic Layer: The Practical Implementation

dbt’s Semantic Layer (built on MetricFlow) is the most accessible entry point for teams already using dbt for transformations. Metrics are defined in YAML alongside your dbt models:

semantic_models:
  - name: orders
    description: "Order-level grain, one row per order"
    model: ref('fct_orders')
    entities:
      - name: order
        type: primary
        expr: order_id
      - name: customer
        type: foreign
        expr: customer_id
    dimensions:
      - name: order_date
        type: time
        type_params:
          time_granularity: day
      - name: region
        type: categorical
        expr: ship_to_region
      - name: channel
        type: categorical
    measures:
      - name: order_count
        agg: count
        expr: order_id
      - name: gross_revenue_cad
        agg: sum
        expr: amount_cad
      - name: refund_amount_cad
        agg: sum
        expr: refund_amount_cad

metrics:
  - name: net_revenue_cad
    description: "Gross revenue minus refunds, in CAD"
    type: derived
    type_params:
      expr: gross_revenue_cad - refund_amount_cad
    meta:
      owner: finance
      reviewed_by: "Sarah Chen, Finance Director"

  - name: monthly_active_customers
    description: "Distinct customers who placed at least one order in the calendar month"
    type: simple
    type_params:
      measure: order_count
    filter: |
      {{ Metric('order_count', ['customer']) }} >= 1

Once defined, these metrics are queryable through the dbt Semantic Layer API using MetricFlow:

# Query net revenue by region for Q1 2024
mf query \
  --metrics net_revenue_cad \
  --group-by region,metric_time__month \
  --where "metric_time__month between '2024-01-01' and '2024-03-31'"

MetricFlow generates the SQL, executes it against your warehouse (Redshift or Athena), and returns consistent results regardless of which tool made the request.

Integration with AWS BI Tools

Amazon QuickSight does not yet have native dbt Semantic Layer integration, but the pattern for using the metrics layer with QuickSight involves exposing pre-computed metric tables in Redshift or Athena. dbt models can materialise metric aggregations at standard granularities (daily, weekly, monthly) that QuickSight queries directly:

-- models/metrics/mrt_net_revenue_daily.sql
{{ config(materialized='table') }}

SELECT
    order_date,
    region,
    channel,
    SUM(amount_cad) - SUM(refund_amount_cad) AS net_revenue_cad,
    COUNT(DISTINCT order_id) AS order_count,
    COUNT(DISTINCT customer_id) AS unique_customers
FROM {{ ref('fct_orders') }}
GROUP BY 1, 2, 3

This is a simpler pattern than a full semantic layer API but solves the consistency problem for a defined set of metrics. When the definition of net_revenue_cad changes, it changes in one model and flows through to all dashboards that reference it.

For teams with Tableau or Power BI alongside QuickSight, the dbt Semantic Layer with a semantic layer integration (Tableau Connector for MetricFlow, or the JDBC interface) provides direct, consistent metric querying from any tool.

The Governance Argument for the Metrics Layer

Beyond consistency, the metrics layer provides governance benefits that matter particularly for regulated industries and organisations subject to financial reporting requirements.

When metric definitions are declared in version-controlled YAML files with documented owners and reviewers, you have an audit trail for every change to every metric. When did the definition of net_revenue change? What changed? Who approved it? Git blame answers all three questions. This is not possible when metric logic is embedded in proprietary BI tool workbooks.

This connects directly to the broader data governance framework — the metrics layer is the governance mechanism for the semantic layer of your data stack, just as dbt tests are the governance mechanism for the transformation layer. Our post on building a data governance framework covers the full governance stack in more depth.

Common Objections and Responses

“Our team is too small for this overhead.” The YAML definitions in dbt are lightweight — defining 20 core business metrics takes a few hours. The overhead is front-loaded; the benefit (eliminating metric debates forever) is ongoing. Even a three-person data team benefits from a well-defined metrics layer.

“Our BI tool doesn’t support semantic layer APIs.” True for QuickSight today. The pre-computed materialization pattern (dbt metric models as Redshift/Athena tables) provides most of the consistency benefit without requiring API integration.

“We already have a data catalogue.” A data catalogue tracks what data exists; a metrics layer defines what metrics mean. They are complementary, not alternatives.

Implementation Roadmap

A pragmatic path for teams starting from scratch:

  1. Identify the top 10 contested metrics — the ones that cause the most arguments. These are your first candidates for formal definition.
  2. Define them in dbt models — even before moving to the full Semantic Layer, creating well-documented, tested dbt models that compute each metric establishes the single source of truth.
  3. Assign owners — each metric needs a business owner (e.g., Finance owns net_revenue, Marketing owns customer_acquisition_cost) who approves definition changes.
  4. Migrate BI tools — update QuickSight datasets and other BI reports to consume from the centralised metric models rather than computing metrics independently.
  5. Adopt MetricFlow — once the team is comfortable with the pattern, formalise metric definitions in YAML and enable the full Semantic Layer API.

Conclusion

The metrics layer solves one of the most persistent and frustrating problems in analytics: inconsistent metric definitions that erode trust in data. By moving business logic upstream into version-controlled, tested, and documented definitions, it makes consistency the default rather than something each analyst has to achieve individually.

For AWS-native data stacks built on Redshift and Athena with dbt, the path to a metrics layer is well-defined and achievable without significant infrastructure investment. The cultural shift — getting the business to agree on metric definitions and maintain them as formal artefacts — is often the harder part.

Infra IT Consulting helps data teams design and implement metrics layers as part of broader analytics engineering programmes. Contact us to discuss your current metric consistency challenges and what a metrics layer implementation would look like for your organisation.

Related reading:

Related posts