Skip to content

Refine guidance on providing attributes at span creation time#4879

Draft
cijothomas wants to merge 1 commit intoopen-telemetry:mainfrom
cijothomas:refine-span-creation-attributes-guidance
Draft

Refine guidance on providing attributes at span creation time#4879
cijothomas wants to merge 1 commit intoopen-telemetry:mainfrom
cijothomas:refine-span-creation-attributes-guidance

Conversation

@cijothomas
Copy link
Member

@cijothomas cijothomas commented Feb 7, 2026

Changes

The current spec gives a blanket preference for providing attributes at span creation for samplers. However, no built-in sampler actually examines attributes — AlwaysOn, AlwaysOff, TraceIdRatioBased, ParentBased, and ProbabilitySampler all ignore them. Eagerly collecting attributes (URL parsing, string ops, Vec/array allocation) for spans that get dropped is wasted work.

This PR replaces the blanket preference with balanced guidance: provide cheap/readily-available attributes at creation (to support custom head-based samplers), but defer expensive attribute computation until after creation, guarded by IsRecording().

.NET instrumentations already follow this guidance - they don't provide attributes at startup time unless they are readily available. I am now adding Rust instrumentations where the costs of providing attributes before sampling is quite high. Hence trying to see if we can balance the wording in the spec.

For non-trivial changes, follow the change proposal process.

  • Related issues #
  • Related OTEP(s) #
  • Links to the prototypes (when adding or changing features)
  • CHANGELOG.md file updated for non-trivial changes
    • For trivial changes, include [chore] in the PR title to skip the changelog check
  • Spec compliance matrix updated if necessary

them for spans that are ultimately dropped is wasted. Instrumentations
MAY defer expensive attribute computation until after span creation,
guarded by [`IsRecording`](#isrecording), to avoid unnecessary overhead
when spans are not being recorded.
Copy link

Choose a reason for hiding this comment

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

+1 on encouraging instrumentation providers to use judgement on when span attributes are provided rather than assuming that eagerly provided attributes are always preferable. In core .NET libraries we often concluded that eagerly provided attributes are not preferred. .NET tries to encourage "pay for play" performance characteristics - we want only the users who enable a feature to pay its performance costs whenever possible.

Copy link
Member

Choose a reason for hiding this comment

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

just to rope @jmacd into the discussion 😄

#1916 (comment)

Copy link
Member Author

Choose a reason for hiding this comment

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

That "lazy" thing is something I am exploring in OTel Rust. The instrumentations in Rust are extremely bad in terms of performance and a lot of it is due to eagerly passing attributes upfront!

The API documentation MUST state that adding attributes at span creation is preferred
to calling `SetAttribute` later, as samplers can only consider information
already present during span creation.
Attributes provided at span creation time are the only attributes available
Copy link
Member Author

Choose a reason for hiding this comment

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

TODO: see if https://github.com/open-telemetry/semantic-conventions/blob/main/docs/http/http-spans.md needs tweaking as well, as it has SHOULD on providing a set of attributes at Span creation time.

- Collecting attribute values can be expensive (e.g., URL parsing, string
formatting). When the configured `Sampler` does not consider attributes —
as is the case for all built-in samplers — the cost of eagerly computing
them for spans that are ultimately dropped is wasted. Instrumentations
Copy link
Member

Choose a reason for hiding this comment

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

I believe it's common in semconv that sampling-relevant attributes are the same that you'd use on metrics, so not collecting them only helps when metrics are disabled

Copy link
Member Author

Choose a reason for hiding this comment

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

Depends!
For duration metric, which is the most common one - that is reported when request is ending only. SpanCreation attribute are at request start time.

Also, in languages like Rust/,NET, metric attributes can be provided via stack allocated arrays, but Span/Trace requires ownership (i.e Heap allocated vectors/arrays/Tags).
Something we are trying to improve in parallel.

Copy link
Member Author

Choose a reason for hiding this comment

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

My goal is not to drastically change the guidance, but add some note like "Use judgement when providing all attributes eagerly vs after-sampling-decision-is-known"

So that .NET (and upcoming Rust) implementations are not considered non-compliant with the OTel semantic conventions)

Copy link
Member

@lmolkova lmolkova Feb 11, 2026

Choose a reason for hiding this comment

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

they would not be strictly compliant because conventions define which attributes SHOULD be provided at start time https://github.com/open-telemetry/semantic-conventions/blob/99f629fec1a9e14a43a33ba8cc5ca7987e7c13f8/docs/http/http-spans.md?plain=1#L300-L306

I don't mind relaxing guidance here for manual, non-semconv instrumentations, but we already applied judgement in semconv for common ones.

Copy link
Member Author

Choose a reason for hiding this comment

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

agree. The ones recommended by SemConv to be provided at startup is quite reasonable and readily available ones only.

@github-actions
Copy link

This PR was marked stale. It will be closed in 14 days without additional activity.

@github-actions github-actions bot added the Stale label Mar 12, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants