What is a Semantic Layer? Definition, Examples & Architecture

A semantic layer maps business logic onto your data warehouse so every query returns consistent metrics. Learn how it works with code examples and architecture patterns.

7 min read

A semantic layer is a business logic abstraction that sits between your data warehouse and the applications that query it. It defines metrics, dimensions, and access rules in one place, so every tool, dashboard, and AI agent gets consistent answers. Without one, the same metric (say "revenue") can return different numbers depending on who writes the SQL.

Think of it as a contract between your data team and everyone who consumes data. The data team defines what metrics mean. The semantic layer enforces those definitions at query time.

Why You Need a Semantic Layer

Consistent Metrics Across Every Surface

Your CEO looks at a dashboard and sees $2.3M revenue. Your VP of Sales queries the same warehouse in a spreadsheet and gets $2.1M. Both are "right" given their SQL. Neither matches the board deck.

A semantic layer defines revenue once. Every consumer that queries it, whether a dashboard, API, React component, or AI agent, gets the same number. The metric definition includes which tables, which filters, which aggregation. One source of truth, every surface.

Multi-Tenancy and Access Control

Row-level security configured in your schema. Tenant A only sees tenant A's data. Marketing only sees marketing metrics. Token exchange maps your existing auth to the semantic layer's security context.

This is critical for B2B products shipping analytics to customers. Each customer queries the same metric definitions but only sees their own data. No separate databases per tenant. No application-level filtering.

Governance groups in the admin UI

AI Agents That Don't Hallucinate

Without a semantic layer, AI agents write SQL against raw tables. They guess at JOINs, invent aggregations, and confidently return wrong numbers. With a semantic layer, agents query defined metrics through MCP tools like explore_schema and query. They can't hallucinate a metric that doesn't exist.

Read more about agentic analytics and why governed metrics are the foundation for trustworthy AI-powered data access.

Caching and Pre-Aggregation

A semantic layer can materialize commonly-queried aggregations ahead of time. Instead of scanning your full orders table on every query, the pre-aggregation cache returns results in milliseconds. The pre-aggregation cache handles this, reducing warehouse load and query latency for both your internal team and your customers.

How a Semantic Layer Works

Cubes: Your Business Entities

A cube maps to a business concept: orders, customers, subscriptions. It defines the SQL source and exposes measures and dimensions.

cubes:
  - name: customers
    sql_table: public.customers

    measures:
      - name: total_count
        type: count
      - name: active_count
        type: count
        filters:
          - sql: "status = 'active'"

    dimensions:
      - name: plan
        sql: plan_name
        type: string
      - name: signed_up_at
        sql: created_at
        type: time

Measures: The Numbers That Matter

Measures are the calculations your business cares about. sum, count, avg, countDistinct, min, max. Each measure has an explicit SQL expression and aggregation type.

measures:
  - name: total_revenue
    sql: amount
    type: sum
  - name: average_order_value
    sql: amount
    type: avg
  - name: unique_customers
    sql: customer_id
    type: countDistinct

No ambiguity. total_revenue always means sum(amount). Not sum(amount) where status != 'refunded' in one dashboard and sum(amount) in another.

Dimensions: How You Slice Them

Dimensions are the axes you group by: time, geography, product category, customer segment. Types include string, number, time, and boolean.

dimensions:
  - name: country
    sql: billing_country
    type: string
  - name: order_month
    sql: created_at
    type: time
    granularity: month
  - name: is_enterprise
    sql: "plan_name IN ('enterprise', 'enterprise_plus')"
    type: boolean

Views: Curated Interfaces

Views expose subsets of cubes for specific use cases. Your marketing team gets a view with the metrics they need. Your AI agent gets a view scoped to customer-facing data. Same underlying definitions, different interfaces.

views:
  - name: marketing_metrics
    cubes:
      - join_path: orders
        includes:
          - total_revenue
          - count
          - status
      - join_path: customers
        includes:
          - total_count
          - plan

When AI agents call explore_schema via MCP, they see views first. Views are curated for analysis and preferable to querying raw cubes directly.

Every Surface, One Schema

The power of a semantic layer is that it decouples metric definitions from how they're consumed. Define once, query from anywhere:

MCP for AI agents: Your customers connect Claude, Cursor, or any MCP-compatible tool to their data via publishable keys. Your internal team connects their AI tools directly. Every agent queries the same governed definitions.

React SDK for embedded analytics: BarChart, LineChart, BigValue, and useBonnardQuery from @bonnard/react. Drop governed charts into your product.

Markdown dashboards: Author dashboards in markdown, deploy with bon deploy. Access-controlled per tenant automatically.

TypeScript SDK: Type-safe queries from @bonnard/sdk. Build internal tools, data pipelines, or custom analytics.

REST API and SQL: For everything else.

One schema definition powers all of these. Change a metric in YAML, bon deploy, and every surface reflects the update.

Semantic Layer vs Metrics Store vs Data Catalog

Semantic Layer Metrics Store Data Catalog
Purpose Define + serve + govern metrics Define metrics Document data assets
Query interface MCP / API / SQL / SDK API Search / browse
Access control Yes (row-level, RBAC) Varies Read-only
Multi-tenancy Built-in Rare No
Caching Yes (pre-aggregation) Varies No
AI-ready Yes (via MCP) Limited No
Embedded analytics Yes (React SDK, dashboards) No No
Examples Bonnard, Cube, dbt Semantic Layer dbt metrics, Transform Atlan, DataHub

A metrics store defines what metrics mean. A data catalog documents where data lives. A semantic layer does both and adds serving, caching, access control, multi-tenancy, and queryable interfaces for AI agents and applications. It's the operational layer that actually delivers data to your customers.

Getting Started

npx @bonnard/cli init --self-hosted
docker compose up -d
bon deploy

Define your cubes and views in YAML. Deploy with bon deploy. Connect AI agents with bon mcp, embed charts with the React SDK, or query via the TypeScript SDK. Import existing dbt models with bon datasource add --from-dbt.

Self-host for free (Apache 2.0) or use Bonnard Cloud for managed infrastructure. If your team needs hands-on help, our forward deployed engineers can work alongside you to ship it.

Read the documentation or view the source on GitHub.

FAQ

What's the difference between a semantic layer and a database view?

A database view is SQL stored in the database. It has no caching, no multi-tenancy, no access control beyond database grants, and no queryable interfaces for AI agents or embedded analytics. A semantic layer adds all of these.

Can I use a semantic layer with dbt?

Yes. Bonnard integrates with dbt models. Run bon datasource add --from-dbt to import your schema and layer metrics on top.

Does Bonnard support Snowflake / BigQuery / Postgres?

Yes, all three plus Databricks, Redshift, DuckDB, ClickHouse, and more. The semantic layer is warehouse-agnostic.

Is a semantic layer the same as a metrics store?

Related but different. A metrics store defines metrics. A semantic layer defines, serves, caches, and governs them with multi-tenancy, access control, and queryable interfaces for AI agents, SDKs, and embedded analytics.

Do I need a semantic layer if I already have dbt?

dbt transforms data. A semantic layer serves it. dbt builds the tables; the semantic layer defines what the numbers in those tables mean, who can access them, and how they're delivered to your customers. They're complementary.

One schema. Every surface.

Define your metrics once in YAML. Query them from AI agents, React components, dashboards, and APIs.