Skip to content

[receiver/prometheus] Prometheus AppenderV2 interface implementation#46426

Merged
songy23 merged 39 commits intoopen-telemetry:mainfrom
perebaj:prometheus-appenderv2
Apr 15, 2026
Merged

[receiver/prometheus] Prometheus AppenderV2 interface implementation#46426
songy23 merged 39 commits intoopen-telemetry:mainfrom
perebaj:prometheus-appenderv2

Conversation

@perebaj
Copy link
Copy Markdown
Contributor

@perebaj perebaj commented Feb 25, 2026

Description

Implementing the new appenderV2 interface. Upstream code -> prometheus/prometheus#17872

Signed-off-by: perebaj <perebaj@gmail.com>
Signed-off-by: perebaj <perebaj@gmail.com>
Signed-off-by: perebaj <perebaj@gmail.com>
Signed-off-by: perebaj <perebaj@gmail.com>
Signed-off-by: perebaj <perebaj@gmail.com>
@dashpole
Copy link
Copy Markdown
Contributor

My recommendation is still to see if you can implement the V2 interface using the V1 methods to start with... Then we can make manageable refactor PRs that simplify the logic. It is mostly hard to review this code because I can't see the diff with the current v1 appender implementation. I assume most of it is copy-pasted, but its hard to tell.

@perebaj
Copy link
Copy Markdown
Contributor Author

perebaj commented Feb 25, 2026

My recommendation is still to see if you can implement the V2 interface using the V1 methods to start with... Then we can make manageable refactor PRs that simplify the logic. It is mostly hard to review this code because I can't see the diff with the current v1 appender implementation. I assume most of it is copy-pasted, but its hard to tell.

thanks David

Signed-off-by: perebaj <perebaj@gmail.com>
Signed-off-by: perebaj <perebaj@gmail.com>
@dashpole
Copy link
Copy Markdown
Contributor

Nice. Why did you add the feature gate? Unless there is something we are particularly concerned about, I think we can just make the switch

Signed-off-by: perebaj <perebaj@gmail.com>
Signed-off-by: perebaj <perebaj@gmail.com>
Signed-off-by: perebaj <perebaj@gmail.com>
Copy link
Copy Markdown
Contributor

@dashpole dashpole left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looking good

Comment thread receiver/prometheusreceiver/internal/transaction_test.go Outdated
perebaj added 3 commits March 10, 2026 16:41
Signed-off-by: perebaj <perebaj@gmail.com>
Signed-off-by: perebaj <perebaj@gmail.com>
Signed-off-by: perebaj <perebaj@gmail.com>
@perebaj
Copy link
Copy Markdown
Contributor Author

perebaj commented Mar 11, 2026

For some reason an angel before me already wrapped the call of the appenderV1 into a helper function, so I just update the func (tt buildTestData) run(t *testing.T) to new version 😊

Some tests that directly call functions belonging to the appender v1 interface cannot be replaced or updated because those functions are no longer available in v2. I’ve added a comment to the test file to make it clear, but I’m not sure what the best approach is. Should I simply delete them?

Signed-off-by: perebaj <perebaj@gmail.com>
@ArthurSens ArthurSens added the receiver/prometheus Prometheus receiver label Mar 11, 2026
@dashpole
Copy link
Copy Markdown
Contributor

Some tests that directly call functions belonging to the appender v1 interface cannot be replaced or updated because those functions are no longer available in v2.

We definitely don't want to reduce test coverage as part of the migration. My suggestion is that in this PR (or follow-up ones), you just make the appender V1 functions non-exported. Then, we just try to refactor and simplify from here in small steps, and update tests as-needed during those refactors.

@perebaj perebaj marked this pull request as ready for review March 11, 2026 16:51
@perebaj perebaj requested review from a team and ArthurSens as code owners March 11, 2026 16:51
@github-actions github-actions bot requested review from Aneurysm9 and krajorama March 11, 2026 16:56
@perebaj
Copy link
Copy Markdown
Contributor Author

perebaj commented Mar 11, 2026

@ArthurSens @dashpole should I share the benchmark results after and before my changes?

@dashpole
Copy link
Copy Markdown
Contributor

That would be excellent!

@ArthurSens ArthurSens added the Skip Changelog PRs that do not require a CHANGELOG.md entry label Apr 6, 2026
Copy link
Copy Markdown
Member

