Semantic Layers in Apache Superset: SIP-182 and Apache Ossie
Apache Superset 7.0 is refactoring its architecture to treat semantic layers as first-class citizens rather than simulated databases.
Deep dive
- SIP-182: A design proposal to standardize how Superset interacts with external data modeling layers.
- SemanticLayer Interface: Defines a minimal set of methods for fetching metrics, dimensions, and table data, bypassing SQL generation.
- Apache Ossie: A new, vendor-neutral JSON/YAML specification for semantic definitions currently in the Apache Incubator.
- .supx: A new file extension for Superset extensions, bundling frontend and backend logic into a single package.
- Compatibility: Future plans include migrating the built-in dataset editor to this same extension interface to reduce core code complexity.
Decoder
- Semantic Layer: A business logic layer that defines metrics and dimensions consistently, ensuring all BI tools report the same numbers for terms like 'ARR' or 'Active Users'.
- Arrow: An in-memory columnar data format designed for high-performance analytics.
- SIP: Superset Improvement Proposal, the formal process for suggesting architectural changes to the Apache Superset project.
Original article
Semantic Layers in Apache Superset: SIP-182 and Apache Ossie
Ask four different systems "how many monthly active users did we have in June?" and you'll get four different answers. The CRM says 41,208 (it's counting trial signups). The warehouse says 39,655 (it excludes internal accounts). The BI tool says 42,730 (someone's ad-hoc metric, defined once, forgotten why). And if you ask an AI agent? It picks one of the above pretty much at random, with total confidence, and no way for you to know which.
Surely, you've run into this. Analysts have been arguing about things like what "customer" means since long before anyone had an LLM to make the argument worse. What's new is the cost of getting it wrong. An analyst who picks the wrong number gets corrected in a meeting. An agent that picks the wrong number gets shipped into a dashboard, a Slack summary, or a decision, with nobody in the loop to say "wait, that's not how we count trials."
A semantic layer is the fix: an agreement about what a number means, defined once and served everywhere. Metrics, dimensions, and the joins between them, in one place instead of four.
Here's the thing most people don't know about Apache Superset™: it's had one of these since the beginning. We just called it the dataset editor. And until a few months ago, it was the only semantic layer you were allowed to have.
Last month, I hosted a webinar with Beto Dealmeida (Apache Superset PMC member, and the author of SIP-182, the proposal that changes this) to walk through what's shipping, what it opens up, and a new standard called Apache Ossie that's about to make the whole thing a lot less bespoke. This post is the write-up I promised at the end of that session, with the architecture, the roadmap, and the parts of the Q&A worth keeping.
Superset already had a (thin) semantic layer
Superset's dataset editor didn't happen by accident. It happened because Superset started as a front end for Apache Druid, back when Druid had no SQL interface at all. You talked to it in JSON. Writing a raw query meant hand-building a JSON request, and Druid was bad at grouping on high-cardinality columns if you didn't warn it first.
So Superset needed somewhere to consolidate that knowledge: which columns are metrics, which are filterable, which are safe to group by. That somewhere became the dataset. Users stopped querying tables directly and started querying a curated, guarded version of the table instead. When SQL support arrived later, the underlying representation shifted to SQL, but the job of the dataset never changed: be the one place that knows what a metric means.
That job description, it turns out, is a semantic layer. Superset had a thin one, opinionated toward "compile-time" safety, running the entire time.
Metrics & Dimensions: a quick, necessary detour
Before going further, it's worth being precise about two words that get used loosely across the industry. In Superset's world:
A metric is an aggregation, almost always over a fact table. COUNT(*), COUNT(DISTINCT user_id), SUM(price), for example. Sometimes something gnarlier, because if you need a filter on a metric, you can't just add a WHERE; you jam a CASE WHEN into the aggregation expression instead.
A dimension is a related column, often reached via a join, that you'd break a metric down by. Usually low-cardinality on purpose: device type, country, age bucket. Use user_id as a dimension and you're not adding insight, you're just exploding your row count.
And underneath both of those sits a category of knowledge that lives nowhere near your database: the tribal kind. "You need to exclude user 42 from that count, we ran a test on that account." Nobody encodes that in a table schema. A semantic layer is where that knowledge finally gets to live somewhere durable, instead of in the head of whichever analyst has been around the longest.
By the way: there are two schools of thought on when a semantic layer resolves a dimension. Superset does it at compile time, when you build the dataset: rigid, and it requires planning ahead, but fast, since the join is already written and the database isn't guessing at query time. Other semantic layers resolve it at run time, joining on demand when you ask for a breakdown you didn't plan for: flexible, but a bet, since a many-to-many relationship joined at the wrong moment can quietly multiply your row counts. Neither is strictly better. It's a trade between planning cost and query-time risk.
The part that doesn't scale: pretending everything is a database
Superset's compile-time approach works great, with an asterisk: it works great for databases. Explore inspects the columns and metrics on a dataset, emits SQL, sends that SQL to a database, and gets a table back. Clean.
The trouble starts once you want to point Superset at something that isn't a database. Over the years, Beto has personally built or overseen integrations with Airbnb's in-house Minerva layer, dbt's semantic layer and later MetricFlow, a Snowflake integration, and Data Junction, another open-source semantic layer. The pattern every single time: pretend the semantic layer is a database. Invent a pseudo-database. Give it pseudo-tables. Emit SQL at it like always, then parse that SQL back into whatever the real semantic layer actually speaks, whether that's a REST call, a GraphQL request, or something else entirely.
If that sounds brittle, it is. Superset's own SQL-generation function runs to roughly 700 lines, threading the needle between dozens of database dialects that disagree on whether you can alias a column in a GROUP BY, or how to express a time grain. Now take that already-complex SQL, and parse it a second time on the way out the door, into a second query language on the other side. You end up with a semantic layer bolted onto a semantic layer, and nobody can tell you what happens if a user defines a metric on the dataset that sits on top of the pseudo-database that sits on top of the real semantic layer. Usually, it just doesn't translate.
Making "semantic layer" a first-class connection
SIP-182 is Beto's fix, and the core move is refusing to keep pretending. Semantic layers stop being disguised as databases and become siblings of databases instead: a data connection in their own right, sitting next to your database connections rather than underneath a costume.
To make that possible, Beto first had to clean up what a chart actually asks for. Explore (a.k.a. Chart Builder) has always sent a payload called the QueryObject to request a chart. Asking every future semantic layer author to learn all of that felt unreasonable. So Beto wrote a mapper (map_query_object()) that translates a QueryObject into a SemanticQuery: metrics, dimensions, filters, order, limit, offset, group limit. Nothing else.
A SemanticLayer implementation is a short, deliberately small interface: configuration and schema methods, accessors to list or fetch semantic views, and on the view itself, get_dimensions(), get_metrics(), get_compatible_metrics(), get_compatible_dimensions(), and the data-retrieval trio get_values(), get_table(), get_row_count(). The payload that comes back is an Arrow table, not a bag of JSON, and not SQL parsed out of a pseudo-database.
By the way: semantic layer connections aren't hand-built forms. Each one defines a schema, Superset turns it into JSON Schema, and JSON Schema builds the config UI. Add a field to the schema and it shows up in the form, no frontend code required. The schema can also react to itself. Connect to Snowflake, and only once your credentials check out does "database" turn from a text box into a dropdown of your actual databases, fetched live instead of typed from memory.
Semantic layers as Superset Extensions
The first implementation of this became one once Superset's extension system matured enough to make that the obvious choice: separate repo, separate release cycle, automatic discovery, and a config form you don't strictly need to hand-write. A semantic layer integration no longer has to earn its way into Superset core to exist. Anyone can build one, package it, and ship it on their own schedule.
Building one is superset-extensions bundle, which validates, installs dependencies, rebuilds the frontend, syncs backend files, and packs the whole thing into a .supx file. Beto's pandas-semantic-layer is the reference implementation, small enough to read start to finish in one sitting.
Five consequences/opportunities worth sitting with
Any semantic layer becomes a contribution, not a request
Snowflake Semantic Views and dbt MetricFlow are shipping on Preset now, with the Pandas implementation already available as a reference. Cube, Malloy, Cantrip, AtScale, and Minerva-style in-house layers are the kind of thing that's now a well-scoped extension for someone to write, rather than a line item on Superset's core backlog. The interface is the point.
Superset's own dataset editor gets to become an extension too
The plan is to migrate it onto the same Explorable/SemanticLayer interface every other extension uses, which hardens that interface, shrinks Superset's core, and reduces the ongoing maintenance burden.
Migration between semantic layers becomes a real workflow, not a rewrite
If Superset can read a semantic layer and write one, it can move you between them: connect the source, serialize what it finds into a neutral model instead of a bespoke script, let a human reconcile whatever didn't map cleanly, then write the target. Expression of Superset's own datasets in a neutral way makes modeling portable.
You can run more than one at a time, on purpose
Nothing forces you down to a single semantic layer. Multiple regions with disconnected data stacks is a legitimate case. The one thing to actually watch for: don't let two active semantic layers both claim ownership of "ARR."
Context compounds in layers
An agent pointed straight at a warehouse is guessing at what a column means. An agent pointed at a semantic layer is reading a definition someone actually wrote down. Ossie's spec includes an ai_context block, freeform instructions and worked examples written once and read by any compliant tool instead of configured separately per vendor copilot.
The standard underneath all of it: Apache Ossie™
None of the above holds together without agreement on what a semantic layer's own definition file actually looks like, and that's a separate, new piece of news: Open Semantic Interchange was accepted into the Apache Incubator in June 2026, and renamed Apache Ossie in the process.
Ossie is a declarative spec, JSON and YAML, that any tool can read or write: semantic models made of datasets, fields, relationships, and metrics, plus an ontology layer for business concepts and rules that don't reduce cleanly to a column. It's vendor-neutral by construction, not by promise.
Why a standard changes Superset's math
Once Cube, MetricFlow, Snowflake, and Polaris can all export the same Ossie YAML, Superset only has to write one thing: a provider that parses that YAML and maps it onto Explorable. That's a file to parse, not a wire protocol to emulate. It puts a working .supx for a new semantic layer within reach of a weekend, instead of a quarter.
Where things stand today
If you're wondering when you can actually touch any of this: the SEMANTIC_LAYERS feature flag exists on Superset master right now. It's targeted at Superset 7.0. On Preset, we tend to run ahead of the open-source release cycle, so this is closer to generally available there already, with Snowflake Semantic Views and dbt MetricFlow rolling out over the next few months.
How to get involved in Semantic Layer Extensions
If you're a Superset contributor, Explorable is in master and stable enough to build against today. If you already run a semantic layer we haven't touched yet, an Ossie .supx is parse-and-map, not protocol emulation, and whoever ships the first one for a given layer sets the pattern everyone after them copies.
Further reading
- The Semantic Layer Is Back. Here's What We're Doing About It.
- A Case Study in Dataset-Centric Visualization Using dbt and Snowflake
- Preset MCP: Analytics Your AI Agent Can Build, Not Just Read
- Building Better BI Chatbots: Why Context and Triggers Matter
- Preset Joins the Open Semantic Interchange (OSI) Initiative
Fresh dev news, AI-digested daily. Never miss a trend at devoured.fyi