cube-js/cube · error

Pre-aggregation '${this.preAggregation.tableName}' requested

Error message

Pre-aggregation '${this.preAggregation.tableName}' requested to build ${partitionRanges.length} partitions which exceeds the maximum number of partitions per pre-aggregation of ${this.options.maxPartitions}

What it means

For partitioned pre-aggregations, Cube splits the requested date range into partition ranges to build. partitionRanges throws if the number of partitions to build exceeds options.maxPartitions, protecting the instance from an accidental explosion of build jobs (memory, queue, storage).

Source

Thrown at packages/cubejs-query-orchestrator/src/orchestrator/PreAggregationPartitionRangeLoader.ts:449

    );

    if (!dateRange) {
      // If there's no date range intersection between query data range and pre-aggregation build range
      // use last partition so outer query can receive expected table structure.
      dateRange = [buildRange[1], buildRange[1]];
    }

    const partitionRanges = this.compilerCacheFn(
      ['timeSeries', this.preAggregation.partitionGranularity, JSON.stringify(dateRange), `${this.preAggregation.timestampPrecision}`],
      () => PreAggregationPartitionRangeLoader.timeSeries(
        this.preAggregation.partitionGranularity,
        dateRange,
        this.preAggregation.timestampPrecision
      )
    );

    if (partitionRanges.length > this.options.maxPartitions) {
      throw new Error(
        `Pre-aggregation '${this.preAggregation.tableName}' requested to build ${partitionRanges.length} partitions which exceeds the maximum number of partitions per pre-aggregation of ${this.options.maxPartitions}`
      );
    }

    return { buildRange: dateRange, partitionRanges };
  }

  public async loadBuildRange(timestampFormat: string = DEFAULT_TS_FORMAT): Promise<QueryDateRange> {
    const { preAggregationStartEndQueries } = this.preAggregation;
    const [startDate, endDate] = await Promise.all(
      preAggregationStartEndQueries.map(
        async rangeQuery => PreAggregationPartitionRangeLoader.extractDate(await this.loadRangeQuery(rangeQuery), this.preAggregation.timezone, timestampFormat),
      ),
    );

    if (!this.preAggregation.partitionGranularity) {
      return this.orNowIfEmpty([startDate, endDate]);
    }

View on GitHub (pinned to 7d981676b3)

Solutions

  1. Increase maxPartitions in preAggregations options if the large number of partitions is intentional.
  2. Narrow the query's date range (add timeDimension dateRange filters) so fewer partitions are needed.
  3. Use coarser partition granularity (month instead of day) for long histories.
  4. Configure partitionRangeAnchor / rolling windows to limit how many partitions a single build materializes.
  5. Ensure queries always include bounded date ranges (validation rules) before hitting the loader.

Example fix

// before
preAggregationsOptions: { maxPartitions: 100 }
// after
preAggregationsOptions: { maxPartitions: 1000 } // or narrow query dateRange
Defensive patterns

Strategy: validation

Validate before calling

function countPartitions(start, end, granularity) {
  const ms = { day: 86400000, hour: 3600000, month: 2629800000 }[granularity];
  return Math.ceil((new Date(end) - new Date(start)) / ms) + 1;
}
if (countPartitions(range[0], range[1], granularity) > maxPartitions) throw new Error('Date range exceeds maxPartitions');

Try / catch

try {
  return await loader.loadPreAggregations();
} catch (e) {
  if (String(e.message).includes('exceeds the maximum number of partitions')) {
    // narrow date range or raise maxPartitions in preAggregations options
  }
  throw e;
}

Prevention

When it happens

Trigger: Querying/building a partitioned pre-aggregation whose dateRange spans more partitions than maxPartitions (e.g., 6 years of day partitions when maxPartitions is 100); a very fine granularity (day/hour) with a wide unbounded range; missing filters so Cube plans to build the full partition extent.

Common situations: Date range filters omitted or unexpectedly wide in dashboard queries; day-granularity partitions over long histories; freshly changed partition granularity without adjusting maxPartitions; errors in date parsing producing huge ranges.

Related errors


AI-assisted analysis of cube-js/cube@7d981676b3 (2026-09-02). Data as JSON: /api/errors/25ef6266f98b4cf5. Report an issue: GitHub.