[SDK] Span limits configuration#4232
Conversation
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #4232 +/- ##
==========================================
- Coverage 82.79% 78.22% -4.56%
==========================================
Files 415 440 +25
Lines 17452 18653 +1201
==========================================
+ Hits 14447 14589 +142
- Misses 3005 4064 +1059
🚀 New features to boost your workflow:
|
…4 and shared libs. fix lambda capture issue in test
dbarker
left a comment
There was a problem hiding this comment.
Sharing some benchmark results and brief analysis. Overall positive for including span limits in TracerProvider and applying to SpanData and OtlpRecordable.
| @@ -93,22 +160,60 @@ void SpanData::SetIdentity(const opentelemetry::trace::SpanContext &span_context | |||
| void SpanData::SetAttribute(nostd::string_view key, | |||
There was a problem hiding this comment.
Span limits performance comparison with #4203
Adding SpanLimits to the SpanData recording hot path (this PR #4232) results in the same or better recording performance compared to the baseline from #4203. Recording a nominal span (6 mixed type attributes) sees a ~10% reduction in mean recording time (span start to span end).
The following table shows mean span start/end times and CV results from span_data_benchmark runs with #4203 (baseline) and #4232 (w/SpanLimits). The full baseline results in #4203 are here and results from this PR are below.
The benchmark covers recording multiple spans with SpanData including: a minimal span (no attributes, events, or links), a nominal span with 6 attributes, and a sweep through the range of span attribute, link, and event counts up to the spec default limits.
Both benchmark runs use the CMake configuration posted below (C++17, Release, nostd types).
| Benchmark | Baseline PR (ns) | SpanLimits PR (ns) | % Difference | CV (baseline) | CV (SpanLimits) |
|---|---|---|---|---|---|
RecordMinimalSpan |
341 | 330 | −3% | 0.28% | 0.86% |
RecordNominalSpan |
581 | 516 | −11% | 2.63% | 0.46% |
RecordSpanWithAttributes / count:1 |
390 | 370 | −5% | 1.07% | 0.28% |
RecordSpanWithAttributes / count:10 |
705 | 636 | −10% | 0.90% | 0.56% |
RecordSpanWithAttributes / count:128 |
7479 | 6525 | −13% | 2.53% | 1.35% |
RecordSpanWithEvents / count:1 |
456 | 437 | −4% | 0.63% | 0.24% |
RecordSpanWithEvents / count:10 |
1584 | 1409 | −11% | 1.54% | 1.48% |
RecordSpanWithEvents / count:128 |
16434 | 14633 | −11% | 1.28% | 3.75% |
RecordSpanWithLinks / count:1 |
435 | 421 | −3% | 0.49% | 0.82% |
RecordSpanWithLinks / count:10 |
1368 | 1310 | −4% | 1.63% | 1.48% |
RecordSpanWithLinks / count:128 |
15304 | 12753 | −17% | 6.08% | 0.56% |
Note: C++14 performance will degrade from C++17 due to the lack of insert_or_assign to set attributes on the SpanData recordable. The OtlpRecordable had span limits enforced in the hot recording path in a prior release and its recording performance is largely unaffected by this PR.
CMake Configuration
-- ---------------------------------------------
-- build settings
-- ---------------------------------------------
-- OpenTelemetry VERSION: 1.28.0-dev
-- OpenTelemetry ABI: 2
-- CMAKE_SYSTEM_PROCESSOR: x86_64
-- CXX: GNU 13.3.0
-- CMAKE_BUILD_TYPE: Release
-- CXXFLAGS:
-- CMAKE_CXX_STANDARD: 17
-- CMAKE_TOOLCHAIN_FILE:
-- BUILD_SHARED_LIBS:
-- ---------------------------------------------
-- opentelemetry-cpp build options
-- ---------------------------------------------
-- WITH_API_ONLY: OFF
-- WITH_NO_DEPRECATED_CODE: ON
-- WITH_ABI_VERSION_1: OFF
-- WITH_ABI_VERSION_2: ON
-- OTELCPP_VERSIONED_LIBS: OFF
-- OTELCPP_MAINTAINER_MODE: ON
-- WITH_STL: OFF
-- WITH_GSL: OFF
-- WITH_NO_GETENV: OFF
-- OPENTELEMETRY_INSTALL: ON
-- ---------------------------------------------
-- opentelemetry-cpp cmake component options
-- ---------------------------------------------
-- WITH_OTLP_GRPC: ON
-- WITH_OTLP_HTTP: ON
-- WITH_OTLP_FILE: ON
-- WITH_HTTP_CLIENT_CURL: ON
-- WITH_ZIPKIN: ON
-- WITH_PROMETHEUS: ON
-- WITH_ELASTICSEARCH: ON
-- WITH_OPENTRACING: OFF
-- WITH_ETW:
-- OPENTELEMETRY_BUILD_DLL:
-- WITH_CONFIGURATION: ON
-- ---------------------------------------------
-- feature preview options
-- ---------------------------------------------
-- WITH_ASYNC_EXPORT_PREVIEW: OFF
-- WITH_THREAD_INSTRUMENTATION_PREVIEW: ON
-- WITH_METRICS_EXEMPLAR_PREVIEW: ON
-- WITH_OTLP_GRPC_SSL_MTLS_PREVIEW: ON
-- WITH_OTLP_GRPC_CREDENTIAL_PREVIEW: ON
-- WITH_OTLP_RETRY_PREVIEW: ON
-- WITH_METRICS_BOUND_INSTRUMENTS_PREVIEW: ON
-- ---------------------------------------------
-- third-party options
-- ---------------------------------------------
-- WITH_NLOHMANN_JSON: ON
-- WITH_CURL_LOGGING: ON
-- WITH_OTLP_HTTP_COMPRESSION: ON
-- ---------------------------------------------
-- versions
-- ---------------------------------------------
-- CMake: 3.28.3
-- GTest: 1.17.0 (find_package)
-- benchmark: 1.9.4 (find_package)
-- Abseil: 20250512
-- opentelemetry-proto: 1.10.0 (fetch_source)
-- Protobuf: 33.6.0 (find_package - STATIC_LIBRARY)
-- gRPC: 1.81.1 (find_package - STATIC_LIBRARY)
-- CURL: 8.21.0-DEV (find_package)
-- ZLIB: 1.3.2 (find_package)
-- nlohmann-json: 3.12.0 (find_package)
-- prometheus-cpp: 1.3.0 (find_package)
-- ryml: 0.12.1 (find_package)
-- ---------------------------------------------
Benchmark run with SpanLimits from this PR
~/build/sdk/test/trace/span_data_benchmark --benchmark_repetitions=5 --benchmark_display_aggregates_only=true
2026-07-09T21:52:28+00:00
Running /home/devuser/build/sdk/test/trace/span_data_benchmark
Run on (32 X 5697.01 MHz CPU s)
CPU Caches:
L1 Data 48 KiB (x16)
L1 Instruction 32 KiB (x16)
L2 Unified 2048 KiB (x16)
L3 Unified 36864 KiB (x1)
Load Average: 0.63, 1.28, 2.33
***WARNING*** ASLR is enabled, the results may have unreproducible noise in them.
--------------------------------------------------------------------------------------------------------------
Benchmark Time CPU Iterations
--------------------------------------------------------------------------------------------------------------
SpanDataFixture/RecordMinimalSpan_mean 330 ns 331 ns 5
SpanDataFixture/RecordMinimalSpan_median 328 ns 330 ns 5
SpanDataFixture/RecordMinimalSpan_stddev 2.82 ns 2.98 ns 5
SpanDataFixture/RecordMinimalSpan_cv 0.86 % 0.90 % 5
SpanDataFixture/RecordNominalSpan_mean 516 ns 517 ns 5
SpanDataFixture/RecordNominalSpan_median 514 ns 516 ns 5
SpanDataFixture/RecordNominalSpan_stddev 2.37 ns 2.40 ns 5
SpanDataFixture/RecordNominalSpan_cv 0.46 % 0.46 % 5
SpanDataFixture/RecordSpanWithAttributes/attribute_count:1_mean 370 ns 372 ns 5 items_per_second=2.68631M/s
SpanDataFixture/RecordSpanWithAttributes/attribute_count:1_median 370 ns 372 ns 5 items_per_second=2.68728M/s
SpanDataFixture/RecordSpanWithAttributes/attribute_count:1_stddev 1.03 ns 1.00 ns 5 items_per_second=7.23475k/s
SpanDataFixture/RecordSpanWithAttributes/attribute_count:1_cv 0.28 % 0.27 % 5 items_per_second=0.27%
SpanDataFixture/RecordSpanWithAttributes/attribute_count:10_mean 636 ns 638 ns 5 items_per_second=15.6774M/s
SpanDataFixture/RecordSpanWithAttributes/attribute_count:10_median 636 ns 639 ns 5 items_per_second=15.6583M/s
SpanDataFixture/RecordSpanWithAttributes/attribute_count:10_stddev 3.54 ns 3.36 ns 5 items_per_second=82.5446k/s
SpanDataFixture/RecordSpanWithAttributes/attribute_count:10_cv 0.56 % 0.53 % 5 items_per_second=0.53%
SpanDataFixture/RecordSpanWithAttributes/attribute_count:128_mean 6525 ns 6530 ns 5 items_per_second=19.6059M/s
SpanDataFixture/RecordSpanWithAttributes/attribute_count:128_median 6469 ns 6474 ns 5 items_per_second=19.7719M/s
SpanDataFixture/RecordSpanWithAttributes/attribute_count:128_stddev 88.4 ns 89.0 ns 5 items_per_second=265.011k/s
SpanDataFixture/RecordSpanWithAttributes/attribute_count:128_cv 1.35 % 1.36 % 5 items_per_second=1.35%
SpanDataFixture/RecordSpanWithEvents/event_count:1_mean 437 ns 438 ns 5 items_per_second=2.28259M/s
SpanDataFixture/RecordSpanWithEvents/event_count:1_median 437 ns 438 ns 5 items_per_second=2.28233M/s
SpanDataFixture/RecordSpanWithEvents/event_count:1_stddev 1.06 ns 1.01 ns 5 items_per_second=5.28885k/s
SpanDataFixture/RecordSpanWithEvents/event_count:1_cv 0.24 % 0.23 % 5 items_per_second=0.23%
SpanDataFixture/RecordSpanWithEvents/event_count:10_mean 1409 ns 1410 ns 5 items_per_second=7.095M/s
SpanDataFixture/RecordSpanWithEvents/event_count:10_median 1402 ns 1403 ns 5 items_per_second=7.12763M/s
SpanDataFixture/RecordSpanWithEvents/event_count:10_stddev 20.8 ns 20.5 ns 5 items_per_second=101.53k/s
SpanDataFixture/RecordSpanWithEvents/event_count:10_cv 1.48 % 1.45 % 5 items_per_second=1.43%
SpanDataFixture/RecordSpanWithEvents/event_count:128_mean 14633 ns 14634 ns 5 items_per_second=8.75625M/s
SpanDataFixture/RecordSpanWithEvents/event_count:128_median 14419 ns 14417 ns 5 items_per_second=8.87853M/s
SpanDataFixture/RecordSpanWithEvents/event_count:128_stddev 549 ns 550 ns 5 items_per_second=313.509k/s
SpanDataFixture/RecordSpanWithEvents/event_count:128_cv 3.75 % 3.76 % 5 items_per_second=3.58%
SpanDataFixture/RecordSpanWithLinks/link_count:1_mean 421 ns 422 ns 5 items_per_second=2.36704M/s
SpanDataFixture/RecordSpanWithLinks/link_count:1_median 422 ns 424 ns 5 items_per_second=2.35949M/s
SpanDataFixture/RecordSpanWithLinks/link_count:1_stddev 3.47 ns 3.64 ns 5 items_per_second=20.4602k/s
SpanDataFixture/RecordSpanWithLinks/link_count:1_cv 0.82 % 0.86 % 5 items_per_second=0.86%
SpanDataFixture/RecordSpanWithLinks/link_count:10_mean 1310 ns 1310 ns 5 items_per_second=7.63408M/s
SpanDataFixture/RecordSpanWithLinks/link_count:10_median 1312 ns 1312 ns 5 items_per_second=7.62065M/s
SpanDataFixture/RecordSpanWithLinks/link_count:10_stddev 19.4 ns 19.2 ns 5 items_per_second=111.236k/s
SpanDataFixture/RecordSpanWithLinks/link_count:10_cv 1.48 % 1.47 % 5 items_per_second=1.46%
SpanDataFixture/RecordSpanWithLinks/link_count:128_mean 12753 ns 12754 ns 5 items_per_second=10.0361M/s
SpanDataFixture/RecordSpanWithLinks/link_count:128_median 12732 ns 12732 ns 5 items_per_second=10.053M/s
SpanDataFixture/RecordSpanWithLinks/link_count:128_stddev 72.0 ns 71.9 ns 5 items_per_second=56.2889k/s
SpanDataFixture/RecordSpanWithLinks/link_count:128_cv 0.56 % 0.56 % 5 items_per_second=0.56%
| #include "opentelemetry/nostd/string_view.h" | ||
| #include "opentelemetry/sdk/instrumentationscope/instrumentation_scope.h" | ||
| #include "opentelemetry/sdk/resource/resource.h" | ||
| #include "opentelemetry/sdk/trace/span_limits.h" |
There was a problem hiding this comment.
OtlpRecordable benchmark performance is the same or slightly better compared to the baseline from #4203 here. This is expected since OtlpRecordable enforces span limits in the baseline also.
~/build/exporters/otlp/otlp_recordable_benchmark --benchmark_repetitions=5 --benchmark_display_aggregates_only=true
2026-07-09T22:48:17+00:00
Running /home/devuser/build/exporters/otlp/otlp_recordable_benchmark
Run on (32 X 5700 MHz CPU s)
CPU Caches:
L1 Data 48 KiB (x16)
L1 Instruction 32 KiB (x16)
L2 Unified 2048 KiB (x16)
L3 Unified 36864 KiB (x1)
Load Average: 3.28, 3.82, 2.16
***WARNING*** ASLR is enabled, the results may have unreproducible noise in them.
--------------------------------------------------------------------------------------------------------------------
Benchmark Time CPU Iterations
--------------------------------------------------------------------------------------------------------------------
OtlpRecordableFixture/RecordMinimalSpan_mean 351 ns 352 ns 5
OtlpRecordableFixture/RecordMinimalSpan_median 351 ns 353 ns 5
OtlpRecordableFixture/RecordMinimalSpan_stddev 2.65 ns 2.72 ns 5
OtlpRecordableFixture/RecordMinimalSpan_cv 0.76 % 0.77 % 5
OtlpRecordableFixture/RecordNominalSpan_mean 615 ns 616 ns 5
OtlpRecordableFixture/RecordNominalSpan_median 610 ns 611 ns 5
OtlpRecordableFixture/RecordNominalSpan_stddev 14.3 ns 14.6 ns 5
OtlpRecordableFixture/RecordNominalSpan_cv 2.32 % 2.37 % 5
OtlpRecordableFixture/RecordSpanWithAttributes/attribute_count:1_mean 390 ns 392 ns 5 items_per_second=2.55168M/s
OtlpRecordableFixture/RecordSpanWithAttributes/attribute_count:1_median 391 ns 392 ns 5 items_per_second=2.55133M/s
OtlpRecordableFixture/RecordSpanWithAttributes/attribute_count:1_stddev 0.703 ns 0.779 ns 5 items_per_second=5.07365k/s
OtlpRecordableFixture/RecordSpanWithAttributes/attribute_count:1_cv 0.18 % 0.20 % 5 items_per_second=0.20%
OtlpRecordableFixture/RecordSpanWithAttributes/attribute_count:10_mean 867 ns 868 ns 5 items_per_second=11.5241M/s
OtlpRecordableFixture/RecordSpanWithAttributes/attribute_count:10_median 863 ns 863 ns 5 items_per_second=11.5835M/s
OtlpRecordableFixture/RecordSpanWithAttributes/attribute_count:10_stddev 16.9 ns 17.3 ns 5 items_per_second=224.052k/s
OtlpRecordableFixture/RecordSpanWithAttributes/attribute_count:10_cv 1.95 % 1.99 % 5 items_per_second=1.94%
OtlpRecordableFixture/RecordSpanWithAttributes/attribute_count:128_mean 7492 ns 7496 ns 5 items_per_second=17.297M/s
OtlpRecordableFixture/RecordSpanWithAttributes/attribute_count:128_median 7005 ns 7010 ns 5 items_per_second=18.2586M/s
OtlpRecordableFixture/RecordSpanWithAttributes/attribute_count:128_stddev 965 ns 965 ns 5 items_per_second=2.13971M/s
OtlpRecordableFixture/RecordSpanWithAttributes/attribute_count:128_cv 12.89 % 12.88 % 5 items_per_second=12.37%
OtlpRecordableFixture/RecordSpanWithEvents/event_count:1_mean 474 ns 476 ns 5 items_per_second=2.10221M/s
OtlpRecordableFixture/RecordSpanWithEvents/event_count:1_median 474 ns 476 ns 5 items_per_second=2.10201M/s
OtlpRecordableFixture/RecordSpanWithEvents/event_count:1_stddev 1.25 ns 1.21 ns 5 items_per_second=5.33549k/s
OtlpRecordableFixture/RecordSpanWithEvents/event_count:1_cv 0.26 % 0.25 % 5 items_per_second=0.25%
OtlpRecordableFixture/RecordSpanWithEvents/event_count:10_mean 1649 ns 1652 ns 5 items_per_second=6.05453M/s
OtlpRecordableFixture/RecordSpanWithEvents/event_count:10_median 1649 ns 1652 ns 5 items_per_second=6.05326M/s
OtlpRecordableFixture/RecordSpanWithEvents/event_count:10_stddev 3.75 ns 3.69 ns 5 items_per_second=13.5277k/s
OtlpRecordableFixture/RecordSpanWithEvents/event_count:10_cv 0.23 % 0.22 % 5 items_per_second=0.22%
OtlpRecordableFixture/RecordSpanWithEvents/event_count:128_mean 16709 ns 16711 ns 5 items_per_second=7.65969M/s
OtlpRecordableFixture/RecordSpanWithEvents/event_count:128_median 16658 ns 16662 ns 5 items_per_second=7.68232M/s
OtlpRecordableFixture/RecordSpanWithEvents/event_count:128_stddev 93.2 ns 92.5 ns 5 items_per_second=42.3267k/s
OtlpRecordableFixture/RecordSpanWithEvents/event_count:128_cv 0.56 % 0.55 % 5 items_per_second=0.55%
OtlpRecordableFixture/RecordSpanWithLinks/link_count:1_mean 491 ns 495 ns 5 items_per_second=2.02101M/s
OtlpRecordableFixture/RecordSpanWithLinks/link_count:1_median 492 ns 495 ns 5 items_per_second=2.02057M/s
OtlpRecordableFixture/RecordSpanWithLinks/link_count:1_stddev 1.83 ns 1.77 ns 5 items_per_second=7.24305k/s
OtlpRecordableFixture/RecordSpanWithLinks/link_count:1_cv 0.37 % 0.36 % 5 items_per_second=0.36%
OtlpRecordableFixture/RecordSpanWithLinks/link_count:10_mean 1771 ns 1774 ns 5 items_per_second=5.63633M/s
OtlpRecordableFixture/RecordSpanWithLinks/link_count:10_median 1771 ns 1774 ns 5 items_per_second=5.6372M/s
OtlpRecordableFixture/RecordSpanWithLinks/link_count:10_stddev 11.1 ns 11.1 ns 5 items_per_second=35.1976k/s
OtlpRecordableFixture/RecordSpanWithLinks/link_count:10_cv 0.63 % 0.63 % 5 items_per_second=0.62%
OtlpRecordableFixture/RecordSpanWithLinks/link_count:128_mean 18768 ns 18772 ns 5 items_per_second=6.821M/s
OtlpRecordableFixture/RecordSpanWithLinks/link_count:128_median 18776 ns 18779 ns 5 items_per_second=6.81616M/s
OtlpRecordableFixture/RecordSpanWithLinks/link_count:128_stddev 400 ns 400 ns 5 items_per_second=143.963k/s
OtlpRecordableFixture/RecordSpanWithLinks/link_count:128_cv 2.13 % 2.13 % 5 items_per_second=2.11%
BM_OtlpPopulateRequest/span_count:1_mean 0.392 us 0.392 us 5 items_per_second=2.54888M/s
BM_OtlpPopulateRequest/span_count:1_median 0.391 us 0.391 us 5 items_per_second=2.55581M/s
BM_OtlpPopulateRequest/span_count:1_stddev 0.005 us 0.005 us 5 items_per_second=35.2498k/s
BM_OtlpPopulateRequest/span_count:1_cv 1.38 % 1.38 % 5 items_per_second=1.38%
BM_OtlpPopulateRequest/span_count:512_mean 24.0 us 24.0 us 5 items_per_second=21.3716M/s
BM_OtlpPopulateRequest/span_count:512_median 24.0 us 24.0 us 5 items_per_second=21.2952M/s
BM_OtlpPopulateRequest/span_count:512_stddev 0.321 us 0.321 us 5 items_per_second=288.031k/s
BM_OtlpPopulateRequest/span_count:512_cv 1.34 % 1.34 % 5 items_per_second=1.35%
Fixes #4046
Add support for programmatic and yaml configuration of span limits through the TracerProvider. Apply span limits on the SpanData recordable and update the OtlpRecordable to use the configured limits (deprecating the limits set in otlp exporter options classes).
Changes
For significant contributions please make sure you have completed the following items:
CHANGELOG.mdupdated for non-trivial changes