Semantic Layer

A semantic layer is where business concepts and metrics are declared once — in code, version-controlled — and from which queries are generated for whatever tool asks: a dashboard, a notebook, an API, an export. Cube states the aim as building “a reusable semantic layer that provides the shared context for AI agents, BI dashboards, and embedded analytics.” Product descriptions here follow the dbt and Cube documentation, checked in September 2026.

The problem it solves is duplication of meaning. Without one, the definition of “active user” lives inside every dashboard that reports it — a filter someone wrote, copied, and adjusted. Seventeen dashboards hold seventeen definitions that agree by accident, and a change requires finding all of them.

What it contains

The vocabulary differs by product and the structure does not, and it maps onto dimensional modelling closely enough that anyone who has worked with fact and dimension tables will recognize it.

  • Entities and joins. dbt’s semantic models are “the starting points of your data,” carrying entities — “the join keys of your semantic model” — which is how the engine knows which tables may be combined and on what.
  • Dimensions. “The ways you want to group or slice/dice your metrics,” or in Cube’s phrasing “Categorical data, such as state, gender, product name, or units of time.”
  • Measures. “Quantitative data, such as number of units sold, number of unique visits, profit” — the columns that get aggregated.
  • Metrics. Named, documented combinations of measures with filters and a type, which is what consumers actually request.
  • Presentation metadata. Kept separate from meaning on purpose: dbt’s label “Defines the display value in downstream tools,” so renaming something in a dashboard cannot change the number.

That definitions are code is the operational point. dbt is explicit — “Define metrics in YAML files within your dbt project, and not in a config block on a model” — which makes a metric change a reviewable diff rather than an edit someone made in a dashboard on Friday.

The technical win: joins you did not have to get right

The most valuable automation is not typing less SQL but avoiding a specific class of silent error. MetricFlow, described as “a SQL query generation tool,” picks the join path by using its engine to “determine the best path between tables based on YAML configurations,” explicitly to “avoid the construction of fan-out and chasm joins.”

Those are the errors that duplicate rows when a fact is joined to a table at a finer grain, inflating a sum with no warning and no failure. An analyst can get this right; an analyst under time pressure, joining four tables they did not model, frequently does not. Encoding the grain and the join keys once moves the correctness from a person’s attention to the configuration.

What it does not solve

Three limits are worth knowing before the project is justified on the wrong grounds.

  • Which definition is correct. The layer serves whichever denominator you declared, faithfully. Deciding it is a business judgment needing a named owner, and an unowned metric definition in a semantic layer is just a tidier version of the same argument.
  • Consumers who go around it. A metric served through the layer and also computed in a spreadsheet produces two numbers again. What makes the layer work is coverage — the share of reporting that actually goes through it — not its capability.
  • Dimensions that disagree. If “region” means one thing in sales and another in support, a shared metric grouped by region is incoherent no matter how it is served. That is what conformed dimensions address, and it is upstream of this layer.

What it assumes about your warehouse

One precondition catches teams out. These engines expect reasonably normalized inputs: MetricFlow is “built to do denormalization efficiently,” and feeding it pre-flattened tables risks “reducing the potential granularity that MetricFlow can use to aggregate metrics.”

So a warehouse built from wide denormalized tables — a common and rational choice for dashboard speed — has already traded away some of what the semantic layer needs to slice correctly. That does not rule out adoption; it means the modelling layer beneath may need work first, and the reasons for denormalization have to be reweighed rather than assumed.

Performance is the other practical question, since generating queries at request time means computing aggregates repeatedly. Products answer it with caching and pre-aggregation, and that answer imports a freshness decision: a cached metric is as current as its refresh, and someone has to say how current that must be per metric. A stale number served fast is still a wrong number.

Consumer-facing abstraction helps here too — Cube’s views give “a layer of abstraction that makes it easier to manage changes to the underlying data model” — which is what lets the physical tables be reshaped without breaking every report. Where consumers are other teams, pair that with a data contract stating what may change and with what notice.

Judge adoption by two numbers rather than by how many metrics are defined: what share of reporting is served through the layer, and how often two reports of the same metric disagree. How the layer fits with definitions, change management, and the boundary between central and team metrics is worked through in Whose Revenue Number Is Right?.

References: dbt Documentation, About MetricFlow; dbt Documentation, Creating metrics; Cube Documentation, Data modeling overview.


Discover more from Insightful Data Lab

Subscribe to get the latest posts sent to your email.

Similar Posts

Questions, corrections, or additional insights?

This site uses Akismet to reduce spam. Learn how your comment data is processed.