{"record":{"id":"25ef6266f98b4cf5","repo":"cube-js/cube","slug":"pre-aggregation-this-preaggregation-tablename","errorCode":null,"errorMessage":"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}","messagePattern":"Pre-aggregation '(.+?)' requested to build (.+?) partitions which exceeds the maximum number of partitions per pre-aggregation of (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/cubejs-query-orchestrator/src/orchestrator/PreAggregationPartitionRangeLoader.ts","lineNumber":449,"sourceCode":"    );\n\n    if (!dateRange) {\n      // If there's no date range intersection between query data range and pre-aggregation build range\n      // use last partition so outer query can receive expected table structure.\n      dateRange = [buildRange[1], buildRange[1]];\n    }\n\n    const partitionRanges = this.compilerCacheFn(\n      ['timeSeries', this.preAggregation.partitionGranularity, JSON.stringify(dateRange), `${this.preAggregation.timestampPrecision}`],\n      () => PreAggregationPartitionRangeLoader.timeSeries(\n        this.preAggregation.partitionGranularity,\n        dateRange,\n        this.preAggregation.timestampPrecision\n      )\n    );\n\n    if (partitionRanges.length > this.options.maxPartitions) {\n      throw new Error(\n        `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}`\n      );\n    }\n\n    return { buildRange: dateRange, partitionRanges };\n  }\n\n  public async loadBuildRange(timestampFormat: string = DEFAULT_TS_FORMAT): Promise<QueryDateRange> {\n    const { preAggregationStartEndQueries } = this.preAggregation;\n    const [startDate, endDate] = await Promise.all(\n      preAggregationStartEndQueries.map(\n        async rangeQuery => PreAggregationPartitionRangeLoader.extractDate(await this.loadRangeQuery(rangeQuery), this.preAggregation.timezone, timestampFormat),\n      ),\n    );\n\n    if (!this.preAggregation.partitionGranularity) {\n      return this.orNowIfEmpty([startDate, endDate]);\n    }","sourceCodeStart":431,"sourceCodeEnd":467,"githubUrl":"https://github.com/cube-js/cube/blob/7d981676b36392fec34088b9afab6bdcad40207c/packages/cubejs-query-orchestrator/src/orchestrator/PreAggregationPartitionRangeLoader.ts#L431-L467","documentation":"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).","triggerScenarios":"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.","commonSituations":"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.","solutions":["Increase maxPartitions in preAggregations options if the large number of partitions is intentional.","Narrow the query's date range (add timeDimension dateRange filters) so fewer partitions are needed.","Use coarser partition granularity (month instead of day) for long histories.","Configure partitionRangeAnchor / rolling windows to limit how many partitions a single build materializes.","Ensure queries always include bounded date ranges (validation rules) before hitting the loader."],"exampleFix":"// before\npreAggregationsOptions: { maxPartitions: 100 }\n// after\npreAggregationsOptions: { maxPartitions: 1000 } // or narrow query dateRange","handlingStrategy":"validation","validationCode":"function countPartitions(start, end, granularity) {\n  const ms = { day: 86400000, hour: 3600000, month: 2629800000 }[granularity];\n  return Math.ceil((new Date(end) - new Date(start)) / ms) + 1;\n}\nif (countPartitions(range[0], range[1], granularity) > maxPartitions) throw new Error('Date range exceeds maxPartitions');","typeGuard":null,"tryCatchPattern":"try {\n  return await loader.loadPreAggregations();\n} catch (e) {\n  if (String(e.message).includes('exceeds the maximum number of partitions')) {\n    // narrow date range or raise maxPartitions in preAggregations options\n  }\n  throw e;\n}","preventionTips":["Always bound time dimension date ranges in application queries.","Choose partition granularity appropriate to data span (month for years of data).","Size maxPartitions to your longest legitimate query range plus headroom.","Validate ranges at the API gateway before they reach the orchestrator."],"tags":["pre-aggregation","partitions","limit","date-range"],"backgroundTag":"max-partitions-exceeded","analyzedSha":"7d981676b36392fec34088b9afab6bdcad40207c","analyzedAt":"2026-09-02T03:45:10.400Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}