@ArthurSens ArthurSens left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It feels like we can simplify the functions that have become private. Although I'd really appreciate it if @krajorama or @bwplotka could clarify how staleness tracking works in the appenderv2 codepath.

If I remember correctly, in v1 the labels hash was used as a stable reference for what was scraped, but since v2 can append multiple items at once, how do we track now?

Comment thread receiver/prometheusreceiver/internal/transaction.go Outdated
Comment thread receiver/prometheusreceiver/internal/transaction.go Outdated
Comment thread receiver/prometheusreceiver/internal/transaction.go Outdated
Comment thread receiver/prometheusreceiver/internal/transaction.go Outdated
Comment thread receiver/prometheusreceiver/internal/transaction.go Outdated
Copy link
Copy Markdown
Member

@ArthurSens ArthurSens left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

Comment thread receiver/prometheusreceiver/internal/transaction.go Outdated
@dashpole dashpole added the ready to merge Code review completed; ready to merge by maintainers label Apr 10, 2026
@krajorama
Copy link
Copy Markdown
Member

Reviewing now, sorry about the delay, plz wait with merge.

Copy link
Copy Markdown
Member

@krajorama krajorama left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for the long delay. Looks good for the most part, but me and Claude found a couple of small issue, and maybe a missing addScopeAttributesFromLabels call.

schema = fh.Schema
}
t.addingNativeHistogram = true
t.addingNHCB = schema == -53
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit:

Suggested change
t.addingNHCB = schema == -53
t.addingNHCB = schema == histogram.CustomBucketsSchema

cacheRef := ls.Hash()
err = curMF.addSeries(seriesRef, metricName, ls, atMs, val)

