Documentation Index
Fetch the complete documentation index at: https://docs.cube.dev/llms.txt
Use this file to discover all available pages before exploring further.
Use case
A common modeling problem is computing a metric that depends on two inputs which change at very different rates:- A large fact table that is expensive to aggregate and only needs to be refreshed on a slow cadence (for example, daily or hourly).
- A small lookup table whose values are applied to each fact row and that needs to be refreshed much more frequently than the fact aggregation.
- Converting an amount column to a target currency using the latest foreign
exchange (FX) rates — either a single-currency column multiplied by a rate,
or an
amountandcurrencycolumn resolved with aCASEstatement. - Re-pricing inventory or order lines with a frequently-updated price list.
- Applying a frequently-tuned scoring weight, tax rate, or commission rate to historical events.
Data modeling
We have two cubes:orders, which stores per-order amounts in the original
transaction currency, and fx_rates, which stores the latest exchange rate
from each currency to USD.
The orders table looks like this:
| id | currency | amount | created_at |
|---|---|---|---|
| 1 | EUR | 120.00 | 2026-05-18 09:14:22 |
| 2 | GBP | 75.50 | 2026-05-18 11:02:47 |
| 3 | EUR | 245.10 | 2026-05-19 08:31:05 |
| 4 | USD | 310.00 | 2026-05-19 10:18:33 |
| 5 | GBP | 89.99 | 2026-05-19 12:44:51 |
fx_rates table looks like this:
| currency | rate_to_usd |
|---|---|
| EUR | 1.085 |
| GBP | 1.262 |
| USD | 1.000 |
rollup pre-aggregation on orders that aggregates the
amount by currency and day. This is the heavy pre-aggregation, so we set a
slow refresh_key — for example, every day:
rollup pre-aggregation on fx_rates. This pre-aggregation is
small (one row per currency) and cheap to rebuild, so we give it a much
faster refresh_key than the orders rollup — for example, every hour:
Both pre-aggregations must include an index on the join key (
currency in
this example) for the rollup_join to match. The fx_rates_rollup also
needs rate_to_usd as a dimension so it’s available downstream.rollup_join pre-aggregation on orders that references
both rollups. This is an ephemeral pre-aggregation — it doesn’t materialize
its own data, so it doesn’t need a refresh_key. Cube serves queries from it
by joining the two underlying rollups on the fly:
orders that
multiplies the order amount by the FX rate from the joined cube:
Query
Let’s query daily sales in USD by currency:Result
Cube serves the query fromorders_with_fx_rollup, joining the cached
orders_rollup (refreshed daily) with the cached fx_rates_rollup
(refreshed hourly). The heavy aggregation never rebuilds when FX rates
change, but the converted totals always reflect the latest rates.