Support
Log In

Migrate from Cube

Convert your Cube cubes and views into governed Malloy data models

Cube and Credible share a worldview: a governed model of measures, dimensions, and joins over your warehouse, queried by intent rather than raw SQL. That makes migration clean — Credible reads your Cube data model and rebuilds it as Malloy, keeping the semantics and shedding the engine-specific tuning.

Still weighing the move? Credible vs. Cube sets the two side by side.

What Credible Reads

Your Cube data model — cubes and views authored in YAML or JavaScript. Point the agent at those files and it has everything it needs to translate. Connecting Cube's MCP server (hosted per tenant over OAuth) or its SQL/REST/GraphQL APIs is optional: it lets the agent read the governed catalog directly and validate results against the live model.

What Comes Across

The everyday modeling carries over. The bigger pieces land like this:

In CubeIn Credible
Cubes & viewsMalloy sources (base + curated); import/export and explores govern exposure
Dimensions, measures, segmentsCarried over — measures, dimensions, and reusable where: filters
Pre-aggregationsNot carried over — declare #@ preaggregate on the hot measures in the converted model instead
Data access policies / member securityFine-grained access control in the model, versioned and enforced at the gateway on every query
title / description#(doc) / #(index), compressed into the engine's concept index
Dashboards built on CubeRebuilt as data apps or notebooks

The Migration Flow

Credible reads the model, translates cubes to base sources and views to curated sources, enriches each field with #(doc)/#(index) tags, and — where you connect it — validates row-by-row against Cube's SQL API.

What Credible Handles

  • Pre-aggregations accelerate Cube's query engine but carry no semantics, so they aren't converted — parity is checked against raw data (a stale pre-agg can differ from the source of truth). Once the model is converted, get the same acceleration by declaring #@ preaggregate on the hot measures: Credible builds and refreshes the rollup, and routes coarse-grain queries to it without the query naming it.
  • JavaScript-defined models — dynamic cubes and templated generation are read through Cube's SQL/REST metadata rather than static file parsing.
  • Data access policies (member-level security, queryRewrite) map to Malloy access control rather than a 1:1 mechanism.

Before & After

cubes:
  - name: orders
    sql_table: sales.orders
    description: All customer orders
    joins:
      - name: customers
        relationship: many_to_one
        sql: "{CUBE.customer_id} = {customers.customer_id}"
    dimensions:
      - name: order_id
        sql: order_id
        type: number
        primary_key: true
      - name: status
        description: Current fulfillment status of the order
        sql: order_status
        type: string
    measures:
      - name: total_revenue
        description: Total revenue in USD
        sql: amount
        type: sum
        format: currency
      - name: cancelled_orders
        type: count
        filters:
          - sql: "{CUBE}.status = 'cancelled'"
      - name: cancellation_rate
        sql: "1.0 * {cancelled_orders} / NULLIF({count}, 0) * 100"
        type: number
        format: percent
    pre_aggregations:              # dropped — engine acceleration
      - name: orders_rollup
        measures: [count, total_revenue]
        time_dimension: created_at
        granularity: day
source: orders is conn.table('sales.orders') extend {
  primary_key: order_id
  join_one: customers is conn.table('sales.customers') on customer_id

  dimension:
    #(doc) Current fulfillment status of the order
    #(index)
    status is order_status

  measure:
    #(doc) Number of orders
    order_count is count()

    #(doc) Total revenue in USD
    # currency
    total_revenue is sum(amount)

    #(doc) Orders that were cancelled
    cancelled_orders is count() { where: status = 'cancelled' }

    #(doc) Percentage of orders that were cancelled
    # percent
    cancellation_rate is cancelled_orders / order_count * 100

  view:
    #(doc) Daily orders and revenue trend
    daily_orders is {
      group_by: created_at.day
      aggregate: order_count, total_revenue
    }
}

More than a reformat. The model queries live data by default, with rollups you opt into per measure, is AI-discoverable through the AI Analytics Engine, and serves agents, apps, and BI — not just Cube's APIs. See what you gain →

Next Steps

On this page