Skip to content

Semantic layer#

A semantic layer defines business metrics, such as revenue or order count, together with the dimensions they can be grouped by and the joins between tables, once and in business terms, so that every tool that asks for a metric gets the same answer.

Before reading

Dimensional modelling

Why it matters#

Without one, every dashboard, notebook and application writes its own SQL for revenue. One excludes cancelled orders, another forgets refunds, a third uses order date instead of payment date. The numbers disagree, and meetings are spent reconciling them. A semantic layer moves the definition out of each tool into one place.

How it works#

A semantic layer holds three kinds of definition. Metrics: what to aggregate and how, such as revenue = sum of amount for orders that are not cancelled. Dimensions: what metrics can be grouped and filtered by, such as order date, product category or customer region. Relationships: how fact and dimension tables join, so that asking for revenue by category produces the right join without the user writing it. A consumer asks for "revenue by category for last month"; the layer generates the SQL, runs it on the engine and returns the result.

The term is used for three different setups, and the difference matters.

Inside a BI tool. Power BI semantic models, Tableau data sources and Looker's LookML define metrics within the BI product. Dashboards in that tool share the definitions. Other tools can reach them only through the product's own interfaces, such as Power BI's XMLA endpoint with DAX queries, which tie consumers to that vendor.

Standalone, often called headless or universal. Products such as Cube, AtScale and the dbt Semantic Layer (built on MetricFlow) run as a separate service between the engine and every consumer. They expose the definitions through their own SQL, REST or GraphQL interfaces, so dashboards, applications and AI agents can all ask for the same metric.

Inside the warehouse or engine. Snowflake semantic views and Databricks metric views store definitions next to the tables, queried with SQL in that platform. Any tool that connects to the platform can use them.

flowchart TB
  subgraph BI[In a BI tool]
    direction LR
    B1[Definitions] --> B2[That tool's<br/>dashboards]
  end
  subgraph SA[Standalone]
    direction LR
    S1[Definitions,<br/>SQL, REST, GraphQL] --> S2[Dashboards,<br/>apps, agents]
  end
  subgraph WH[In the warehouse]
    direction LR
    W1[Definitions<br/>next to tables] --> W2[Any SQL client<br/>of that platform]
  end
  BI ~~~ SA ~~~ WH

An open standard for exchanging definitions is emerging. The Open Semantic Interchange initiative, announced in September 2025 by Snowflake, dbt Labs and others and renamed Apache Ossie when it entered the Apache Incubator in July 2026, defines a YAML format so that tools can share metric definitions instead of each holding their own.

A semantic layer usually adds caching. Results of common queries, or pre-aggregated tables, are kept so dashboards respond quickly and the engine is not asked the same question repeatedly. Caches must be refreshed when the underlying tables change, or they serve stale numbers.

Access rules can be applied in the layer: which metrics a user may see, and row filters on dimensions, such as a manager seeing only their region. If the same data is also reachable directly through the engine, the same rules must apply there, as described in Row-level security and masking.

A semantic layer serves aggregates: metrics grouped by dimensions. Applications that need individual records, such as one customer's orders, need a data API instead, described in Data APIs and the backend-for-frontend pattern.

Key terms#

  • Metric A named calculation with business meaning, such as revenue.
  • Dimension An attribute that metrics are grouped or filtered by.
  • Relationship How tables join, declared once in the layer.
  • Headless semantic layer A standalone service exposing metrics through APIs to any tool.
  • Pre-aggregation A stored summary table used to answer common queries quickly.
  • Metrics API An interface that returns metric values by dimension.

Example#

Revenue and order count, defined once (simplified YAML, not tied to one tool):

semantic_model: order_lines
table: shop.fct_order_line
joins:
  - table: shop.dim_product
    on: fct_order_line.product_key = dim_product.product_key
dimensions:
  - name: order_date
    type: time
  - name: category
    expr: dim_product.category
metrics:
  - name: revenue
    description: Sum of order line amounts, tax included, cancelled orders excluded.
    agg: sum
    expr: amount
    filter: order_status <> 'cancelled'
  - name: order_count
    agg: count_distinct
    expr: order_id

The finance dashboard shows revenue by month; the merchandising app shows revenue by category for the last seven days through the layer's REST API; the sales assistant, an AI agent, asks the layer for revenue last week. All three get numbers built from the same definition.

Pitfalls#

  • The same metric defined in two places. A revenue measure in the BI tool and another in the standalone layer drift apart; choose one owner per metric.
  • Treating a BI tool's model as the company's semantic layer. Other consumers cannot use it without that vendor.
  • Stale caches. Refresh or invalidate them when the tables they summarise change.
  • Access rules only in the layer. Users with direct engine access bypass them.
  • Using the semantic layer to serve records to applications. It is built for aggregates.

Learn more#