{"record":{"id":"0ff756202ca9ea15","repo":"thanos-io/thanos","slug":"too-many-samples-0ff756","errorCode":null,"errorMessage":"too many samples","messagePattern":"too many samples","errorType":"http","errorClass":null,"httpStatus":413,"severity":"warning","filePath":"pkg/receive/handler_otlp.go","lineNumber":93,"sourceCode":"\n\tmetrics, _, err := h.convertToPrometheusFormat(ctx, req.Metrics())\n\tif err != nil {\n\t\thttp.Error(w, err.Error(), http.StatusBadRequest)\n\t\treturn\n\t}\n\n\ttotalSamples := 0\n\tfor _, ts := range metrics {\n\t\ttotalSamples += len(ts.Samples)\n\t}\n\n\tif !requestLimiter.AllowSeries(tenant, int64(len(metrics))) {\n\t\thttp.Error(w, \"too many timeseries\", http.StatusRequestEntityTooLarge)\n\t\treturn\n\t}\n\n\tif !requestLimiter.AllowSamples(tenant, int64(totalSamples)) {\n\t\thttp.Error(w, \"too many samples\", http.StatusRequestEntityTooLarge)\n\t\treturn\n\t}\n\n\trep := uint64(0)\n\t// If the header is empty, we assume the request is not yet replicated.\n\tif replicaRaw := r.Header.Get(h.options.ReplicaHeader); replicaRaw != \"\" {\n\t\tif rep, err = strconv.ParseUint(replicaRaw, 10, 64); err != nil {\n\t\t\thttp.Error(w, \"could not parse replica header\", http.StatusBadRequest)\n\t\t\treturn\n\t\t}\n\t}\n\n\t//TODO: (nicolastakashi) Handle metadata in the future.\n\twreq := tprompb.WriteRequest{\n\t\tTimeseries: metrics,\n\t}\n\n\t// Exit early if the request contained no data. We don't support metadata yet. We also cannot fail here, because","sourceCodeStart":75,"sourceCodeEnd":111,"githubUrl":"https://github.com/thanos-io/thanos/blob/35b8b991177def87ed52dcf10f9b6d87f07282c8/pkg/receive/handler_otlp.go#L75-L111","documentation":"HTTP 413 returned when the total number of samples in the request exceeds the tenant's per-request sample limit enforced by requestLimiter.AllowSamples. Like the series limit, it bounds the processing cost of a single OTLP write; totalSamples is computed by summing len(ts.Samples) over all converted time series.","triggerScenarios":"A single OTLP export whose total sample count (including multiple datapoints per series, e.g. cumulative histograms or dense time points) exceeds the tenant's max samples per request.","commonSituations":"High-frequency scrapers sending many datapoints per series; cumulative histogram buckets each counted as samples; per-request sample limit tuned too low for batched exports.","solutions":["Send datapoints more frequently in smaller batches instead of accumulating many points per export (prefer delta temporality or smaller batch windows).","Increase the tenant's max samples per request limit.","Reduce histogram bucket counts or switch to exponential histograms.","Split the payload across multiple requests at the collector."],"exampleFix":"# before: one batch with many points per series\nbatch:\n  timeout: 30s\n# after: smaller windows\nbatch:\n  timeout: 5s\n  send_batch_max_size: 2000","handlingStrategy":"validation","validationCode":"if totalSamples > maxSamplesPerRequest { splitIntoSmallerExports() }","typeGuard":null,"tryCatchPattern":"if resp.StatusCode == 413 { shrinkBatchWindow(); retry() }","preventionTips":["Prefer delta temporality or frequent small exports over accumulating points","Limit histogram bucket counts","Set batch max size at the collector"],"tags":["http","limits","thanos","samples"],"backgroundTag":"payload-too-large","analyzedSha":"35b8b991177def87ed52dcf10f9b6d87f07282c8","analyzedAt":"2026-09-07T01:49:59.689Z","contentChangedAt":"2026-09-07T01:49:59.689Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}