Celiq
v0.12Open app โ†—
Docs/Analytics/Best Practices

Best Practices

Design patterns and conventions for building maintainable, performant semantic models in Celiq.

LuminaryWeaverUpdated June 2026 ยท 10 min read
โœฆ
In this section
Part of Celiq's semantic layer platform. Connect your warehouse, model your data once, query it everywhere.
๐Ÿ’ก
Tip

This page collects the patterns that consistently produce clean, fast, maintainable Celiq deployments. See also Anti-patterns for the corresponding list of things to avoid.

Semantic model design

One node per grain

Map each node to one physical table at one level of granularity. Avoid mixing row-level and aggregate-level data in the same node.

Do:
cml
node: orders          # one row per order
  dataset: orders

node: order_items     # one row per order line
  dataset: order_items
Don't: Put both order-level and item-level measures in the same node โ€” you'll get fan-out errors and inflated counts.

Use descriptive, stable dataset names

Dataset names propagate into CML node definitions. Once a dataset is referenced in production nodes, renaming it requires updating every node. Choose names that will survive schema evolution.

  • Use the logical concept, not the table name: customers not dim_customers
  • Use singular nouns: order not orders (though either works โ€” be consistent)
  • Avoid warehouse-specific prefixes: user not sf_user or prod_user

Keep domains focused

Each domain should answer one business question area. Broad domains with 20+ joins become hard to maintain and generate confusing Discover experiences.

A useful test: if someone opens Discover and picks your domain, can they intuitively find the metric they're looking for in under 30 seconds? If not, split the domain.

Name measures for the business, not the SQL

Measure names are what end users see in Discover and what Orion reads when answering questions. Name them for the business reader:

SQL instinctBusiness name
sum_revenuetotal_revenue
cnt_ordersorder_count
avg_order_valueaverage_order_value
daudaily_active_users

Define AI context for Orion

Every node and reveal should have an ai_description that explains what the data represents in plain English. This is the single most impactful thing you can do to improve Orion's answer quality:

cml
node: orders
  ai_description: "Contains one row per customer order. Revenue is the net amount after returns and discounts but before shipping."

Good descriptions include:

  • What each row represents
  • How key metrics are calculated (especially non-obvious ones)
  • Date fields and their timezone assumptions
  • Any known data quirks (e.g. "returns are excluded from this table")

Deployment & environment management

Always have at least two deployments

A Production deployment and a Development deployment are the minimum. This lets you:

  • Test new nodes against dev data before promoting to prod
  • Validate schema changes in dev before they break prod queries
  • Let Weavers experiment without risk

Validate mappings before switching the default deployment

Before promoting a new deployment to default, run Validate All Mappings on every dataset. A deployment with any mapping below 100% compatibility should not become the default.

Keep compatibility at 100% for all production mappings

A compatibility score below 100% means some queries will error. Treat any production mapping below 100% as an incident, not a warning. Common causes:

  • A column was renamed or dropped in the warehouse
  • A migration ran in the warehouse but the dataset definition wasn't updated
  • The wrong physical table was specified

Use database/schema overrides for environment parity

When a single Snowflake or Postgres connection serves multiple environments, use database_override and schema_override on dataset mappings instead of creating separate connections. This reduces credential management overhead.

Query performance

Partition and cluster the tables your nodes use most

Celiq generates standard SQL โ€” it benefits from the same query optimisations as any SQL tool. For time-series nodes, ensure the primary time column is:

  • Partitioned in BigQuery
  • Clustered in Snowflake
  • Indexed in Postgres (CREATE INDEX ON orders (created_at))

Avoid high-cardinality dimensions in default fields

When a node has many dimensions, be selective about which are enabled by default in a Reveal. High-cardinality string dimensions (user IDs, email addresses) force Celiq to fetch all values for filter suggestions โ€” expensive on large tables.

Mark high-cardinality dimensions as hidden: true in the reveal's suggested_attributes list unless specifically needed.

Use rolling window table calculations, not SQL window functions for small datasets

For datasets under ~1M rows with date ordering, use Celiq's client-side table calculations (running total, rolling average) instead of relying on SQL window functions. Client-side calculations let the warehouse return results faster and Celiq applies the window logic after.

For large datasets where you need the window function pushed down to the warehouse, use rolling_average or rolling_sum intent โ€” these use SQL OVER() clauses.

Security model

Always set Data Keys at the node level, not the domain level

Data Keys (row-level security) should be on the node, not applied ad-hoc in domain joins. This ensures RLS applies regardless of which domain the node is queried through.

Test security rules as a restricted user

After configuring Data Keys and Data Gates, log in as a Tracer-role user (or use sudo mode with a test account) and verify the expected rows and columns are hidden. Security rules that look correct in CML can have subtle bugs that only appear when executing queries.

Use workspaces to separate teams with completely different data access

If two business units should never see each other's data (not just filtered differently), put them in separate workspaces rather than trying to express the separation through Data Keys. Data Keys are for row-level filtering within a team, not complete data isolation between teams.

Governance and collaboration

Certify reveals before sharing them broadly

The certification workflow marks a Reveal as the canonical version of a metric. Certified Reveals appear first in search, get governance badges in the UI, and prevent duplicates from proliferating.

Require certification for any Reveal that:

  • Is used in a Mosaic shared with 10+ people
  • Is referenced in a scheduled report
  • Is cited in a business review or executive summary

Write description fields for all nodes, measures, and dimensions

Descriptions appear as tooltips in Discover and as context for Orion. A node or measure without a description is a documentation gap:

cml
node: orders
  description: "All confirmed customer orders. Excludes cancelled and draft orders."
  measures:
    - name: total_revenue
      description: "Net revenue after returns and discounts, in USD. Excludes shipping and tax."

Use Evals to prevent regressions

Create Evals for the 10โ€“20 questions your team asks most frequently. Run them before every semantic model release. A passing eval confirms that semantic changes didn't break Orion's understanding of your most important metrics.