if stMs > 0 {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit, negative timestamps are allowed in Prometheus and we do != in other places.

Suggested change
if stMs > 0 {
if stMs != 0 {

seriesRef := t.getSeriesRef(ls, curMF.mtype)
cacheRef := ls.Hash()

if stMs > 0 {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Start time can be negative in Prometheus

Suggested change
if stMs > 0 {
if stMs != 0 {

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

Comment on lines +2227 to +2228
require.Equal(t, tt.val, md.ResourceMetrics().At(0).ScopeMetrics().At(0).Metrics().At(0).Sum().DataPoints().At(0).DoubleValue())
dp := md.ResourceMetrics().At(0).ScopeMetrics().At(0).Metrics().At(0).Sum().DataPoints().At(0)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit:

Suggested change
require.Equal(t, tt.val, md.ResourceMetrics().At(0).ScopeMetrics().At(0).Metrics().At(0).Sum().DataPoints().At(0).DoubleValue())
dp := md.ResourceMetrics().At(0).ScopeMetrics().At(0).Metrics().At(0).Sum().DataPoints().At(0)
dp := md.ResourceMetrics().At(0).ScopeMetrics().At(0).Metrics().At(0).Sum().DataPoints().At(0)
require.Equal(t, tt.val, dp.DoubleValue())

}
require.Equal(t, pcommon.NewTimestampFromTime(time.UnixMilli(tt.stMs)), dp.StartTimestamp())
case pmetric.MetricTypeExponentialHistogram:
dp := md.ResourceMetrics().At(0).ScopeMetrics().At(0).Metrics().At(0).ExponentialHistogram().DataPoints().At(0)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit, let's assert on a value here as well:

Suggested change
dp := md.ResourceMetrics().At(0).ScopeMetrics().At(0).Metrics().At(0).ExponentialHistogram().DataPoints().At(0)
dp := md.ResourceMetrics().At(0).ScopeMetrics().At(0).Metrics().At(0).ExponentialHistogram().DataPoints().At(0)
expectedSum := func() float64 {
if tt.h != nil {
return tt.h.Sum
} else {
return tt.fh.Sum
}
}()
require.Equal(t, expectedSum, dp.Sum())

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

// addSampleDatapoint processes one scraped sample and stores it in the
// appropriate metric family for the resource/scope context. It is shared by
// both V1 and V2 appender paths.
func (t *transaction) addSampleDatapoint(rKey resourceKey, scope scopeID, ls labels.Labels, metricName string, atMs int64, val float64, stMs int64) (storage.SeriesRef, error) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See below. This is not needed, recalculated anyway.

Suggested change
func (t *transaction) addSampleDatapoint(rKey resourceKey, scope scopeID, ls labels.Labels, metricName string, atMs int64, val float64, stMs int64) (storage.SeriesRef, error) {
func (t *transaction) addSampleDatapoint(rKey resourceKey, ls labels.Labels, metricName string, atMs int64, val float64, stMs int64) (storage.SeriesRef, error) {

@@ -103,42 +103,23 @@ func newTransaction(
}

// Append returns a stable series reference to enable Prometheus staleness tracking.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// Append returns a stable series reference to enable Prometheus staleness tracking.
// append returns a stable series reference to enable Prometheus staleness tracking.


if h != nil && h.CounterResetHint == histogram.GaugeType || fh != nil && fh.CounterResetHint == histogram.GaugeType {
t.logger.Warn("dropping unsupported gauge histogram datapoint", zap.String("metric_name", metricName), zap.Any("labels", ls))
t.logger.Warn("unsupported gauge histogram datapoint", zap.String("metric_name", metricName), zap.Any("labels", ls))
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: dropping was more explicit

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dashpole did a similar comment here #46426 (comment)

We are not dropping anything. Unless we decide to add return here

return 0, err
}

var sRef storage.SeriesRef
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We are computing the reference number from the labels. The set of labels is identifying, so the same series will get the same labels and thus the same reference, so that's correct to use for staleness tracking.

However, we could have hash collision, meaning that we don't detect staleness sometimes as one series can keep alive the cache.

This is probably fine for now, but as soon as the scape cache is used for some new purpose, this will break.

// validate method-specific behavior that is not exposed as independent calls in
// the V2 interface (for example, direct AppendExemplar/STZero contract checks).

func TestTransactionAppend(t *testing.T) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

some basic tests on attributes handling would be nice here I think

@andrzej-stencel andrzej-stencel removed the ready to merge Code review completed; ready to merge by maintainers label Apr 13, 2026
@andrzej-stencel
Copy link
Copy Markdown
Member

Removing the ready to merge label as one of the codeowners' requested changes.

perebaj added 3 commits April 13, 2026 18:18
… scope parameter from addSampleDatapoint and

    addHistogramDatapoint, since it was recalculated internally
  - Add missing addScopeAttributesFromLabels call in addHistogramDatapoint
  - Use stMs != 0 instead of stMs > 0 to allow negative timestamps
  - Replace magic number -53 with histogram.CustomBucketsSchema
  - Simplify test datapoint access and add value assertion for
    exponential histogram Sum
  - Add scope attribute test cases to TestTransactionAppend
  - Fix comment casing on append function

Signed-off-by: perebaj <perebaj@gmail.com>
…try-collector-contrib into prometheus-appenderv2
@ArthurSens
Copy link
Copy Markdown
Member

@perebaj, pinging just in case you missed this:

Error: receiver/prometheusreceiver/internal/transaction_test.go:2282:13: indent-error-flow: if block ends with a return statement, so drop this else and outdent its block (revive)

@perebaj
Copy link
Copy Markdown
Contributor Author

perebaj commented Apr 14, 2026

@perebaj, pinging just in case you missed this:

Error: receiver/prometheusreceiver/internal/transaction_test.go:2282:13: indent-error-flow: if block ends with a return statement, so drop this else and outdent its block (revive)

thank you, I thought that the reds were related to other things not related to my PR, fixing...

Signed-off-by: perebaj <perebaj@gmail.com>
Copy link
Copy Markdown
Member

@ArthurSens ArthurSens left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Epic work @perebaj! Thanks for the patience and getting this through the finishing line!

@ArthurSens
Copy link
Copy Markdown
Member

I made sure Jonathan's latest commits addresses Krajo's comments. So I'm adding the ready to merge label

@ArthurSens ArthurSens added the ready to merge Code review completed; ready to merge by maintainers label Apr 14, 2026
@perebaj
Copy link
Copy Markdown
Contributor Author

perebaj commented Apr 14, 2026

Final Benchmark Report

Obs: This benchmark and the summary were generated with the help of AI

Branch: prometheus-appenderv2 vs main
Platform: darwin/arm64 | Apple M3 Pro | 8 iterations per benchmark
Package: receiver/prometheusreceiver/internal


Execution Time (CPU)

Benchmark Group Baseline (main) Avg New Branch Avg Shift
Append ~17.6 ms ~18.7 ms ~6% Slower
AppendHistogram ~16.7 ms ~18.7 ms ~12% Slower
ClassicMetrics Commit (Baseline) ~50.0 ms ~42.1 ms same
ClassicMetrics Commit (WithTargetInfo) ~41.4 ms ~41.3 ms ~Same
ClassicMetrics Commit (WithScopeInfo) ~41.4 ms ~41.0 ms ~Same
NativeHistogram Commit (Baseline) ~41.5 ms ~46.9 ms ~13% Slower
NativeHistogram Commit (WithTargetInfo) ~46.0 ms ~51.7 ms ~12% Slower
NativeHistogram Commit (WithScopeInfo) ~49.8 ms ~49.2 ms ~Same
AppendCreatedMetricLine ~35.3 ms ~35.6 ms ~Same
AppendSTZeroSample ~34.7 ms ~21.0 ms ~40% Faster

Memory & Allocations

Metric Baseline (main) New Branch Difference
Append B/op 7.736 MiB/op 8.042 MiB/op +3.95%
Append allocs/op 110.1k 130.1k +18.17% (+20k exactly)
Commit Classic B/op 28.91 MiB/op 31.50 MiB/op +8.97%
Commit NativeHist B/op 31.65 MiB/op 34.25 MiB/op +8.20%
Commit allocs/op (all variants) 620k / 650k 620k / 650k Same
AppendCreatedMetricLine B/op 7.652 MiB/op 8.263 MiB/op +7.98%
AppendCreatedMetricLine allocs/op 120.1k 160.1k +33.31% (+40k exactly)
AppendSTZeroSample B/op 7.652 MiB/op 7.431 MiB/op -2.89%
AppendSTZeroSample allocs/op 120.1k 120.1k Same

benchstat Geomean Summary

Metric Type Baseline (main) New Branch Shift
Execution Time (sec/op) 34.28 ms 33.77 ms -1.51%
Memory Allocated (B/op) 17.49 MiB 18.61 MiB +6.39%
Allocations Count (allocs/op) 320.5k 341.1k +6.41%

Structural Analysis (from raw .bench files)

Allocation Count Deltas (deterministic, 0% variance)

Benchmark Baseline New Branch Delta
Append 110,099 130,099 +20,000
AppendHistogram 110,099 130,099 +20,000
Commit (all variants) 620k / 650k 620k / 650k 0
AppendCreatedMetricLine 120,099 160,099 +40,000
AppendSTZeroSample 120,099 120,099 0

Memory Deltas (deterministic)

Benchmark Delta (B/op) Per-Series Overhead
Append / AppendHistogram +320,224 B ~32 B/series
Commit Classic +2,720,032 B ~272 B/series
Commit NativeHist +2,720,028 B ~272 B/series
AppendCreatedMetricLine +640,222 B ~32 B/line (20k lines)
AppendSTZeroSample -231,777 B Saves ~23 B/series

The Commit delta is identical (+2,720,030 B) for both Classic and NativeHistogram, confirming the extra memory comes from the same shared code path (attribute map capacity pre-allocation), not from metric-type-specific logic.


CPU Profiling Analysis

BenchmarkAppend - CPU Hot Paths

Function Baseline (main) cum% New Branch cum%
(*transaction).Append 63.57% 60.69%
(*transaction).addSampleDatapoint N/A (inlined) 47.40%
(*transaction).getSeriesRef 17.14% 19.08%
(*transaction).getOrCreateMetricFamily 14.29% 15.03%
(*transaction).prepareLabels N/A 13.29%
labels.Labels.Range 5.00% 12.72%
getScopeID 5.00% 6.36%
runtime.madvise 11.43% 10.98%

BenchmarkCommit/ClassicMetrics - CPU Hot Paths

Function Baseline (main) cum% New Branch cum%
(*metricFamily).appendMetric 37.10% 34.45%
(*metricGroup).toNumberDataPoint 31.70% 30.38%
populateAttributes 30.71% 27.75%
Map.PutStr 25.31% 22.25%
Map.Get 16.71% 15.55%
runtime.gcDrain 17.20% 19.62%

BenchmarkCommit/NativeHistogram - CPU Hot Paths

Function Baseline (main) cum% New Branch cum%
(*metricGroup).toExponentialHistogramDataPoints 33.65% 33.48%
populateAttributes 28.44% 30.00%
Map.PutStr 20.85% 25.22%
Map.Get 14.22% 16.09%
Baseline: (*transaction).AppendHistogram 12.80% N/A
New: (*transaction).addHistogramDatapoint N/A 13.04%

Memory Profiling Analysis

BenchmarkAppend - Top Memory Allocators

Function Baseline (main) New Branch
loadMetricGroupOrCreate 178.02 MB (31.02%) 208.53 MB (30.22%)
metadataForMetric 91.51 MB (15.94%) 119.01 MB (17.25%)
labels.Builder.Set 101.70 MB (17.72%) 113.23 MB (16.41%)
getOrCreateMetricFamily 215.55 MB (37.56%) 269.48 MB (39.05%)
newMetricFamily 148.01 MB (25.79%) 189.01 MB (27.39%)
NewExemplarSlice 13.50 MB (2.35%) 25.50 MB (3.70%)

BenchmarkCommit/ClassicMetrics - Top Memory Allocators

Function Baseline (main) New Branch
Map.EnsureCapacity 784.34 MB (39.94%) 869.20 MB (42.44%)
NewAnyValueStringValue 379.01 MB (19.30%) 350.51 MB (17.11%)
NewMetric 81.51 MB (4.15%) 86.51 MB (4.22%)
Map.PutStr 390.51 MB (19.88%) 371.51 MB (18.14%)

@perebaj
Copy link
Copy Markdown
Contributor Author

perebaj commented Apr 14, 2026

Guys, this is the final benchmark. And it made me stay a little bit skeptical about the performance boost of this whole change. Especially the AppendSTZeroSample because it was the only function that suffered the biggest boost. I think it would be interesting to spend some more time reviewing why only this function experienced this performance increase; it sounds very strange to me. Can we hold the merge until I validate that nothing is actually missing?

@ArthurSens
Copy link
Copy Markdown
Member

ArthurSens commented Apr 14, 2026

Ps: a regular benchstat comparison is probably a lot easier to read than an AI generated comparison. It's a lot more compact and we're all used to the format already :)

@perebaj
Copy link
Copy Markdown
Contributor Author

perebaj commented Apr 15, 2026

Ps: a regular benchstat comparison is probably a lot easier to read than an AI generated comparison. It's a lot more compact and we're all used to the format already :)

goos: darwin
goarch: arm64
pkg: github.com/open-telemetry/opentelemetry-collector-contrib/receiver/prometheusreceiver/internal
cpu: Apple M3 Pro
                                                                     │ baseline.bench.txt │    new-branch-clean.bench.txt     │
                                                                     │      sec/op        │     sec/op       vs base          │
Append-11                                                                    17.38m ± 11%     18.35m ±  7%   +5.58% (p=0.038 n=8)
AppendHistogram-11                                                           16.59m ±  8%     18.52m ±  2%  +11.67% (p=0.000 n=8)
Commit/ClassicMetrics/Baseline-11                                            44.19m ± 56%     40.49m ±  4%        ~ (p=0.130 n=8)
Commit/ClassicMetrics/WithTargetInfo-11                                      41.43m ±  7%     40.66m ±  2%        ~ (p=0.798 n=8)
Commit/ClassicMetrics/WithScopeInfo-11                                       41.44m ±  6%     40.11m ±  2%        ~ (p=0.878 n=8)
Commit/NativeHistogram/Baseline-11                                           41.49m ±  4%     47.36m ±  9%  +14.14% (p=0.000 n=8)
Commit/NativeHistogram/WithTargetInfo-11                                     45.75m ± 12%     51.68m ± 10%  +12.98% (p=0.007 n=8)
Commit/NativeHistogram/WithScopeInfo-11                                      47.97m ± 11%     47.96m ± 11%        ~ (p=0.574 n=8)
AppendWithCreatedLine/AppendCreatedMetricLine-11                             33.94m ±  5%     34.94m ±  4%        ~ (p=0.105 n=8)
AppendWithCreatedLine/AppendWithCreatedLineWithAppendSTZeroSample-11         33.19m ± 24%     20.92m ± 11%  -36.96% (p=0.000 n=8)
geomean                                                                      34.28m           33.77m         -1.51%

                                                                     │ baseline.bench.txt │    new-branch-clean.bench.txt     │
                                                                     │       B/op         │      B/op        vs base          │
Append-11                                                                   7.736Mi ± 0%    8.042Mi ± 0%   +3.95% (p=0.000 n=8)
AppendHistogram-11                                                          7.736Mi ± 0%    8.042Mi ± 0%   +3.95% (p=0.000 n=8)
Commit/ClassicMetrics/Baseline-11                                           28.91Mi ± 0%    31.50Mi ± 0%   +8.97% (p=0.000 n=8)
Commit/ClassicMetrics/WithTargetInfo-11                                     28.91Mi ± 0%    31.50Mi ± 0%   +8.97% (p=0.000 n=8)
Commit/ClassicMetrics/WithScopeInfo-11                                      28.91Mi ± 0%    31.50Mi ± 0%   +8.97% (p=0.000 n=8)
Commit/NativeHistogram/Baseline-11                                          31.65Mi ± 0%    34.25Mi ± 0%   +8.20% (p=0.000 n=8)
Commit/NativeHistogram/WithTargetInfo-11                                    31.65Mi ± 0%    34.25Mi ± 0%   +8.20% (p=0.000 n=8)
Commit/NativeHistogram/WithScopeInfo-11                                     31.65Mi ± 0%    34.25Mi ± 0%   +8.20% (p=0.000 n=8)
AppendWithCreatedLine/AppendCreatedMetricLine-11                            7.652Mi ± 0%    8.263Mi ± 0%   +7.98% (p=0.000 n=8)
AppendWithCreatedLine/AppendWithCreatedLineWithAppendSTZeroSample-11        7.652Mi ± 0%    7.431Mi ± 0%   -2.89% (p=0.000 n=8)
geomean                                                                     17.49Mi         18.61Mi        +6.39%

                                                                     │ baseline.bench.txt │    new-branch-clean.bench.txt     │
                                                                     │     allocs/op      │   allocs/op     vs base           │
Append-11                                                                    110.1k ± 0%     130.1k ± 0%  +18.17% (p=0.000 n=8)
AppendHistogram-11                                                           110.1k ± 0%     130.1k ± 0%  +18.17% (p=0.000 n=8)
Commit/ClassicMetrics/Baseline-11                                            620.0k ± 0%     620.0k ± 0%        ~ (p=1.000 n=8) ¹
Commit/ClassicMetrics/WithTargetInfo-11                                      620.0k ± 0%     620.0k ± 0%        ~ (p=1.000 n=8) ¹
Commit/ClassicMetrics/WithScopeInfo-11                                       620.0k ± 0%     620.0k ± 0%        ~ (p=1.000 n=8) ¹
Commit/NativeHistogram/Baseline-11                                           650.0k ± 0%     650.0k ± 0%        ~ (p=1.000 n=8) ¹
Commit/NativeHistogram/WithTargetInfo-11                                     650.0k ± 0%     650.0k ± 0%        ~ (p=1.000 n=8) ¹
Commit/NativeHistogram/WithScopeInfo-11                                      650.0k ± 0%     650.0k ± 0%        ~ (p=1.000 n=8) ¹
AppendWithCreatedLine/AppendCreatedMetricLine-11                             120.1k ± 0%     160.1k ± 0%  +33.31% (p=0.000 n=8)
AppendWithCreatedLine/AppendWithCreatedLineWithAppendSTZeroSample-11         120.1k ± 0%     120.1k ± 0%        ~ (p=1.000 n=8) ¹
geomean                                                                      320.5k          341.1k        +6.41%

The results are the same! I just asked Cursor to adjust the output using Markdown tables.

Signed-off-by: perebaj <perebaj@gmail.com>
@ArthurSens
Copy link
Copy Markdown
Member

Thanks for the benchstat result! I know it's the same, but it's a lot easier to read since we're all used to it by now :)

I have some performance optimization ideas, but they will conflict with your PR. I was waiting for yours to get merged first 😬. I'll start opening them, and let's see if we can get these numbers to a good level

@perebaj
Copy link
Copy Markdown
Contributor Author

perebaj commented Apr 15, 2026

I did a last code review, especially in the function that I mentioned before. Now I'm more confident that I'm not screwing anything

@songy23 songy23 merged commit 8ddf356 into open-telemetry:main Apr 15, 2026
191 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ready to merge Code review completed; ready to merge by maintainers receiver/prometheus Prometheus receiver Skip Changelog PRs that do not require a CHANGELOG.md entry

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants