SigNoz/signoz · error · model.ApiError
exceeded maximum resolution of 11,000 points per timeseries.
Error message
exceeded maximum resolution of 11,000 points per timeseries. Try decreasing the query resolution (?step=XX)
What it means
SigNoz caps range queries at 11,000 points per timeseries (matching Prometheus safety limits) to prevent memory exhaustion. When (end-start)/step exceeds 11000 the request is rejected and you are told to increase step.
Source
Thrown at pkg/query-service/app/parser.go:165
if end.Before(start) {
err := errors.New("end timestamp must not be before start time")
return nil, &model.ApiError{Typ: model.ErrorBadData, Err: err}
}
step, err := parseMetricsDuration(r.FormValue("step"))
if err != nil {
return nil, &model.ApiError{Typ: model.ErrorBadData, Err: err}
}
if step <= 0 {
err := errors.New("zero or negative query resolution step widths are not accepted. Try a positive integer")
return nil, &model.ApiError{Typ: model.ErrorBadData, Err: err}
}
// For safety, limit the number of returned points per timeseries.
// This is sufficient for 60s resolution for a week or 1h resolution for a year.
if end.Sub(start)/step > 11000 {
err := errors.New("exceeded maximum resolution of 11,000 points per timeseries. Try decreasing the query resolution (?step=XX)")
return nil, &model.ApiError{Typ: model.ErrorBadData, Err: err}
}
queryRangeParams := model.QueryRangeParams{
Start: start,
End: end,
Step: step,
Query: r.FormValue("query"),
Stats: r.FormValue("stats"),
}
return &queryRangeParams, nil
}
func parseGetUsageRequest(r *http.Request) (*model.GetUsageParams, error) {
startTime, err := parseTime("start", r)
if err != nil {
return nil, errView on GitHub (pinned to 5069bf80b0)
Solutions
- Increase step so that (end-start)/step <= 11000 (e.g. for 30 days use step>=240s, commonly step=5m or step=1h)
- Compute step dynamically from the window: step = max(minStep, window/10000)
- Narrow the queried time range
Example fix
// before
params.Set("step", "15s") // with a 30d range
// after
window := end.Sub(start)
step := window / 10000
if step < 15*time.Second {
step = 15 * time.Second
}
params.Set("step", strconv.FormatInt(int64(step.Seconds()), 10)) Defensive patterns
Strategy: validation
Validate before calling
window := end.Sub(start)
step := window / 10000
if step < time.Second {
step = time.Second
}
if window/step > 11000 {
return fmt.Errorf("range too wide for step %v", step)
} Try / catch
if err != nil && strings.Contains(err.Error(), "exceeded maximum resolution") {
// auto-retry with a coarser step
step = window / 10000
resp, err = api.QueryRangeMetrics(ctx, start, end, step, query)
} Prevention
- Always derive step from the selected time window
- Cap dashboard time ranges when step is fixed
- Watch Prometheus parity: same 11000-point limit applies
When it happens
Trigger: Querying a long window with a fine step, e.g. 30 days at step=60s (43200 points) or a year at step=1h; auto-step formulas that use a fixed small step regardless of window size.
Common situations: Dashboards with long time ranges (30d/90d) and hardcoded step=15s; custom date-pickers allowing very wide ranges; scripts that iterate with tiny steps.
Related errors
- zero or negative query resolution step widths are not accept
- CodeLicenseUnavailable
- CodeInvalidInput
- CodeForbidden
- CodeNotFound
AI-assisted analysis of SigNoz/signoz@5069bf80b0 (2026-08-28).
Data as JSON: /api/errors/77a4a583e784dc29.
Report an issue: GitHub.