Skip to content

Allow duplicate metric names - #1728

Closed
jaydeluca wants to merge 12 commits into
mainfrom
allow-dup-names-2
Closed

Allow duplicate metric names#1728
jaydeluca wants to merge 12 commits into
mainfrom
allow-dup-names-2

Conversation

@jaydeluca

@jaydelucajaydeluca commented Dec 8, 2025

Copy link
Copy Markdown
Member

Resolves#696

The goal of this change is to be able to have multiple metrics with the same name but different labels, which had previously been prevented by a check during registration.

While implementing this, I operated under a few assumptions:

  • We will allow metrics with different labels to have the same name, but scraping metrics with the same name and same labels results in an exception
  • Metrics with the same name but different metric types will result in an exception
  • Metrics with the same name but different labels should all be merged under a single HELP/TYPE heading

I originally attempted to implement the validation during metric registration, but that required doing some things that felt wrong, so I moved the validation to scrape time. This does result in a bit of a performance hit (~10% reduction in op/s in the benchmarks I ran) on the scrape operation.

The benchmarks I ran were on an apple M4. I did 4 runs total - 2 of the main branch for a baseline and 2 for this feature branch and then averaged them.

Benchmark results

TextFormatUtilBenchmark

BenchmarkMain #1Main #2Feature #1Feature #2Main AvgFeature Avg
openMetricsWriteToByteArray1,179,213 ± 5,9591,170,787 ± 5,5791,080,037 ± 5,8361,068,906 ± 5,2881,175,0001,074,471
openMetricsWriteToNull1,197,768 ± 16,5131,191,845 ± 13,8971,083,832 ± 3,8731,076,979 ± 4,8161,194,8061,080,406
prometheusWriteToByteArray1,281,014 ± 21,4371,273,552 ± 26,8891,144,375 ± 3,3031,138,252 ± 5,7441,277,2831,141,313
prometheusWriteToNull1,254,177 ± 7,5131,308,925 ± 14,3261,167,007 ± 6,1831,152,662 ± 2,5651,281,5511,159,835

CounterBenchmark

BenchmarkMain #1Main #2Feature #1Feature #2Main AvgFeature Avg
codahaleIncNoLabels71,040 ± 1,67681,355 ± 9,28787,105 ± 8,19378,829 ± 12,37076,19782,967
openTelemetryAdd1,472 ± 381,350 ± 391,419 ± 571,350 ± 391,4111,384
openTelemetryInc1,437 ± 451,361 ± 821,389 ± 501,349 ± 681,3991,369
openTelemetryIncNoLabels1,521 ± 421,347 ± 881,330 ± 1031,419 ± 741,4341,375
prometheusAdd84,285 ± 10284,233 ± 7984,015 ± 7984,255 ± 2884,25984,135
prometheusInc85,739 ± 16086,172 ± 22585,484 ± 6886,128 ± 11385,95685,806
prometheusNoLabelsInc85,586 ± 24286,075 ± 6585,385 ± 5285,954 ± 5785,83085,669
simpleclientAdd8,730 ± 1,4299,114 ± 1,3628,003 ± 7339,200 ± 1,2028,9228,602
simpleclientInc7,655 ± 79810,469 ± 1,6359,201 ± 1,4769,746 ± 1,1259,0629,473
simpleclientNoLabelsInc8,328 ± 9089,124 ± 8477,951 ± 8159,988 ± 7658,7268,970

HistogramBenchmark

BenchmarkMain #1Main #2Feature #1Feature #2Main AvgFeature Avg
openTelemetryClassic780 ± 66932 ± 75794 ± 12841 ± 98856817
openTelemetryExponential737 ± 65764 ± 96732 ± 68725 ± 51751729
prometheusClassic3,844 ± 633,886 ± 1174,080 ± 1373,865 ± 623,8653,973
prometheusNative2,829 ± 2452,933 ± 732,961 ± 1482,969 ± 982,8812,965
simpleclient15,192 ± 1,91411,926 ± 1,20914,669 ± 39515,781 ± 1,36513,55915,225

@jaydeluca
jaydelucaforce-pushed the allow-dup-names-2 branch 7 times, most recently from b9e17cf to 97348f6CompareDecember 9, 2025 14:22

