Skip to main content

Quick Start

This guide walks you through setting up Aggregate Awareness so Holistics can automatically use your pre-aggregated tables for faster queries.

What you'll accomplish:

  • Map a raw model to a pre-aggregated table
  • Configure Holistics to use that table automatically

Example scenario

We'll use a common scenario: a raw_transactions table with billions of rows that users frequently query by day, status, and location.

Raw transactions table

The goal: Create a pre-aggregated table with daily counts, so queries like "transactions by day and country" scan thousands of rows instead of billions.

Pre-aggregated table

Step 1: Define the pre-aggregate mapping

In your dataset file, add a pre_aggregates block that maps your model's fields to the columns in your pre-aggregated table.

Dataset ecommerce {
models: [transactions]

pre_aggregates: {
agg_transactions: PreAggregate {

// Dimension mappings: model field → pre-agg column
dimension created_at_day {
for: r(transactions.created_at)
time_granularity: "day"
}
dimension status {
for: r(transactions.status)
}
dimension country {
for: r(transactions.country)
}
dimension city {
for: r(transactions.city)
}

// Measure mapping: aggregation type + source field
measure count_transactions {
for: r(transactions.id)
aggregation_type: 'count'
}
}
}
}

What this does:

  • dimension created_at_day tells Holistics that queries at day granularity (or coarser) can use this table
  • measure count_transactions tells Holistics this table contains pre-computed counts of transactions.id
Pre-aggregate configuration

Step 2: Connect to a pre-aggregated table

Now tell Holistics where to find the actual table. Choose the option that fits your setup:

Option A: Use an existing table

If you already have pre-aggregated tables in your warehouse (from dbt, Airflow, etc.), point to them with ExternalPersistence:

Dataset ecommerce {
pre_aggregates: {
agg_transactions: PreAggregate {
// ... dimension and measure mappings from Step 1

persistence: ExternalPersistence {
table_name: 'your_schema.your_aggregated_table'
}
}
}
}
Column names must match

The dimension and measure names in your pre-aggregate config must exactly match the column names in your external table.

Option B: Let Holistics create the table

If you don't have a pre-aggregated table yet, Holistics can create and maintain it for you:

Dataset ecommerce {
pre_aggregates: {
agg_transactions: PreAggregate {
// ... dimension and measure mappings from Step 1

persistence: FullPersistence {
schema: 'persisted'
}
}
}
}

After adding this configuration, trigger the table creation. See Built-in Pre-aggregate Persistence for instructions.

Which option should I choose?
  • ExternalPersistence → You manage the table refresh schedule and logic
  • FullPersistence → Holistics manages everything for you

Step 3: Verify it's working

After configuration, test that Aggregate Awareness is active:

  1. Open an exploration using your model
  2. Query dimensions and measures that exist in your pre-aggregate
  3. Check the generated SQL—it should reference your pre-aggregated table, not the raw table
Query using pre-aggregate

What happened: The user queried transactions, but Holistics automatically used agg_transactions because it had all the required fields at the right granularity.


Next steps


Let us know what you think about this document :)