Skip to content

sdk/metric: Support specifying cardinality limits per instrument kinds#7855

Merged
dmathieu merged 38 commits intoopen-telemetry:mainfrom
petern48:per-instrument-cardinality-limits
Mar 20, 2026
Merged

sdk/metric: Support specifying cardinality limits per instrument kinds#7855
dmathieu merged 38 commits intoopen-telemetry:mainfrom
petern48:per-instrument-cardinality-limits

Conversation

@petern48
Copy link
Copy Markdown
Member

@petern48 petern48 commented Jan 31, 2026

Previously, we only had WithCardinalityLimit(), which adds a global cardinality limit.

This PR adds a new API on the reader WithCardinalityLimitSelector that can be used to specify limits per instrument kinds.

spec

schema

closes #7786

@codecov
Copy link
Copy Markdown

codecov bot commented Jan 31, 2026

Codecov Report

❌ Patch coverage is 91.66667% with 3 lines in your changes missing coverage. Please review.
✅ Project coverage is 81.7%. Comparing base (e604da5) to head (313de28).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
sdk/metric/reader.go 70.0% 3 Missing ⚠️
Additional details and impacted files

Impacted file tree graph

@@          Coverage Diff          @@
##            main   #7855   +/-   ##
=====================================
  Coverage   81.7%   81.7%           
=====================================
  Files        308     308           
  Lines      23632   23655   +23     
=====================================
+ Hits       19320   19343   +23     
- Misses      3928    3929    +1     
+ Partials     384     383    -1     
Files with missing lines Coverage Δ
sdk/metric/config.go 95.1% <ø> (ø)
sdk/metric/manual_reader.go 83.8% <100.0%> (+0.7%) ⬆️
sdk/metric/periodic_reader.go 87.0% <100.0%> (+0.2%) ⬆️
sdk/metric/pipeline.go 90.2% <100.0%> (+0.1%) ⬆️
sdk/metric/reader.go 93.6% <70.0%> (-6.4%) ⬇️

... and 2 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@petern48 petern48 force-pushed the per-instrument-cardinality-limits branch from fd48f36 to 56c399f Compare January 31, 2026 05:26
@petern48 petern48 changed the title Support specifying cardinality limits for different instrument kinds in metrics sdk sdk/metric: Support specifying cardinality limits per instrument kinds Jan 31, 2026
@petern48 petern48 marked this pull request as ready for review January 31, 2026 05:46
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.

This does not follow what is in the specification.

If there is no matching view, but the MetricReader defines a default
cardinality limit value based on the instrument an aggregation is created
for, that value SHOULD be used.

This does not suggest that the metric reader needs configuration allowing the cardinality limit to be changed per-instrument-kind. It only suggests that the default value chosen by the SDK can be based on the instrument.

The correct specification for this configuration is here

aggregation_cardinality_limit: A positive integer value defining the
maximum number of data points allowed to be emitted in a collection cycle by
a single instrument. See cardinality limits, below.

Users can provide an aggregation_cardinality_limit, but it is up to their
discretion. Therefore, the stream configuration parameter needs to be
structured to accept an aggregation_cardinality_limit, but MUST NOT
obligate a user to provide one. If the user does not provide an
aggregation_cardinality_limit value, the MeterProvider MUST apply the
default aggregation cardinality limit the MetricReader is
configured with.

@dashpole
Copy link
Copy Markdown
Contributor

dashpole commented Feb 2, 2026

I've opened open-telemetry/opentelemetry-configuration#524 to fix this in the configuration.

@petern48
Copy link
Copy Markdown
Member Author

petern48 commented Feb 2, 2026

Got it, thanks. I largely just blindly followed the issue, but I definitely also felt it was strange based on the spec. Left a comment on the issue you created, we'll see where it goes, considering other sdks have implemented it.

@dashpole
Copy link
Copy Markdown
Contributor

Ok, so this needs to be configuration on the metric reader, not the MeterProvider.

See https://github.com/open-telemetry/opentelemetry-specification/blame/49845849d2d8df07059f82033f39e96c561927cf/specification/metrics/sdk.md#L1282.

  • The default aggregation cardinality limit (optional) to use, a function of instrument kind. If not configured, a default value of 2000 SHOULD be used.

So this should be a function that takes an instrument kind, and returns a cardinality limit.

@petern48
Copy link
Copy Markdown
Member Author

gentle bump @dashpole. Could you review again?

@petern48 petern48 force-pushed the per-instrument-cardinality-limits branch from 8338181 to c5471d9 Compare March 12, 2026 18:40
@petern48
Copy link
Copy Markdown
Member Author

