SigNoz/signoz · error

maximum traces that can be paginated is 10000

Error message

maximum traces that can be paginated is 10000

What it means

For traces list pagination, the sum of limit + offset (or pageSize + offset for logs) must not exceed TRACE_V4_MAX_PAGINATION_LIMIT (10000). This protects the trace store from unbounded windowed pagination scans.

Source

Thrown at pkg/query-service/app/querier/querier.go:358

	limitWithOffset := limit + offset
	if isLogs {
		// for logs we use pageSize to define the current limit and limit to define the absolute limit
		limitWithOffset = pageSize + offset
		if limit > 0 && offset >= limit {
			return nil, nil, fmt.Errorf("max limit exceeded")
		}
	}

	for _, v := range tsRanges {
		params.Start = v.Start
		params.End = v.End
		length := uint64(0)

		// max limit + offset is 10k for pagination for traces/logs
		// TODO(nitya): define something for logs
		if !isLogs && limitWithOffset > constants.TRACE_V4_MAX_PAGINATION_LIMIT {
			return nil, nil, fmt.Errorf("maximum traces that can be paginated is 10000")
		}

		// we are updating the offset and limit based on the number of traces/logs we have found in the current timerange
		// eg -
		// 1)offset = 0, limit = 100, tsRanges = [t1, t10], [t10, 20], [t20, t30]
		//
		// if 100 traces/logs are there in [t1, t10] then 100 will return immediately.
		// if 10 traces/logs are there in [t1, t10] then we get 10, set offset to 0 and limit to 90, search in the next timerange of [t10, 20]
		// if we don't find any trace in [t1, t10], then we search in [t10, 20] with offset=0, limit=100

		//
		// 2) offset = 50, limit = 100, tsRanges = [t1, t10], [t10, 20], [t20, t30]
		//
		// If we find 150 traces/logs with limit=150 and offset=0 in [t1, t10] then we return immediately 100 traces/logs
		// If we find 50 in [t1, t10] with limit=150 and offset=0 then it will set limit = 100 and offset=0 and search in the next timerange of [t10, 20]
		// if we don't find any trace in [t1, t10], then we search in [t10, 20] with limit=150 and offset=0

		params.CompositeQuery.BuilderQueries[qName].Offset = 0

View on GitHub (pinned to 5069bf80b0)

Solutions

  1. Cap limit+offset at 10000: reduce page size or page shallower
  2. Use time-range windows or filters instead of deep offset pagination to reach older traces
  3. If you truly need more than 10k traces, page over narrower time ranges (the API already windows internally) or export directly from ClickHouse

Example fix

// before
params.Limit, params.Offset = 9500, 1000
// after
const maxPagination = 10000
if params.Limit+params.Offset > maxPagination {
    params.Limit = maxPagination - params.Offset
}
Defensive patterns

Strategy: validation

Validate before calling

const maxPagination = 10000
if params.Limit+params.Offset > maxPagination {
    params.Limit = maxPagination - params.Offset
    if params.Limit <= 0 { /* narrow time range instead */ }
}

Type guard

func withinTracePaginationLimit(limit, offset uint64) bool { return limit+offset <= 10000 }

Prevention

When it happens

Trigger: Calling QueryRange with a traces List panel where limitWithOffset exceeds 10000, e.g. limit=9500 with offset=1000, or logs with pageSize+offset beyond the cap when isLogs is false path (traces).

Common situations: Scripting or UI pagination that walks deep into trace results; exporting large trace lists; misconfigured page size multiplied by page count over 10000.

Related errors


AI-assisted analysis of SigNoz/signoz@5069bf80b0 (2026-08-28). Data as JSON: /api/errors/b4b3117d4e691607. Report an issue: GitHub.