The baseline
Count, sum, group-by-month. Every layer can basically do the basics. Otherwise they wouldn't be in the conversation.
| Semantic Rails | 7 native |
| MetricFlow | 7 native |
| Cube | 6 native · 1 workaround (q05) |
| Malloy | 7 native |
| Snowflake SV | 7 native |
Every cell below is a real run against a shared DuckDB (and Snowflake trial) dataset. The same Jaffle-shop questions run through Semantic Rails, MetricFlow, Cube, Malloy, and Snowflake Semantic Views. Where a layer can't express the intent as a governed primitive, the question still gets answered - but the cost shows up as a helper view, a precomputed rollup, or query-level SQL.
Coming from MetricFlow? Translate your existing project with one command.
The translator reads your semantic_models/ directory or
semantic_manifest.json,
and emits a complete package directory you can load, edit, and commit.
Shapes that don't translate cleanly surface as warnings on the report.
Imported metrics keep their semantics intact, ready to upgrade to the
more expressive primitives that Semantic Rails enables.
uv run semantic-rails import \
--from metricflow \
--source path/to/target/semantic_manifest.json \
--output configs/semantic_rails \
--package-id my_package
These layers weren't built to express the q08–q16 questions as governed primitives — the counts below show what each workaround costs.
Count, sum, group-by-month. Every layer can basically do the basics. Otherwise they wouldn't be in the conversation.
| Semantic Rails | 7 native |
| MetricFlow | 7 native |
| Cube | 6 native · 1 workaround (q05) |
| Malloy | 7 native |
| Snowflake SV | 7 native |
Metric predicates, temporal validity, same-store conversion, contextual entity-graph inheritance. Without these as primitives, your agent leaves the governed API and writes raw SQL against the warehouse.
| Semantic Rails | 9 native |
| MetricFlow | 2 native · 7 precomputed |
| Cube | 3 workaround · 6 precomputed |
| Malloy | 9 workaround |
| Snowflake SV | 9 workaround |
Sixteen questions that any analyst should be able to answer.
All 16 normalized outputs match across the five layers
(shared/comparison_data.json, run 2026-05-07); configuration parity
rules are published in the methodology.
| Question | Semantic Rails | MetricFlow | Cube | Malloy | Snowflake SV |
|---|
Support per each layer's official docs, ranked by analytics-warehouse prevalence. Semantic Rails packages run unchanged on every supported engine: a cross-dialect conformance suite executes the same semantic queries against identical seeded data on each connector and asserts row-for-row parity with the DuckDB reference.
| Warehouse | Semantic Rails | dbt Semantic Layer | Cube | Malloy | Snowflake SV |
|---|---|---|---|---|---|
| Snowflake | yes | yes | yes | yes | yes |
| BigQuery | yes | yes | yes | yes | no |
| Databricks | yes | yes | yes | yes | no |
| Amazon Redshift | no | yes | yes | no | no |
| SQL Server / Fabric | no | no | yes | partial | no |
| PostgreSQL | yes | yes | yes | yes | no |
| MySQL | no | no | yes | yes | no |
| ClickHouse | yes | no | yes | no | no |
| Amazon Athena | yes | no | yes | no | no |
| Trino / Presto | no | yes | yes | yes | no |
| DuckDB | yes | no | yes | yes | no |
Every configuration, query, and normalized output is in the repo. If you find a better configuration for any layer, submit a PR and we will gladly update the benchmark.