Skip label cloning without external labels

perfloop/prometheus · AVOIDABLE COPY

https://perfloop.ai/t/oss/case_qpkz5hmsfk

Verdict

VERIFIED · settled 2026-08-22 · merged as prometheus/prometheus#19503

What happened: The paired measurements met the required improvement.

Hypothesis

In the accepted remote-read samples path, remoteReadSamples first receives TimeSeries labels materialized by ToQueryResult and then, once per returned TimeSeries in every query, unconditionally assigns ts.Labels = MergeLabels(ts.Labels, sortedExternalLabels) before EncodeReadResponse consumes the response. MergeLabels always makes a fresh []prompb.Label backing array and appends every input label. When sortedExternalLabels is empty, that is a real retained output allocation and L-label struct copy per series, while the just-materialized primary slice has no later consumer; returning primary is safe on this handler path because it is not mutated before encoding. The removed delta therefore scales with returned-series count times labels per series (S×L), at per-series cadence within each remote-read query. A focused stock-code check, BenchmarkPerfloopMergeLabelsWithEmptySecondary with 24 primary labels and an empty secondary slice, measured 1213 ns/op, 1792 B/op, and 1 alloc/op; this is a function microbenchmark rather than evidence of end-to-end latency. A case session should reproduce it with a benchmark sweeping S and L through remoteReadSamples with no external labels and confirm one fewer primary-label backing allocation per series in allocs/op and bytes/op, then use an allocation/CPU profile of the remote-read endpoint to establish whether the saved copies improve request cost without changing encoded labels.

Change to test: Add an empty-secondary fast path that returns the already materialized primary labels unchanged, while retaining the current merge for configured external labels and preserving the existing response-label tests.

Where it lives

perfloop/prometheus · storage/remote/read_handler.go

Evidence

sampled remote read without external labels (100 series, 24 labels) · 10 sample pairs

metric baseline candidate paired median change confidence range required result
ns/op 325109 272038 −14.2% (−46048) −56945 to −35736 < −16255 PASSED
B/op 774362 595162 −23.1% (−179200) −179200 to −179200 < −38718 PASSED
allocs/op 1358 1258 −7.4% (−100) −100 to −100 < −67.9 PASSED

Checks: 5 of 5 passed. Verification: no defect found.

Timeline