cube-js/cube · error · Error

The count of generated date ranges (${count}) for the reques

Error message

The count of generated date ranges (${count}) for the request from [${startStr}] to [${endStr}] by ${intervalStr} is over limit (${limit}). Please reduce the requested date interval or use bigger granularity.

What it means

checkSeriesForDateRange (packages/cubejs-backend-shared/src/time.ts:209) computes the number of interval buckets the requested [start,end] range produces (rangeSeconds / intervalAsSeconds) and throws if it exceeds a hard soft limit of 50000. It guards timeSeries/timeSeriesFromCustomInterval against generating enormous arrays of date ranges that would exhaust memory or stall the request.

Source

Thrown at packages/cubejs-backend-shared/src/time.ts:209

  Object.entries(parsedInterval).forEach(([key, value]) => {
    duration.add(value, key as unitOfTime.DurationConstructor);
  });

  return duration;
};

function checkSeriesForDateRange(intervalStr: string, [startStr, endStr]: QueryDateRange): void {
  const intervalParsed = parseSqlInterval(intervalStr);
  const intervalAsSeconds = parsedSqlIntervalToDuration(intervalParsed).asSeconds();
  const start = moment(startStr);
  const end = moment(endStr);
  const rangeSeconds = end.diff(start, 'seconds');

  const limit = 50000; // TODO Make this as configurable soft limit
  const count = rangeSeconds / intervalAsSeconds;

  if (count > limit) {
    throw new Error(`The count of generated date ranges (${count}) for the request from [${startStr}] to [${endStr}] by ${intervalStr} is over limit (${limit}). Please reduce the requested date interval or use bigger granularity.`);
  }
}

export const timeSeriesFromCustomInterval = (intervalStr: string, [startStr, endStr]: QueryDateRange, origin: moment.Moment, options: TimeSeriesOptions = { timestampPrecision: 3 }): QueryDateRange[] => {
  checkSeriesForDateRange(intervalStr, [startStr, endStr]);

  const intervalParsed = parseSqlInterval(intervalStr);
  const start = moment(startStr);
  const end = moment(endStr);
  let alignedStart = alignToOrigin(start, intervalParsed, origin);

  const dates: QueryDateRange[] = [];

  while (alignedStart.isBefore(end)) {
    const s = alignedStart.clone();
    alignedStart = addInterval(alignedStart, intervalParsed);
    dates.push([
      s.format(`YYYY-MM-DDTHH:mm:ss.${'0'.repeat(options.timestampPrecision)}`),

View on GitHub (pinned to 7d981676b3)

Solutions

  1. Reduce the requested date range (narrow start/end) so the bucket count stays under 50000.
  2. Use a bigger granularity (minute/hour/day instead of second) — as the message itself suggests.
  3. Clamp or round user-supplied ranges in application code before calling timeSeries.
  4. Pre-aggregate upstream (e.g. rollups) and query the coarser series instead.

Example fix

// before
timeSeries('second', ['2020-01-01', '2026-01-01']); // ~190M buckets: throws

// after
timeSeries('hour', ['2020-01-01', '2026-01-01']); // ~52k → use 'day' to stay safe
timeSeries('day', ['2020-01-01', '2026-01-01']);
Defensive patterns

Strategy: validation

Validate before calling

const MAX = 50000;
function assertSeriesSize(interval: string, [start, end]: [string, string]) {
  const seconds = (Date.parse(end) - Date.parse(start)) / 1000;
  const intervalSeconds = /* parse '1 second' etc. */ 1;
  if (seconds / intervalSeconds > MAX) {
    throw new Error(`Requested series has >${MAX} buckets; narrow the range or increase granularity`);
  }
}

Try / catch

try {
  return timeSeries(granularity, range, opts);
} catch (e) {
  if (/is over limit/.test(String(e))) {
    return timeSeries('day', range, opts); // coarser fallback
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling timeSeries(granularity, ['2000-01-01','2026-01-01']) with a small granularity such as 'second' or 'minute' over many years, or timeSeriesFromCustomInterval('1 second', ...) over a multi-month span, so count = rangeSeconds/intervalAsSeconds > 50000.

Common situations: Dashboard widgets requesting second-level granularity over years of history; user-supplied date pickers allowing arbitrarily wide ranges combined with fine granularity; misconfigured custom intervals like '1 millisecond'.

Related errors


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