Why Dosi¶
This page explains, without assuming any background, what problem Dosi solves and why it works the way it does. If you just want to run something, start with Install and the first-metric-query tutorial — then come back here for the why.
The problem: everyone redefines "revenue"¶
In most data teams, the definition of a metric lives in dozens of places at once — a BI dashboard, a hand-written SQL query, a spreadsheet, a notebook. Each copy is slightly different: one filters out cancelled orders, another forgets to, a third joins a table that quietly doubles the total. The result is familiar to everyone: two "correct" numbers that don't match, and a meeting to figure out which one to trust.
A semantic model fixes this by defining each metric once — what revenue
means, which table it comes from, how tables relate — as a single source of
truth. Every query then derives from that one definition instead of
re-implementing it.
What OSI is¶
OSI (Open Semantic Interchange) is an open standard for writing that semantic model down: a plain YAML file describing your datasets (tables), the relationships between them, and your metrics as ordinary SQL expressions. It is vendor-neutral — no proprietary format, no lock-in — so the same model can be understood by any tool that speaks OSI.
OSI describes what your metrics are. It deliberately does not say how to turn them into correct SQL for a specific warehouse. That is the gap Dosi fills.
What Dosi does¶
Dosi is a small, fast (Rust) engine that reads a pure OSI model and turns a metric request into correct, warehouse-specific SQL — then, optionally, runs it:
flowchart LR
A["Your OSI model<br/><small>metrics defined once</small>"] --> B["Dosi"]
B --> C["Correct SQL<br/><small>for your warehouse</small>"]
C --> D["Results"]
You ask for a metric, a few dimensions to group by, and a warehouse dialect. Dosi works out the joins, the aggregation, and the exact SQL idioms that dialect needs — the same model produces correct SQL for DuckDB, Postgres, MySQL, ClickHouse, Snowflake, BigQuery, StarRocks, Trino, and more. Switching warehouses changes one flag, not your metric definitions.
You can use it three ways — a command-line tool, a REST/Arrow server, or Python bindings — all sharing the same engine and the same answers.
What makes the numbers trustworthy¶
The reason to use an engine instead of writing the SQL yourself is that it protects you from the mistakes that produce those mismatched numbers:
- It never silently double-counts. When a metric would require joining tables at different levels of detail (the classic "fan-out" that doubles your revenue), Dosi either computes it correctly at each grain, or stops and tells you — it will not hand back a quietly inflated total.
- Time ranges are unambiguous. A range like Jan 2024 means
[2024-01-01, 2025-01-01)— start included, end excluded — so days never get double-counted at month boundaries. - Errors tell you how to fix them. A wrong metric name doesn't get a stack
trace; it gets a message naming the closest valid options. In
--format json, every error carries a stable code and suggested fix, so automated tools (and AI agents) can self-correct.
These guarantees are written down precisely — as a normative contract — in the semantics reference. You don't need to read it to use Dosi, but it's there when you want to know exactly what the engine promises.
Who it's for¶
- Analytics & data engineers who want one metric definition that stays correct across every warehouse and every consumer.
- Teams migrating or multi-homing warehouses who don't want to rewrite metric SQL per engine.
- Builders of data apps and AI agents who need a metric API with structured, machine-readable errors instead of free-form SQL.
Next steps¶
-
Get the
dosibinary and verify it in a couple of minutes. -
A 10-minute, hands-on walk from a model to real results.
-
The precise rules behind "never silently double-counts."