@zeitlingerzeitlinger left a comment

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.

great 😄

@jaydeluca
jaydelucaforce-pushed the allow-dup-names-2 branch 2 times, most recently from 509709c to f56241eCompareDecember 11, 2025 21:08
@jaydelucajaydeluca changed the title Allow duplicate metric names (WIP)Allow duplicate metric namesDec 26, 2025
Signed-off-by: Jay DeLuca <jaydeluca4@gmail.com>
Signed-off-by: Jay DeLuca <jaydeluca4@gmail.com>
Signed-off-by: Jay DeLuca <jaydeluca4@gmail.com>
Signed-off-by: Jay DeLuca <jaydeluca4@gmail.com>
Signed-off-by: Jay DeLuca <jaydeluca4@gmail.com>
Signed-off-by: Jay DeLuca <jaydeluca4@gmail.com>
Signed-off-by: Jay DeLuca <jaydeluca4@gmail.com>
Signed-off-by: Jay DeLuca <jaydeluca4@gmail.com>
@jaydeluca
jaydeluca marked this pull request as ready for review December 26, 2025 20:29

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR enables multiple metrics with the same Prometheus name but different label sets to coexist, addressing a limitation where duplicate metric names were previously rejected at registration time. The validation has been moved from registration to scrape time, where it now checks for type consistency and unique label combinations. During exposition, metrics with the same name are merged under a single HELP/TYPE declaration.

Key changes:

  • Registration no longer rejects duplicate metric names; validation occurs at scrape time
  • Metrics with the same name but different types or duplicate label sets throw exceptions at scrape time
  • Exposition formats merge duplicate metric names into single metric families with combined data points

Reviewed changes

Copilot reviewed 16 out of 16 changed files in this pull request and generated 6 comments.

Show a summary per file
FileDescription
PrometheusRegistry.javaRemoved duplicate name checking at registration time and during scrape
Collector.javaUpdated documentation to remove reference to registration-time name checking
MultiCollector.javaUpdated documentation to remove reference to registration-time name checking
MetricSnapshots.javaAdded validation logic for type consistency and duplicate label detection at construction time
TextFormatUtil.javaAdded mergeDuplicates() method to combine snapshots with the same Prometheus name
PrometheusTextFormatWriter.javaIntegrated mergeDuplicates() to ensure single HELP/TYPE per metric family
OpenMetricsTextFormatWriter.javaIntegrated mergeDuplicates() for OpenMetrics format
PrometheusProtobufWriterImpl.javaIntegrated mergeDuplicates() for protobuf format
PrometheusRegistryTest.javaAdded comprehensive tests for duplicate name scenarios
TextFormatUtilTest.javaAdded tests for the mergeDuplicates functionality
DuplicateNamesExpositionTest.javaNew test file validating duplicate names in text formats
DuplicateNamesProtobufTest.javaNew test file validating duplicate names in protobuf format
DuplicateMetricsIT.javaNew integration test for end-to-end duplicate metrics validation
DuplicateMetricsSample.javaNew sample application demonstrating duplicate metrics usage
pom.xml filesAdded new test module to build configuration

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Signed-off-by: Jay DeLuca <jaydeluca4@gmail.com>
Signed-off-by: Jay DeLuca <jaydeluca4@gmail.com>
Signed-off-by: Jay DeLuca <jaydeluca4@gmail.com>
@jaydeluca

Copy link
Copy Markdown
MemberAuthor

closing in favor of #1800

zeitlinger pushed a commit that referenced this pull request Feb 5, 2026
Closes#696
Alternate approach to #1728 Validation occurs at registration time:
- Metrics with the same name, type, unit, and help - but different
labels, are allowed to be registered
- Custom Collectors that do not implement the required fields
(prometheus name, metric type) will skip validation and could risk
creating duplicate series that will cause issues at scrape time.
- I looked into adding a fallback, but it requires calling `collect()`
at registration in order to introspect existing metadata and that seemed
not great due to potential side effects
---------
Signed-off-by: Jay DeLuca <jaydeluca4@gmail.com>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Same metric name, different set of label names

3 participants

@jaydeluca@zeitlinger