Three approvals already. Are we waiting on anything else before merging?

@dmathieu dmathieu merged commit 015ed1a into open-telemetry:main Mar 20, 2026
33 checks passed
@petern48 petern48 deleted the per-instrument-cardinality-limits branch March 20, 2026 14:39
@pellared pellared added this to the v1.43.0 milestone Apr 1, 2026
dmathieu added a commit that referenced this pull request Apr 3, 2026
Release issue:
#8127

## Added

- Add `IsRandom` and `WithRandom` on `TraceFlags`, and `IsRandom` on
`SpanContext` in `go.opentelemetry.io/otel/trace`
for [W3C Trace Context Level 2 Random Trace ID
Flag](https://www.w3.org/TR/trace-context-2/#random-trace-id-flag)
support. (#8012)
- Add service detection with `WithService` in
`go.opentelemetry.io/otel/sdk/resource`. (#7642)
- Add `DefaultWithContext` and `EnvironmentWithContext` in
`go.opentelemetry.io/otel/sdk/resource` to support plumbing
`context.Context` through default and environment detectors. (#8051)
- Support attributes with empty value (`attribute.EMPTY`) in
`go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc`.
(#8038)
- Support attributes with empty value (`attribute.EMPTY`) in
`go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc`.
(#8038)
- Support attributes with empty value (`attribute.EMPTY`) in
`go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc`. (#8038)
- Support attributes with empty value (`attribute.EMPTY`) in
`go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp`.
(#8038)
- Support attributes with empty value (`attribute.EMPTY`) in
`go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp`.
(#8038)
- Support attributes with empty value (`attribute.EMPTY`) in
`go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp`. (#8038)
- Support attributes with empty value (`attribute.EMPTY`) in
`go.opentelemetry.io/otel/sdk/metric/metricdata/metricdatatest`. (#8038)
- Add support for per-series start time tracking for cumulative metrics
in `go.opentelemetry.io/otel/sdk/metric`.
  Set `OTEL_GO_X_PER_SERIES_START_TIMESTAMPS=true` to enable. (#8060)
- Add `WithCardinalityLimitSelector` for metric reader for configuring
cardinality limits specific to the instrument kind. (#7855)

## Changed

- Introduce the `EMPTY` Type in `go.opentelemetry.io/otel/attribute` to
reflect that an empty value is now a valid value, with `INVALID`
remaining as a deprecated alias of `EMPTY`. (#8038)
- Refactor slice handling in `go.opentelemetry.io/otel/attribute` to
optimize short slice values with fixed-size fast paths. (#8039)
- Improve performance of span metric recording in
`go.opentelemetry.io/otel/sdk/trace` by returning early if
self-observability is not enabled. (#8067)
- Improve formatting of metric data diffs in
`go.opentelemetry.io/otel/sdk/metric/metricdata/metricdatatest`. (#8073)

## Deprecated

- Deprecate `INVALID` in `go.opentelemetry.io/otel/attribute`. Use
`EMPTY` instead. (#8038)

## Fixed

- Return spec-compliant `TraceIdRatioBased` description. This is a
breaking behavioral change, but it is necessary to
make the implementation
[spec-compliant](https://opentelemetry.io/docs/specs/otel/trace/sdk/#traceidratiobased).
(#8027)
- Fix a race condition in `go.opentelemetry.io/otel/sdk/metric` where
the lastvalue aggregation could collect the value 0 even when no
zero-value measurements were recorded. (#8056)
- Limit HTTP response body to 4 MiB in
`go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp` to
mitigate excessive memory usage caused by a misconfigured or malicious
server.
Responses exceeding the limit are treated as non-retryable errors.
(#8108)
- Limit HTTP response body to 4 MiB in
`go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp` to
mitigate excessive memory usage caused by a misconfigured or malicious
server.
Responses exceeding the limit are treated as non-retryable errors.
(#8108)
- Limit HTTP response body to 4 MiB in
`go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp` to
mitigate excessive memory usage caused by a misconfigured or malicious
server.
Responses exceeding the limit are treated as non-retryable errors.
(#8108)
- `WithHostID` detector in `go.opentelemetry.io/otel/sdk/resource` to
use full path for `kenv` command on BSD. (#8113)
- Fix missing `request.GetBody` in
`go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp` to
correctly handle HTTP2 GOAWAY frame. (#8096)

---------

Co-authored-by: Tyler Yahn <MrAlias@users.noreply.github.com>
Sign up for free to 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.

WithCardinalityLimit should provide per instrument configuration

5 participants