Postgres or MySQL as a starter warehouse
Use Postgres or MySQL as a starter warehouse for a thin semantic layer, then move to Snowflake or BigQuery without rewriting consumers.
The datahashi team3 min read

You do not need Snowflake or BigQuery on day one to prove a semantic layer. Postgres or MySQL is enough to connect a warehouse, author metrics in YAML, publish an immutable model, and query the same numbers from the console, REST, and MCP. When you later move to a cloud warehouse, consumers keep the same request shape.
This is a practical starter path for data engineers who want agent-ready metrics without waiting on a warehouse migration.
Why a starter warehouse works
datahashi is a thin semantic layer. Transforms stay in the warehouse; the model maps tables to entities, dimensions, measures, and metrics. Compilation targets the warehouse you connected. Nine engines are supported, including Snowflake, BigQuery, Postgres, and MySQL. The Semantic Query object does not change when the backend does.
That portability is the point of starting small:
- Prove grain and join paths on a familiar database.
- Publish three metrics you would trust an agent to say aloud.
- Hand a governed credential to one dashboard and one MCP agent.
- Confirm both return the same number before you scale compute.
You are validating the contract, not the warehouse brand.
Connect with a read-only role
Create a read-only database user that can SELECT the schemas you intend to model. Point a Query Runner at that role, then register the runner as a source in datahashi. Nothing is copied out of your warehouse; the engine never opens it, and the runner does not widen the access you granted.
Keep production write credentials out of this path. Row-level rules, if you use them later, apply on every read - but for a starter, a dedicated read-only role and a non-production copy of core tables is enough.
Author a minimal model
Start with one entity, one measure, one metric, and one time dimension. Example shape (illustrative):
entities:
- name: Order
table: public.orders
primary_key: id
measures:
- name: revenue
expr: amount
agg: sum
- name: order_count
expr: id
agg: count
dimensions:
- name: ordered_at
expr: ordered_at
type: time
metrics:
- name: revenue
expr: Order.revenue
- name: avg_order_value
expr: revenue / order_count
Validate in the app before you publish. A wrong grain or missing join is cheaper to catch here than in a wrong agent answer.
Keep transforms in SQL views or tables you already maintain. Currency conversion, status mapping, and refund netting belong in Postgres/MySQL objects the model references - not as sprawling logic inside the semantic layer.
Publish, then query the same way you will in production
Publishing freezes the model and its access rules as one version. From that point:
- Query in the console playground with metrics × dimensions × filters.
- Call the same shape over REST from an app or script.
- Connect an agent over MCP. The six tools are
list_catalog,describe_metric,run_semantic_query,drill_down,refine_semantic_query, andlist_dimension_values. None accept or return SQL.
Grant agents a role with named metrics and the dimensions they need. Grant raw measures only to analysts who need them.
Every call is metered, so even on a starter warehouse you can see who is querying what.
Moving to Snowflake or BigQuery later
When volume or concurrency outgrows Postgres/MySQL:
- Stand up the cloud warehouse and migrate (or replicate) the tables and transforms the model depends on.
- Point a Query Runner at the new warehouse with a read-only role, then register that runner as the source.
- Re-publish the model against the new physical tables if names or schemas shifted.
- Leave consumer requests alone. Dashboards, apps, and MCP agents still send metrics, dimensions, and filters - not warehouse-specific SQL.
Do not invent a second metric catalog for the new warehouse. The certified definitions are the migration surface.
What success looks like
A starter warehouse is done when dashboard X and agent Y return the same revenue for the same filters, and when you can explain every number from the published YAML - not from tribal SQL. Scale the warehouse when the contract is already trusted.
Product notes
An occasional email when we ship something or write something worth reading.