Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

dougqh
Copy link
Contributor

@dougqh dougqh commented Mar 19, 2025

This change reduces the overhead from constructing spans both in terms of CPU and memory.

The biggest gains come when making use of SpanBuilders for both constructing the span and manipulating the tags on the Span. Span creation throughput with SpanBuilders improves by as much as 45%. startSpan methods commonly used in instrumentations improve by around 20%. In applications, real median response time gains are around to 5-10%.

More importantly, these changes reduce the amount of memory consumed by each Span reducing allocation / garbage collection pressure.

In a "real" application, the change is less noticeable when memory is plentiful; however, the difference becomes more pronounced when memory is limited. spring-petclinic shows a 17% throughput improvement relative to the current release when memory is constrained to 192M or 128M. At 96M, the difference is negligible 2-3% gain throughput. At 64M, this change becomes a detriment showing a -5% change in throughput.

What Does This Do

These gains are accomplished by changing how tags are stored to use a new Map (TagMap) that excels at Map-to-Map copies. To fully realize the gain, there's additional work to skip tag interceptors when possible. With these changes, the setting of the shared tags on a Span-s is nearly allocation free.

Motivation

The tracer does some Map operations regularly that regular HashMaps aren't good at.

The primary operation of concern being copying Entry-s from Map to Map where every copied Entry requires allocating a new Entry object in the destination Map.

And secondarily, Builder patterns which use defensive copying but also require in-order processing in the Tracer.

TagMap solves both those problems by using immutable Entry objects. By making the Entry objects immutable, the Entry objects can be freely shared between Map instances and between the Builder and a Map.

Additional Notes

To get the full benefit of this new TagMap, both the source Map and the destination Map need to be TagMap-s and the transfer needs to happen through putAll or the TagMap specific putEntry.

Meaning - that to get a significant gain quite a few files had to be modified

Contributor Checklist

@dougqh dougqh requested review from a team as code owners March 19, 2025 17:16
@dougqh dougqh requested review from smola, sezen-datadog, ojung and anmarchenko and removed request for a team March 19, 2025 17:16
AgentSpanContext traceContext =
new TagContext(
CIConstants.CIAPP_TEST_ORIGIN,
Collections.emptyMap(),
Copy link
Contributor Author

@dougqh dougqh Mar 19, 2025

Choose a reason for hiding this comment

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

I have mixed feelings about this particular change. In effect, the constructor previously required the user to pass a mutable map. However if the provided Map was empty, the class would lazily construction a mutable Map to take place of the empty Map.

Because TagMap does not have an O(1) isEmpty, I didn't want to stick with this pattern.

What could be done instead is to pass TagMap.EMPTY and then check via a reference equality check. If others prefer that, I can adjust accordingly.

this.context = new TestContextImpl(coverageStore);

AgentSpanContext traceContext =
new TagContext(CIConstants.CIAPP_TEST_ORIGIN, Collections.emptyMap());
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Same mutable empty Map issue

private ConfigurationUpdater configurationUpdater;
private DefaultExceptionDebugger exceptionDebugger;
private TestSnapshotListener listener;
private Map<String, Object> spanTags = new HashMap<>();
Copy link
Contributor Author

@dougqh dougqh Mar 19, 2025

Choose a reason for hiding this comment

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

This is the primary type of change that I've made throughout -- replacing HashMaps with TagMap-s.
To get the benefit of TagMap's quick Map-to-Map copying ability, both the source and destination Map need to be TagMap-s.

/** A set of tags that are added only to the application's root span */
private final Map<String, ?> localRootSpanTags;
private final TagMap localRootSpanTags;
private final boolean localRootSpanTagsNeedIntercept;
Copy link
Contributor Author

@dougqh dougqh Mar 19, 2025

Choose a reason for hiding this comment

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

To get the full benefit of TagMap's fast copy ability, I need to be to call TagMap.putAll.

However the TagInterceptor interferes with being able to do that, so I've added a method to TagInterceptor that can check the source Map in advance. If any tag in the source Map requires interception, then "needs intercept" is "true". If no tag needs interception, then "needs intercept" is false.

When "needs intercept" is false, setAllTags can then safely bypass the interceptor and use TagMap.putAll to do the fully optimized copy.


public CoreTracerBuilder localRootSpanTags(Map<String, ?> localRootSpanTags) {
this.localRootSpanTags = tryMakeImmutableMap(localRootSpanTags);
this.localRootSpanTags = TagMap.fromMapImmutable(localRootSpanTags);
Copy link
Contributor Author

@dougqh dougqh Mar 19, 2025

Choose a reason for hiding this comment

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

I kept some of the old methods that take Map instead of TagMap for ease of testing; however, the preferred way is to use TagMap now.

}

@Deprecated
private CoreTracer(
Copy link
Contributor Author

Choose a reason for hiding this comment

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

In a few places, I kept constructors that take Map-s instead of TagMap-s. This is mostly concession to the Groovy tests where using Map is far easier.

I may eliminate these over time, but I didn't want to create a giant diff where many test files had to be updated. This diff is big enough as it is.

spanSamplingRules = SpanSamplingRules.deserializeFile(spanSamplingRulesFile);
}

this.tagInterceptor =
Copy link
Contributor Author

@dougqh dougqh Mar 19, 2025

Choose a reason for hiding this comment

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

Had to do a bit of reordering to make tagInterceptor available earlier in the constructor, so I can analyze the shared tag sets.

For the curious, I was not able to move the setting of defaultSpanTags down because it has some odd interactions with other parts of the constructor.


// Builder attributes
private Map<String, Object> tags;
private TagMap.Builder tagBuilder;
Copy link
Contributor Author

@dougqh dougqh Mar 19, 2025

Choose a reason for hiding this comment

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

TagMap.Builder serves as a stand-in for using LinkedHashMap to preserve order. Although, the semantics aren't exactly the same.

LinkedHashMap traverses entries in the original insertion order. Meaning that if you insert: tag1, tag2, tag1. Then there will be a traversal of tag1, tag2.

TagMap.Builder simply records modifications in order, so the traversal order will be tag1 first value, tag2, tag1 second value. Arguably, this is closer to the intended semantics because it makes the behavior of the builder the same as calling setTag.

}
if (value == null) {
tagMap.remove(tag);
tagBuilder.remove(tag);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

tagBuilder records removals as a special removal Entry object. Removal Entry objects are never stored in the TagMap.

This design allows tagBuilder to be an in-order ledger of modifications, but also allow Entry objects to be shared between the TagMap.Builder and the TagMap that is produced in the end.

samplingPriority = PrioritySampling.UNSET;
origin = null;
coreTags = null;
coreTagsNeedsIntercept = false;
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I could just as easily set needs intercept to true, since interception short-circuits on a null TagMap.

+ (null == coreTags ? 0 : coreTags.size())
+ (null == rootSpanTags ? 0 : rootSpanTags.size())
+ (null == contextualTags ? 0 : contextualTags.size());
final int tagsSize = 0;
Copy link
Contributor Author

@dougqh dougqh Mar 19, 2025

Choose a reason for hiding this comment

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

As a further simplification, TagMaps are a fixed size (16) that's big enough to avoid a large number of collisions. But more importantly, TagMap doesn't currently implement an O(1) size method.

In short, the tagsSize calculation just isn't needed and its costly.

If no one objects to this, then I'll probably eliminate tagsSize altogether. Right now, this variable still exists because there's an argument still being passed to the DDSpanContext constructor.


final Map<String, ?> mergedTracerTags = traceConfig.mergedTracerTags;
final TagMap mergedTracerTags = traceConfig.mergedTracerTags;
boolean mergedTracerTagsNeedsIntercept = traceConfig.mergedTracerTagsNeedsIntercept;
Copy link
Contributor Author

@dougqh dougqh Mar 19, 2025

Choose a reason for hiding this comment

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

Similar pattern of checking if interception is needed in advance - in this case, traceConfig will be updated each time a new config is received by remote config.

if (contextualTags != null) {
context.setAllTags(contextualTags);
}
context.setAllTags(mergedTracerTags, mergedTracerTagsNeedsIntercept);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

These calls have been updated to call new versions of setAllTags that work with TagMap or TagMap.Builder. For those that takes a TagMap, there's also the ability to pass along previously done calculation for "needs intercept".

context.setAllTags(tagBuilder);
context.setAllTags(coreTags, coreTagsNeedsIntercept);
context.setAllTags(rootSpanTags, rootSpanTagsNeedsIntercept);
context.setAllTags(contextualTags);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I haven't yet updated contextualTags to use a TagMap. That's an obvious next step.

if (null == oldSnapshot) {
mergedTracerTags = CoreTracer.this.defaultSpanTags;
mergedTracerTags = CoreTracer.this.defaultSpanTags.immutableCopy();
this.mergedTracerTagsNeedsIntercept = CoreTracer.this.defaultSpanTagsNeedsIntercept;
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Pulling from CoreTracer use its "needs intercept" value

this.mergedTracerTagsNeedsIntercept = CoreTracer.this.defaultSpanTagsNeedsIntercept;
} else if (getTracingTags().equals(oldSnapshot.getTracingTags())) {
mergedTracerTags = oldSnapshot.mergedTracerTags;
mergedTracerTagsNeedsIntercept = oldSnapshot.mergedTracerTagsNeedsIntercept;
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Prior config - just reuse "needs intercept" value from before

mergedTracerTagsNeedsIntercept = oldSnapshot.mergedTracerTagsNeedsIntercept;
} else {
mergedTracerTags = withTracerTags(getTracingTags(), CoreTracer.this.initialConfig, this);
mergedTracerTagsNeedsIntercept = CoreTracer.this.tagInterceptor.needsIntercept(mergedTracerTags);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

New tag set -- needs to be freshly analyzed

@pr-commenter
Copy link

pr-commenter bot commented Mar 19, 2025

Debugger benchmarks

Parameters

Baseline Candidate
baseline_or_candidate baseline candidate
ci_job_date 1752588642 1752588987
end_time 2025-07-15T14:12:03 2025-07-15T14:17:48
git_branch master dougqh/interceptor-bypass
git_commit_sha b86f4f7 1481179
start_time 2025-07-15T14:10:43 2025-07-15T14:16:28
See matching parameters
Baseline Candidate
ci_job_id 1029219562 1029219562
ci_pipeline_id 70581072 70581072
cpu_model Intel(R) Xeon(R) Platinum 8259CL CPU @ 2.50GHz Intel(R) Xeon(R) Platinum 8259CL CPU @ 2.50GHz
git_commit_date 1752587968 1752587968

Summary

Found 0 performance improvements and 0 performance regressions! Performance is the same for 8 metrics, 7 unstable metrics.

See unchanged results
scenario Ξ” mean agg_http_req_duration_min Ξ” mean agg_http_req_duration_p50 Ξ” mean agg_http_req_duration_p75 Ξ” mean agg_http_req_duration_p99 Ξ” mean throughput
scenario:noprobe unstable
[-25.473Β΅s; +41.258Β΅s] or [-9.177%; +14.864%]
unstable
[-35.723Β΅s; +56.598Β΅s] or [-11.235%; +17.800%]
unstable
[-45.848Β΅s; +68.842Β΅s] or [-13.767%; +20.671%]
unstable
[-161.049Β΅s; +176.714Β΅s] or [-16.448%; +18.047%]
unstable
[-129.317op/s; +129.342op/s] or [-5.237%; +5.238%]
scenario:basic same same same unstable
[-125.007Β΅s; +31.564Β΅s] or [-16.533%; +4.175%]
unstable
[-241.311op/s; +99.064op/s] or [-8.929%; +3.665%]
scenario:loop same unsure
[-11.660Β΅s; -1.259Β΅s] or [-0.130%; -0.014%]
unsure
[-13.736Β΅s; -2.288Β΅s] or [-0.152%; -0.025%]
same same
Request duration reports for reports
gantt
    title reports - request duration [CI 0.99] : candidate=None, baseline=None
    dateFormat X
    axisFormat %s
section baseline
noprobe (317.967 Β΅s) : 284, 352
.   : milestone, 318,
basic (276.316 Β΅s) : 270, 283
.   : milestone, 276,
loop (8.965 ms) : 8960, 8969
.   : milestone, 8965,
section candidate
noprobe (328.404 Β΅s) : 276, 381
.   : milestone, 328,
basic (278.719 Β΅s) : 273, 285
.   : milestone, 279,
loop (8.958 ms) : 8953, 8963
.   : milestone, 8958,
Loading
  • baseline results
Scenario Request median duration [CI 0.99]
noprobe 317.967 Β΅s [284.248 Β΅s, 351.686 Β΅s]
basic 276.316 Β΅s [269.621 Β΅s, 283.011 Β΅s]
loop 8.965 ms [8.96 ms, 8.969 ms]
  • candidate results
Scenario Request median duration [CI 0.99]
noprobe 328.404 Β΅s [276.201 Β΅s, 380.607 Β΅s]
basic 278.719 Β΅s [272.658 Β΅s, 284.78 Β΅s]
loop 8.958 ms [8.953 ms, 8.963 ms]

@pr-commenter
Copy link

pr-commenter bot commented Mar 19, 2025

Benchmarks

Startup

Parameters

Baseline Candidate
baseline_or_candidate baseline candidate
git_branch master dougqh/interceptor-bypass
git_commit_date 1752586391 1752587968
git_commit_sha b86f4f7 1481179
release_version 1.52.0-SNAPSHOT~b86f4f70d6 1.52.0-SNAPSHOT~148117965e
See matching parameters
Baseline Candidate
application insecure-bank insecure-bank
ci_job_date 1752589838 1752589838
ci_job_id 1029219546 1029219546
ci_pipeline_id 70581072 70581072
cpu_model Intel(R) Xeon(R) Platinum 8259CL CPU @ 2.50GHz Intel(R) Xeon(R) Platinum 8259CL CPU @ 2.50GHz
kernel_version Linux runner-zfyrx7zua-project-304-concurrent-1-4sy9e9e9 6.8.0-1031-aws #33~22.04.1-Ubuntu SMP Thu Jun 26 14:22:30 UTC 2025 x86_64 x86_64 x86_64 GNU/Linux Linux runner-zfyrx7zua-project-304-concurrent-1-4sy9e9e9 6.8.0-1031-aws #33~22.04.1-Ubuntu SMP Thu Jun 26 14:22:30 UTC 2025 x86_64 x86_64 x86_64 GNU/Linux
module Agent Agent
parent None None

Summary

Found 0 performance improvements and 0 performance regressions! Performance is the same for 46 metrics, 7 unstable metrics.

Startup time reports for petclinic
gantt
    title petclinic - global startup overhead: candidate=1.52.0-SNAPSHOT~148117965e, baseline=1.52.0-SNAPSHOT~b86f4f70d6

    dateFormat X
    axisFormat %s
section tracing
Agent [baseline] (1.0 s) : 0, 1000399
Total [baseline] (10.685 s) : 0, 10684993
Agent [candidate] (997.628 ms) : 0, 997628
Total [candidate] (10.679 s) : 0, 10678576
section appsec
Agent [baseline] (1.174 s) : 0, 1173501
Total [baseline] (10.749 s) : 0, 10748782
Agent [candidate] (1.175 s) : 0, 1175281
Total [candidate] (10.79 s) : 0, 10789701
section iast
Agent [baseline] (1.131 s) : 0, 1130723
Total [baseline] (10.885 s) : 0, 10884576
Agent [candidate] (1.135 s) : 0, 1134691
Total [candidate] (10.888 s) : 0, 10888315
section profiling
Agent [baseline] (1.248 s) : 0, 1247670
Total [baseline] (10.96 s) : 0, 10960360
Agent [candidate] (1.256 s) : 0, 1255825
Total [candidate] (10.945 s) : 0, 10945382
Loading
  • baseline results
Module Variant Duration Ξ” tracing
Agent tracing 1.0 s -
Agent appsec 1.174 s 173.102 ms (17.3%)
Agent iast 1.131 s 130.324 ms (13.0%)
Agent profiling 1.248 s 247.272 ms (24.7%)
Total tracing 10.685 s -
Total appsec 10.749 s 63.789 ms (0.6%)
Total iast 10.885 s 199.583 ms (1.9%)
Total profiling 10.96 s 275.367 ms (2.6%)
  • candidate results
Module Variant Duration Ξ” tracing
Agent tracing 997.628 ms -
Agent appsec 1.175 s 177.653 ms (17.8%)
Agent iast 1.135 s 137.063 ms (13.7%)
Agent profiling 1.256 s 258.197 ms (25.9%)
Total tracing 10.679 s -
Total appsec 10.79 s 111.126 ms (1.0%)
Total iast 10.888 s 209.74 ms (2.0%)
Total profiling 10.945 s 266.806 ms (2.5%)
gantt
    title petclinic - break down per module: candidate=1.52.0-SNAPSHOT~148117965e, baseline=1.52.0-SNAPSHOT~b86f4f70d6

    dateFormat X
    axisFormat %s
section tracing
BytebuddyAgent [baseline] (690.215 ms) : 0, 690215
BytebuddyAgent [candidate] (687.238 ms) : 0, 687238
GlobalTracer [baseline] (243.55 ms) : 0, 243550
GlobalTracer [candidate] (243.831 ms) : 0, 243831
AppSec [baseline] (30.623 ms) : 0, 30623
AppSec [candidate] (30.684 ms) : 0, 30684
Debugger [baseline] (6.073 ms) : 0, 6073
Debugger [candidate] (6.038 ms) : 0, 6038
Remote Config [baseline] (677.245 Β΅s) : 0, 677
Remote Config [candidate] (680.364 Β΅s) : 0, 680
Telemetry [baseline] (8.262 ms) : 0, 8262
Telemetry [candidate] (8.196 ms) : 0, 8196
section appsec
BytebuddyAgent [baseline] (708.53 ms) : 0, 708530
BytebuddyAgent [candidate] (708.455 ms) : 0, 708455
GlobalTracer [baseline] (235.353 ms) : 0, 235353
GlobalTracer [candidate] (236.826 ms) : 0, 236826
IAST [baseline] (23.457 ms) : 0, 23457
IAST [candidate] (23.407 ms) : 0, 23407
AppSec [baseline] (170.982 ms) : 0, 170982
AppSec [candidate] (171.378 ms) : 0, 171378
Debugger [baseline] (5.707 ms) : 0, 5707
Debugger [candidate] (5.756 ms) : 0, 5756
Remote Config [baseline] (594.017 Β΅s) : 0, 594
Remote Config [candidate] (603.263 Β΅s) : 0, 603
Telemetry [baseline] (7.956 ms) : 0, 7956
Telemetry [candidate] (8.049 ms) : 0, 8049
section iast
BytebuddyAgent [baseline] (805.287 ms) : 0, 805287
BytebuddyAgent [candidate] (806.812 ms) : 0, 806812
GlobalTracer [baseline] (232.524 ms) : 0, 232524
GlobalTracer [candidate] (234.683 ms) : 0, 234683
IAST [baseline] (26.495 ms) : 0, 26495
IAST [candidate] (29.091 ms) : 0, 29091
AppSec [baseline] (31.349 ms) : 0, 31349
AppSec [candidate] (28.951 ms) : 0, 28951
Debugger [baseline] (5.69 ms) : 0, 5690
Debugger [candidate] (5.742 ms) : 0, 5742
Remote Config [baseline] (577.435 Β΅s) : 0, 577
Remote Config [candidate] (579.008 Β΅s) : 0, 579
Telemetry [baseline] (7.904 ms) : 0, 7904
Telemetry [candidate] (7.934 ms) : 0, 7934
section profiling
BytebuddyAgent [baseline] (678.856 ms) : 0, 678856
BytebuddyAgent [candidate] (682.998 ms) : 0, 682998
GlobalTracer [baseline] (363.094 ms) : 0, 363094
GlobalTracer [candidate] (365.515 ms) : 0, 365515
AppSec [baseline] (31.98 ms) : 0, 31980
AppSec [candidate] (31.582 ms) : 0, 31582
Debugger [baseline] (11.376 ms) : 0, 11376
Debugger [candidate] (11.46 ms) : 0, 11460
Remote Config [baseline] (660.108 Β΅s) : 0, 660
Remote Config [candidate] (669.187 Β΅s) : 0, 669
Telemetry [baseline] (9.633 ms) : 0, 9633
Telemetry [candidate] (10.274 ms) : 0, 10274
ProfilingAgent [baseline] (103.255 ms) : 0, 103255
ProfilingAgent [candidate] (104.297 ms) : 0, 104297
Profiling [baseline] (103.28 ms) : 0, 103280
Profiling [candidate] (104.322 ms) : 0, 104322
Loading
Startup time reports for insecure-bank
gantt
    title insecure-bank - global startup overhead: candidate=1.52.0-SNAPSHOT~148117965e, baseline=1.52.0-SNAPSHOT~b86f4f70d6

    dateFormat X
    axisFormat %s
section tracing
Agent [baseline] (1.003 s) : 0, 1002967
Total [baseline] (8.644 s) : 0, 8644195
Agent [candidate] (1.003 s) : 0, 1003120
Total [candidate] (8.6 s) : 0, 8600021
section iast
Agent [baseline] (1.141 s) : 0, 1140523
Total [baseline] (9.33 s) : 0, 9329840
Agent [candidate] (1.141 s) : 0, 1140885
Total [candidate] (9.334 s) : 0, 9333957
Loading
  • baseline results
Module Variant Duration Ξ” tracing
Agent tracing 1.003 s -
Agent iast 1.141 s 137.556 ms (13.7%)
Total tracing 8.644 s -
Total iast 9.33 s 685.646 ms (7.9%)
  • candidate results
Module Variant Duration Ξ” tracing
Agent tracing 1.003 s -
Agent iast 1.141 s 137.765 ms (13.7%)
Total tracing 8.6 s -
Total iast 9.334 s 733.936 ms (8.5%)
gantt
    title insecure-bank - break down per module: candidate=1.52.0-SNAPSHOT~148117965e, baseline=1.52.0-SNAPSHOT~b86f4f70d6

    dateFormat X
    axisFormat %s
section tracing
BytebuddyAgent [baseline] (692.139 ms) : 0, 692139
BytebuddyAgent [candidate] (690.329 ms) : 0, 690329
GlobalTracer [baseline] (244.198 ms) : 0, 244198
GlobalTracer [candidate] (245.136 ms) : 0, 245136
AppSec [baseline] (30.715 ms) : 0, 30715
AppSec [candidate] (30.997 ms) : 0, 30997
Debugger [baseline] (5.994 ms) : 0, 5994
Debugger [candidate] (6.097 ms) : 0, 6097
Remote Config [baseline] (678.101 Β΅s) : 0, 678
Remote Config [candidate] (687.589 Β΅s) : 0, 688
Telemetry [baseline] (8.335 ms) : 0, 8335
Telemetry [candidate] (9.032 ms) : 0, 9032
section iast
BytebuddyAgent [baseline] (812.494 ms) : 0, 812494
BytebuddyAgent [candidate] (811.969 ms) : 0, 811969
GlobalTracer [baseline] (234.303 ms) : 0, 234303
GlobalTracer [candidate] (235.342 ms) : 0, 235342
AppSec [baseline] (30.941 ms) : 0, 30941
AppSec [candidate] (30.032 ms) : 0, 30032
Debugger [baseline] (5.77 ms) : 0, 5770
Debugger [candidate] (5.768 ms) : 0, 5768
Remote Config [baseline] (596.384 Β΅s) : 0, 596
Remote Config [candidate] (584.02 Β΅s) : 0, 584
Telemetry [baseline] (7.952 ms) : 0, 7952
Telemetry [candidate] (7.96 ms) : 0, 7960
IAST [baseline] (27.514 ms) : 0, 27514
IAST [candidate] (28.295 ms) : 0, 28295
Loading

Load

Parameters

Baseline Candidate
baseline_or_candidate baseline candidate
git_branch master dougqh/interceptor-bypass
git_commit_date 1752586391 1752587968
git_commit_sha b86f4f7 1481179
release_version 1.52.0-SNAPSHOT~b86f4f70d6 1.52.0-SNAPSHOT~148117965e
See matching parameters
Baseline Candidate
application insecure-bank insecure-bank
ci_job_date 1752589599 1752589599
ci_job_id 1029219549 1029219549
ci_pipeline_id 70581072 70581072
cpu_model Intel(R) Xeon(R) Platinum 8259CL CPU @ 2.50GHz Intel(R) Xeon(R) Platinum 8259CL CPU @ 2.50GHz
kernel_version Linux runner-zfyrx7zua-project-304-concurrent-0-972opo9b 6.8.0-1031-aws #33~22.04.1-Ubuntu SMP Thu Jun 26 14:22:30 UTC 2025 x86_64 x86_64 x86_64 GNU/Linux Linux runner-zfyrx7zua-project-304-concurrent-0-972opo9b 6.8.0-1031-aws #33~22.04.1-Ubuntu SMP Thu Jun 26 14:22:30 UTC 2025 x86_64 x86_64 x86_64 GNU/Linux

Summary

Found 1 performance improvements and 2 performance regressions! Performance is the same for 9 metrics, 12 unstable metrics.

scenario Ξ” mean http_req_duration Ξ” mean throughput candidate mean http_req_duration candidate mean throughput baseline mean http_req_duration baseline mean throughput
scenario:load:insecure-bank:tracing:high_load better
[-515.235Β΅s; -269.472Β΅s] or [-6.637%; -3.471%]
unstable
[-43.150op/s; +105.400op/s] or [-7.231%; +17.663%]
7.371ms 627.844op/s 7.763ms 596.719op/s
scenario:load:petclinic:iast:high_load worse
[+1.522ms; +2.355ms] or [+3.503%; +5.420%]
unstable
[-12.140op/s; +3.040op/s] or [-11.276%; +2.824%]
45.398ms 103.112op/s 43.459ms 107.662op/s
scenario:load:petclinic:tracing:high_load worse
[+1.323ms; +2.103ms] or [+3.134%; +4.981%]
unstable
[-12.147op/s; +3.447op/s] or [-10.961%; +3.111%]
43.935ms 106.475op/s 42.222ms 110.825op/s
Request duration reports for petclinic
gantt
    title petclinic - request duration [CI 0.99] : candidate=1.52.0-SNAPSHOT~148117965e, baseline=1.52.0-SNAPSHOT~b86f4f70d6
    dateFormat X
    axisFormat %s
section baseline
no_agent (36.464 ms) : 36176, 36752
.   : milestone, 36464,
appsec (47.596 ms) : 47169, 48024
.   : milestone, 47596,
code_origins (45.211 ms) : 44812, 45610
.   : milestone, 45211,
iast (43.459 ms) : 43088, 43829
.   : milestone, 43459,
profiling (48.239 ms) : 47789, 48689
.   : milestone, 48239,
tracing (42.222 ms) : 41874, 42570
.   : milestone, 42222,
section candidate
no_agent (36.432 ms) : 36133, 36732
.   : milestone, 36432,
appsec (47.889 ms) : 47457, 48321
.   : milestone, 47889,
code_origins (45.408 ms) : 45010, 45806
.   : milestone, 45408,
iast (45.398 ms) : 44995, 45800
.   : milestone, 45398,
profiling (47.215 ms) : 46783, 47647
.   : milestone, 47215,
tracing (43.935 ms) : 43559, 44311
.   : milestone, 43935,
Loading
  • baseline results
Variant Request duration [CI 0.99] Ξ” no_agent
no_agent 36.464 ms [36.176 ms, 36.752 ms] -
appsec 47.596 ms [47.169 ms, 48.024 ms] 11.132 ms (30.5%)
code_origins 45.211 ms [44.812 ms, 45.61 ms] 8.747 ms (24.0%)
iast 43.459 ms [43.088 ms, 43.829 ms] 6.995 ms (19.2%)
profiling 48.239 ms [47.789 ms, 48.689 ms] 11.775 ms (32.3%)
tracing 42.222 ms [41.874 ms, 42.57 ms] 5.758 ms (15.8%)
  • candidate results
Variant Request duration [CI 0.99] Ξ” no_agent
no_agent 36.432 ms [36.133 ms, 36.732 ms] -
appsec 47.889 ms [47.457 ms, 48.321 ms] 11.457 ms (31.4%)
code_origins 45.408 ms [45.01 ms, 45.806 ms] 8.976 ms (24.6%)
iast 45.398 ms [44.995 ms, 45.8 ms] 8.965 ms (24.6%)
profiling 47.215 ms [46.783 ms, 47.647 ms] 10.783 ms (29.6%)
tracing 43.935 ms [43.559 ms, 44.311 ms] 7.503 ms (20.6%)
Request duration reports for insecure-bank
gantt
    title insecure-bank - request duration [CI 0.99] : candidate=1.52.0-SNAPSHOT~148117965e, baseline=1.52.0-SNAPSHOT~b86f4f70d6
    dateFormat X
    axisFormat %s
section baseline
no_agent (4.391 ms) : 4343, 4440
.   : milestone, 4391,
iast (9.6 ms) : 9442, 9758
.   : milestone, 9600,
iast_FULL (13.801 ms) : 13526, 14076
.   : milestone, 13801,
iast_GLOBAL (10.359 ms) : 10178, 10540
.   : milestone, 10359,
profiling (8.42 ms) : 8275, 8566
.   : milestone, 8420,
tracing (7.763 ms) : 7644, 7883
.   : milestone, 7763,
section candidate
no_agent (4.261 ms) : 4208, 4314
.   : milestone, 4261,
iast (9.43 ms) : 9271, 9590
.   : milestone, 9430,
iast_FULL (14.346 ms) : 14051, 14640
.   : milestone, 14346,
iast_GLOBAL (10.227 ms) : 10049, 10405
.   : milestone, 10227,
profiling (8.418 ms) : 8283, 8553
.   : milestone, 8418,
tracing (7.371 ms) : 7262, 7480
.   : milestone, 7371,
Loading
  • baseline results
Variant Request duration [CI 0.99] Ξ” no_agent
no_agent 4.391 ms [4.343 ms, 4.44 ms] -
iast 9.6 ms [9.442 ms, 9.758 ms] 5.209 ms (118.6%)
iast_FULL 13.801 ms [13.526 ms, 14.076 ms] 9.41 ms (214.3%)
iast_GLOBAL 10.359 ms [10.178 ms, 10.54 ms] 5.968 ms (135.9%)
profiling 8.42 ms [8.275 ms, 8.566 ms] 4.029 ms (91.8%)
tracing 7.763 ms [7.644 ms, 7.883 ms] 3.372 ms (76.8%)
  • candidate results
Variant Request duration [CI 0.99] Ξ” no_agent
no_agent 4.261 ms [4.208 ms, 4.314 ms] -
iast 9.43 ms [9.271 ms, 9.59 ms] 5.17 ms (121.3%)
iast_FULL 14.346 ms [14.051 ms, 14.64 ms] 10.085 ms (236.7%)
iast_GLOBAL 10.227 ms [10.049 ms, 10.405 ms] 5.966 ms (140.0%)
profiling 8.418 ms [8.283 ms, 8.553 ms] 4.157 ms (97.6%)
tracing 7.371 ms [7.262 ms, 7.48 ms] 3.11 ms (73.0%)

Dacapo

Parameters

Baseline Candidate
baseline_or_candidate baseline candidate
git_branch master dougqh/interceptor-bypass
git_commit_date 1752586391 1752587968
git_commit_sha b86f4f7 1481179
release_version 1.52.0-SNAPSHOT~b86f4f70d6 1.52.0-SNAPSHOT~148117965e
See matching parameters
Baseline Candidate
application biojava biojava
ci_job_date 1752590010 1752590010
ci_job_id 1029219552 1029219552
ci_pipeline_id 70581072 70581072
cpu_model Intel(R) Xeon(R) Platinum 8259CL CPU @ 2.50GHz Intel(R) Xeon(R) Platinum 8259CL CPU @ 2.50GHz
kernel_version Linux runner-zfyrx7zua-project-304-concurrent-2-7omj3y1f 6.8.0-1031-aws #33~22.04.1-Ubuntu SMP Thu Jun 26 14:22:30 UTC 2025 x86_64 x86_64 x86_64 GNU/Linux Linux runner-zfyrx7zua-project-304-concurrent-2-7omj3y1f 6.8.0-1031-aws #33~22.04.1-Ubuntu SMP Thu Jun 26 14:22:30 UTC 2025 x86_64 x86_64 x86_64 GNU/Linux

Summary

Found 0 performance improvements and 0 performance regressions! Performance is the same for 12 metrics, 0 unstable metrics.

Execution time for biojava
gantt
    title biojava - execution time [CI 0.99] : candidate=1.52.0-SNAPSHOT~148117965e, baseline=1.52.0-SNAPSHOT~b86f4f70d6
    dateFormat X
    axisFormat %s
section baseline
no_agent (15.493 s) : 15493000, 15493000
.   : milestone, 15493000,
appsec (14.609 s) : 14609000, 14609000
.   : milestone, 14609000,
iast (18.364 s) : 18364000, 18364000
.   : milestone, 18364000,
iast_GLOBAL (17.934 s) : 17934000, 17934000
.   : milestone, 17934000,
profiling (15.234 s) : 15234000, 15234000
.   : milestone, 15234000,
tracing (14.789 s) : 14789000, 14789000
.   : milestone, 14789000,
section candidate
no_agent (15.611 s) : 15611000, 15611000
.   : milestone, 15611000,
appsec (14.758 s) : 14758000, 14758000
.   : milestone, 14758000,
iast (18.114 s) : 18114000, 18114000
.   : milestone, 18114000,
iast_GLOBAL (18.522 s) : 18522000, 18522000
.   : milestone, 18522000,
profiling (15.846 s) : 15846000, 15846000
.   : milestone, 15846000,
tracing (14.723 s) : 14723000, 14723000
.   : milestone, 14723000,
Loading
  • baseline results
Variant Execution Time [CI 0.99] Ξ” no_agent
no_agent 15.493 s [15.493 s, 15.493 s] -
appsec 14.609 s [14.609 s, 14.609 s] -884.0 ms (-5.7%)
iast 18.364 s [18.364 s, 18.364 s] 2.871 s (18.5%)
iast_GLOBAL 17.934 s [17.934 s, 17.934 s] 2.441 s (15.8%)
profiling 15.234 s [15.234 s, 15.234 s] -259.0 ms (-1.7%)
tracing 14.789 s [14.789 s, 14.789 s] -704.0 ms (-4.5%)
  • candidate results
Variant Execution Time [CI 0.99] Ξ” no_agent
no_agent 15.611 s [15.611 s, 15.611 s] -
appsec 14.758 s [14.758 s, 14.758 s] -853.0 ms (-5.5%)
iast 18.114 s [18.114 s, 18.114 s] 2.503 s (16.0%)
iast_GLOBAL 18.522 s [18.522 s, 18.522 s] 2.911 s (18.6%)
profiling 15.846 s [15.846 s, 15.846 s] 235.0 ms (1.5%)
tracing 14.723 s [14.723 s, 14.723 s] -888.0 ms (-5.7%)
Execution time for tomcat
gantt
    title tomcat - execution time [CI 0.99] : candidate=1.52.0-SNAPSHOT~148117965e, baseline=1.52.0-SNAPSHOT~b86f4f70d6
    dateFormat X
    axisFormat %s
section baseline
no_agent (1.473 ms) : 1461, 1484
.   : milestone, 1473,
appsec (2.396 ms) : 2346, 2446
.   : milestone, 2396,
iast (2.185 ms) : 2123, 2248
.   : milestone, 2185,
iast_GLOBAL (2.232 ms) : 2169, 2295
.   : milestone, 2232,
profiling (2.035 ms) : 1984, 2085
.   : milestone, 2035,
tracing (2.002 ms) : 1954, 2051
.   : milestone, 2002,
section candidate
no_agent (1.471 ms) : 1460, 1483
.   : milestone, 1471,
appsec (2.397 ms) : 2347, 2447
.   : milestone, 2397,
iast (2.18 ms) : 2117, 2242
.   : milestone, 2180,
iast_GLOBAL (2.234 ms) : 2172, 2297
.   : milestone, 2234,
profiling (2.048 ms) : 1996, 2099
.   : milestone, 2048,
tracing (2.001 ms) : 1953, 2049
.   : milestone, 2001,
Loading
  • baseline results
Variant Execution Time [CI 0.99] Ξ” no_agent
no_agent 1.473 ms [1.461 ms, 1.484 ms] -
appsec 2.396 ms [2.346 ms, 2.446 ms] 923.167 Β΅s (62.7%)
iast 2.185 ms [2.123 ms, 2.248 ms] 712.511 Β΅s (48.4%)
iast_GLOBAL 2.232 ms [2.169 ms, 2.295 ms] 758.785 Β΅s (51.5%)
profiling 2.035 ms [1.984 ms, 2.085 ms] 561.821 Β΅s (38.1%)
tracing 2.002 ms [1.954 ms, 2.051 ms] 529.582 Β΅s (36.0%)
  • candidate results
Variant Execution Time [CI 0.99] Ξ” no_agent
no_agent 1.471 ms [1.46 ms, 1.483 ms] -
appsec 2.397 ms [2.347 ms, 2.447 ms] 925.877 Β΅s (62.9%)
iast 2.18 ms [2.117 ms, 2.242 ms] 708.758 Β΅s (48.2%)
iast_GLOBAL 2.234 ms [2.172 ms, 2.297 ms] 763.4 Β΅s (51.9%)
profiling 2.048 ms [1.996 ms, 2.099 ms] 576.604 Β΅s (39.2%)
tracing 2.001 ms [1.953 ms, 2.049 ms] 530.044 Β΅s (36.0%)

Copy link
Member

@smola smola left a comment

Choose a reason for hiding this comment

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

I'd suggest a rebase to get an up-to-date benchmark run.

Copy link
Contributor

github-actions bot commented Mar 26, 2025

Hi! πŸ‘‹ Thanks for your pull request! πŸŽ‰

To help us review it, please make sure to:

  • Add at least one type, and one component or instrumentation label to the pull request

If you need help, please check our contributing guidelines.

@dougqh dougqh added comp: core Tracer core tag: performance Performance related changes type: enhancement Enhancements and improvements labels Mar 26, 2025
Comment on lines 54 to 55
* Because the Entry objects can be shared between multiple TagMaps, the Entry objects cannot contain
* form a link list to handle collisions.
Copy link
Contributor

Choose a reason for hiding this comment

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

I think you need to choose only one verb between contain/form

public static final TagMap EMPTY = createEmpty();

private static final TagMap createEmpty() {
return new TagMap().freeze();
Copy link
Contributor

@vandonr vandonr Apr 7, 2025

Choose a reason for hiding this comment

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

could we use the parameterized ctor to avoid allocating an array of 16 entries that'll never be used ?

Suggested change
return new TagMap().freeze();
return new TagMap(null);

(not sure if null is OK, I haven't read all the code yet :p)

Copy link
Contributor

Choose a reason for hiding this comment

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

so, yeah, not ok, but we could create an empty array.

Comment on lines 226 to 249
public final boolean getBoolean(String tag) {
Entry entry = this.getEntry(tag);
return entry == null ? false : entry.booleanValue();
}

public final int getInt(String tag) {
Entry entry = this.getEntry(tag);
return entry == null ? 0 : entry.intValue();
}

public final long getLong(String tag) {
Entry entry = this.getEntry(tag);
return entry == null ? 0L : entry.longValue();
}

public final float getFloat(String tag) {
Entry entry = this.getEntry(tag);
return entry == null ? 0F : entry.floatValue();
}

public final double getDouble(String tag) {
Entry entry = this.getEntry(tag);
return entry == null ? 0D : entry.doubleValue();
}
Copy link
Contributor

Choose a reason for hiding this comment

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

looks a bit dangerous to have default values for those, then we cannot really know when we get 0 if the value is really 0 or if the key is absent πŸ€”
Maybe it's no issue the way it's used... And I don't really have a better proposal other than throwing

Object[] thisBuckets = this.buckets;

int hash = _hash(tag);
int bucketIndex = hash & (thisBuckets.length - 1);
Copy link
Contributor

Choose a reason for hiding this comment

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

is the speed gain from doing a bitmask rather than a modulo worth the downside of discarding the upper bits from the hash ?

Copy link
Member

Choose a reason for hiding this comment

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

It's pretty standard to use a bitmask to get the bucket index instead of modulo. div is not cheap on cpu.
I don't understand your comment about discarding the upper bits. modulo will give the same result.
the only constraint is the power of 2 for bucket array size.

Copy link
Contributor

@vandonr vandonr Apr 7, 2025

Choose a reason for hiding this comment

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

yeah if we keep the power of two constraint it doesn't change anything, but if you use modulo you can use prime numbers for the array size, which will be better at shuffling hash bits when modulo-ed.
If you do a bitmask with a size that is a power of two, you effectively only look at the lower bits of the hash
(the most significant bits are just masked away)

Copy link
Contributor

Choose a reason for hiding this comment

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

the hashes are already "folded in two" in the _hash() function, but that's still 16 bits, of which the upper bits will rarely see the light

Copy link
Member

Choose a reason for hiding this comment

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

This is what the standard HashMap in the JDK is doing, nothing new here.

@vandonr
Copy link
Contributor

vandonr commented Apr 7, 2025

It seems it'd be relatively straightforward to keep track of the count in the map and avoid the O(n) price of computing it (or checking for emptiness), was it a deliberate choice to save to memory of the count and the operations of incrementing/decrementing it ?

@dougqh
Copy link
Contributor Author

dougqh commented Apr 9, 2025

I'll admit that the lack of count support partially is down to laziness so far. I'm happy to try implementing it and then we can measure the impact. I'm not really worried about the extra memory - mostly just the extra code to track it, but I imagine the cost is negligible.

@dougqh dougqh requested a review from a team as a code owner May 8, 2025 20:08
@dougqh
Copy link
Contributor Author

dougqh commented May 9, 2025

It seems it'd be relatively straightforward to keep track of the count in the map and avoid the O(n) price of computing it (or checking for emptiness), was it a deliberate choice to save to memory of the count and the operations of incrementing/decrementing it ?

I've gone ahead and added the count support.

In some places updating count is O(n) itself because of needing to traverse the collision chain. In practice, the chain shouldn't be deep and the constant factor is small, so I think it is worthwhile change.

I did rerun my benchmarks and adding count tracking had no real impact overall.

Comment on lines +1118 to +1150
// e.g. size 0 will not work, it results in ArrayIndexOutOfBoundsException, but size 1 does
static final OptimizedTagMap EMPTY = new OptimizedTagMap(new Object[1], 0);
Copy link
Contributor

Choose a reason for hiding this comment

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

took me 30 seconds to understand why it says "size 0 will not work" and just after we pass 0 to the size parameter. The comment refers to the size of the buckets array. Maybe the comment can be rephrased to be understood more easily.

@dougqh dougqh requested a review from a team as a code owner May 29, 2025 19:26
@AlexeyKuznetsov-DD AlexeyKuznetsov-DD self-requested a review May 30, 2025 17:08
This change introduces TagMap as replacement for HashMap when working with tags.
TagMap has two different implementations...
- one that extends a regular HashMap
- another that uses a different approach that allows for Entry sharing

This change currently uses the HashMap approach by default, but allows for switching to the optimized Map
via a configuration flag.

The optimized TagMap is designed to be good at operations that the tracer performs regularly but HashMap
isn't great at.  Specifically, Map-to-Map copies and storing primitives.

To get the benefit of the optimized TagMap, calling code needs to use TagMap-s for both the source and destination map.
The calling code also needs to make sure to use the bulk operations that which are the most optimized.

To take advantage of TagMap in span creation, a mechanism was introduced that allows for bypassing TagInterceptors.
Bypassing TagInterceptors is done by analyzing a TagMap that is going to be reused ahead-of-time to determine if
interception is needed.  If interception isn't needed, then SpanBuilder can use a bulk operation to update the map.

To maintain the insertion order semantics of SpanBuilder, TagMap also includes a Ledger.
A Ledger is concatenative ledger of entry modifications to a map
A Ledger is now used in place of a LinkedHashMap in SpanBuilder to provide the insertion order semantics.

Since these changes primarily serve to reduce allocation, they should the biggest gain in memory constrained environments.
In memory constrained environments, these changes yield a 10% increase in sustainable throughput with spring-petclinic.
@dougqh dougqh force-pushed the dougqh/interceptor-bypass branch from 05204f1 to 98f71f6 Compare July 15, 2025 13:58
@dougqh dougqh merged commit d9df78f into master Jul 15, 2025
550 checks passed
@dougqh dougqh deleted the dougqh/interceptor-bypass branch July 15, 2025 16:20
@github-actions github-actions bot added this to the 1.52.0 milestone Jul 15, 2025
mhlidd pushed a commit that referenced this pull request Jul 17, 2025
This change introduces TagMap as replacement for HashMap when working with tags.
TagMap has two different implementations...
- one that extends a regular HashMap
- another that uses a different approach that allows for Entry sharing

This change currently uses the HashMap approach by default, but allows for switching to the optimized Map
via a configuration flag.

The optimized TagMap is designed to be good at operations that the tracer performs regularly but HashMap
isn't great at.  Specifically, Map-to-Map copies and storing primitives.

To get the benefit of the optimized TagMap, calling code needs to use TagMap-s for both the source and destination map.
The calling code also needs to make sure to use the bulk operations that which are the most optimized.

To take advantage of TagMap in span creation, a mechanism was introduced that allows for bypassing TagInterceptors.
Bypassing TagInterceptors is done by analyzing a TagMap that is going to be reused ahead-of-time to determine if
interception is needed.  If interception isn't needed, then SpanBuilder can use a bulk operation to update the map.

To maintain the insertion order semantics of SpanBuilder, TagMap also includes a Ledger.
A Ledger is concatenative ledger of entry modifications to a map
A Ledger is now used in place of a LinkedHashMap in SpanBuilder to provide the insertion order semantics.

Since these changes primarily serve to reduce allocation, they should the biggest gain in memory constrained environments.
In memory constrained environments, these changes yield a 10% increase in sustainable throughput with spring-petclinic.
@mcculls mcculls changed the title Incorporating TagMap into the tracer Reduce overhead from constructing spans by switching to optimized TagMap Aug 4, 2025
@mcculls mcculls changed the title Reduce overhead from constructing spans by switching to optimized TagMap Reduce span construction overhead by switching to optimized TagMap Aug 4, 2025
svc-squareup-copybara pushed a commit to cashapp/misk that referenced this pull request Aug 5, 2025
| Package | Type | Package file | Manager | Update | Change |
|---|---|---|---|---|---|
| [redis.clients:jedis](https://github.com/redis/jedis) | dependencies |
misk/gradle/libs.versions.toml | gradle | minor | `6.0.0` -> `6.1.0` |
|
[com.google.api.grpc:proto-google-common-protos](https://github.com/googleapis/sdk-platform-java)
| dependencies | misk/gradle/libs.versions.toml | gradle | minor |
`2.59.2` -> `2.60.0` |
|
[com.google.cloud:google-cloud-core-http](https://github.com/googleapis/sdk-platform-java)
| dependencies | misk/gradle/libs.versions.toml | gradle | minor |
`2.58.2` -> `2.59.0` |
|
[com.google.cloud:google-cloud-core](https://github.com/googleapis/sdk-platform-java)
| dependencies | misk/gradle/libs.versions.toml | gradle | minor |
`2.58.2` -> `2.59.0` |
| [com.google.api:gax](https://github.com/googleapis/sdk-platform-java)
| dependencies | misk/gradle/libs.versions.toml | gradle | minor |
`2.68.2` -> `2.69.0` |
| [com.squareup.wire](https://github.com/square/wire) | plugin |
misk/gradle/libs.versions.toml | gradle | patch | `5.3.5` -> `5.3.6` |
| [com.squareup.wire:wire-schema](https://github.com/square/wire) |
dependencies | misk/gradle/libs.versions.toml | gradle | patch | `5.3.5`
-> `5.3.6` |
| [com.squareup.wire:wire-runtime](https://github.com/square/wire) |
dependencies | misk/gradle/libs.versions.toml | gradle | patch | `5.3.5`
-> `5.3.6` |
| [com.squareup.wire:wire-reflector](https://github.com/square/wire) |
dependencies | misk/gradle/libs.versions.toml | gradle | patch | `5.3.5`
-> `5.3.6` |
| [com.squareup.wire:wire-moshi-adapter](https://github.com/square/wire)
| dependencies | misk/gradle/libs.versions.toml | gradle | patch |
`5.3.5` -> `5.3.6` |
| [com.squareup.wire:wire-grpc-client](https://github.com/square/wire) |
dependencies | misk/gradle/libs.versions.toml | gradle | patch | `5.3.5`
-> `5.3.6` |
| [com.squareup.wire:wire-bom](https://github.com/square/wire) |
dependencies | misk/gradle/libs.versions.toml | gradle | patch | `5.3.5`
-> `5.3.6` |
| [com.datadoghq:dd-trace-api](https://github.com/datadog/dd-trace-java)
| dependencies | misk/gradle/libs.versions.toml | gradle | minor |
`1.51.2` -> `1.52.0` |
| [software.amazon.awssdk:sdk-core](https://aws.amazon.com/sdkforjava) |
dependencies | misk/gradle/libs.versions.toml | gradle | patch |
`2.32.14` -> `2.32.15` |
| [software.amazon.awssdk:sqs](https://aws.amazon.com/sdkforjava) |
dependencies | misk/gradle/libs.versions.toml | gradle | patch |
`2.32.14` -> `2.32.15` |
| [software.amazon.awssdk:regions](https://aws.amazon.com/sdkforjava) |
dependencies | misk/gradle/libs.versions.toml | gradle | patch |
`2.32.14` -> `2.32.15` |
|
[software.amazon.awssdk:dynamodb-enhanced](https://aws.amazon.com/sdkforjava)
| dependencies | misk/gradle/libs.versions.toml | gradle | patch |
`2.32.14` -> `2.32.15` |
| [software.amazon.awssdk:dynamodb](https://aws.amazon.com/sdkforjava) |
dependencies | misk/gradle/libs.versions.toml | gradle | patch |
`2.32.14` -> `2.32.15` |
| [software.amazon.awssdk:aws-core](https://aws.amazon.com/sdkforjava) |
dependencies | misk/gradle/libs.versions.toml | gradle | patch |
`2.32.14` -> `2.32.15` |
| [software.amazon.awssdk:bom](https://aws.amazon.com/sdkforjava) |
dependencies | misk/gradle/libs.versions.toml | gradle | patch |
`2.32.14` -> `2.32.15` |
| [software.amazon.awssdk:auth](https://aws.amazon.com/sdkforjava) |
dependencies | misk/gradle/libs.versions.toml | gradle | patch |
`2.32.14` -> `2.32.15` |

---

### Release Notes

<details>
<summary>redis/jedis (redis.clients:jedis)</summary>

### [`v6.1.0`](https://github.com/redis/jedis/releases/tag/v6.1.0):
6.1.0

### Changes

#### πŸš€ New Features

- Add support for SVS-VAMANA vector indexing
([#&#8203;4222](redis/jedis#4222))
- Clarify why new stream entries aren't deleted with XDELEX
([#&#8203;4218](redis/jedis#4218))
- Add support for new stream commands
([#&#8203;4211](redis/jedis#4211))
- Add Support for New BITOP Operations in Redis 8.2
([#&#8203;4188](redis/jedis#4188))
([#&#8203;4190](redis/jedis#4190))
- Add binary stream support for XREAD and XREADGROUP
([#&#8203;3566](redis/jedis#3566))
([#&#8203;4152](redis/jedis#4152))
- Run pipeline in current thread if all the keys on same node
([#&#8203;4149](redis/jedis#4149))

#### πŸ› Bug Fixes

- Restore binary compatibility of SetParams
([#&#8203;4225](redis/jedis#4225))
- Fix memory leak in JedisClusterInfoCache - replica nodes not cleared
([#&#8203;4205](redis/jedis#4205))
- Fix:JedisCluster throws NullPointerException when maxAttempts is set
to 0 ([#&#8203;4186](redis/jedis#4186))

#### 🧰 Maintenance

- DOC-5471 time series doc examples
([#&#8203;4210](redis/jedis#4210))
- Bump jackson.version from 2.19.1 to 2.19.2
([#&#8203;4208](redis/jedis#4208))
- Fix flaky test ClientCommandsTest.killSkipmeYesNo
([#&#8203;4206](redis/jedis#4206))
- Bump org.junit:junit-bom from 5.13.2 to 5.13.3
([#&#8203;4198](redis/jedis#4198))
- Migrate publishing to Maven Central Portal
([#&#8203;4199](redis/jedis#4199))
- Bump org.apache.maven.plugins:maven-gpg-plugin from 3.2.7 to 3.2.8
([#&#8203;4197](redis/jedis#4197))
- Bump org.junit:junit-bom from 5.13.1 to 5.13.2
([#&#8203;4192](redis/jedis#4192))
- DOC-5227 added probabilistic data type examples
([#&#8203;4184](redis/jedis#4184))
- Bump jackson.version from 2.19.0 to 2.19.1
([#&#8203;4180](redis/jedis#4180))
- Update test infra to use latest Redis
([#&#8203;4179](redis/jedis#4179))
- Bump org.junit:junit-bom from 5.13.0-RC1 to 5.13.1
([#&#8203;4174](redis/jedis#4174))
- Bump org.json:json from
[`2025010`](redis/jedis@20250107) to
[`2025051`](redis/jedis@20250517)
([#&#8203;4171](redis/jedis#4171))
- Bump org.apache.httpcomponents.client5:httpclient5-fluent from 5.4.4
to 5.5 ([#&#8203;4170](redis/jedis#4170))
- Fix flaky tests in DocumentTest
([#&#8203;3617](redis/jedis#3617))
- Add retryable command execution example
([#&#8203;3780](redis/jedis#3780))
- Bump jackson.version from 2.18.3 to 2.19.0
([#&#8203;4160](redis/jedis#4160))
- Bump com.google.code.gson:gson from 2.12.1 to 2.13.1
([#&#8203;4161](redis/jedis#4161))

#### Contributors

We'd like to thank all the contributors who worked on this release!

[@&#8203;219sansim](https://github.com/219sansim),
[@&#8203;YoHanKi](https://github.com/YoHanKi),
[@&#8203;andy-stark-redis](https://github.com/andy-stark-redis),
[@&#8203;ggivo](https://github.com/ggivo),
[@&#8203;jujn](https://github.com/jujn),
[@&#8203;thachlp](https://github.com/thachlp),
[@&#8203;uglide](https://github.com/uglide) and
[@&#8203;xrayw](https://github.com/xrayw)

</details>

<details>
<summary>googleapis/sdk-platform-java
(com.google.api.grpc:proto-google-common-protos)</summary>

###
[`v2.60.0`](https://github.com/googleapis/sdk-platform-java/blob/HEAD/CHANGELOG.md#2600-2025-06-23)

##### Features

- handle auto pagination for BigQuery v2
([#&#8203;3829](googleapis/sdk-platform-java#3829))
([025c84c](googleapis/sdk-platform-java@025c84c))

##### Dependencies

- update google auth library dependencies to v1.37.1
([#&#8203;3846](googleapis/sdk-platform-java#3846))
([ea1d9e5](googleapis/sdk-platform-java@ea1d9e5))
- update google http client dependencies to v1.47.1
([#&#8203;3848](googleapis/sdk-platform-java#3848))
([a9a39d7](googleapis/sdk-platform-java@a9a39d7))

</details>

<details>
<summary>square/wire (com.squareup.wire)</summary>

###
[`v5.3.6`](https://github.com/square/wire/blob/HEAD/CHANGELOG.md#Version-536)

[Compare Source](square/wire@5.3.5...5.3.6)

*2025-08-05*

##### CLI

- New CLI option `--ignore_unused_roots_and_prunes`
([#&#8203;3354](square/wire#3354))

##### JVM

- Fix: Handle negative hexadecimal in default values
([#&#8203;3355](square/wire#3355))
- Optimization: Avoid copying of repeated and map types when
mutableTypes are being used
([#&#8203;3352](square/wire#3352) by \[Rahul
Ravikumar]\[tikurahul])

##### Swift

- Fix: Properly disambiguate OneOf enum if it has the same name as
enclosing type
([#&#8203;3350](square/wire#3350) by
\[Dimitris Koutsogiorgas]\[dnkoutso])

</details>

<details>
<summary>datadog/dd-trace-java (com.datadoghq:dd-trace-api)</summary>

###
[`v1.52.0`](https://github.com/DataDog/dd-trace-java/releases/tag/v1.52.0):
1.52.0

### Components

#### Application Security Management (WAF)

- ✨ Only report ASM\_DD, ASM\_DATA and ASM capabilities when
AppSec is enabled
([#&#8203;9260](DataDog/dd-trace-java#9260) -
[@&#8203;manuel-alvarez-alvarez](https://github.com/manuel-alvarez-alvarez))
- πŸ› Fix NPE in AppSecConfigServiceImpl
([#&#8203;9165](DataDog/dd-trace-java#9165) -
[@&#8203;manuel-alvarez-alvarez](https://github.com/manuel-alvarez-alvarez))
- πŸ› Fix AppSec play.mvc.StatusHeader instrumentation for play 2.6
([#&#8203;9160](DataDog/dd-trace-java#9160) -
[@&#8203;manuel-alvarez-alvarez](https://github.com/manuel-alvarez-alvarez))

#### Build & Tooling

- βœ¨πŸ“– Automatically register crashtracking via native
extensions
([#&#8203;8851](DataDog/dd-trace-java#8851) -
[@&#8203;MattAlp](https://github.com/MattAlp))

#### Configuration at Runtime

- ✨ Create activation origin config for telemetry
([#&#8203;9064](DataDog/dd-trace-java#9064) -
[@&#8203;sezen-datadog](https://github.com/sezen-datadog))

#### Continuous Integration Visibility

- ✨ Update GitLab provided tags
([#&#8203;9275](DataDog/dd-trace-java#9275) -
[@&#8203;daniel-mohedano](https://github.com/daniel-mohedano))
- πŸ› Fix base branch SHA usage in GitHub Actions
([#&#8203;9257](DataDog/dd-trace-java#9257) -
[@&#8203;daniel-mohedano](https://github.com/daniel-mohedano))
- ✨ Add `ci.job.id` tag
([#&#8203;9256](DataDog/dd-trace-java#9256) -
[@&#8203;daniel-mohedano](https://github.com/daniel-mohedano))
- ✨ Add new org to Weaver instrumentation
([#&#8203;9235](DataDog/dd-trace-java#9235) -
[@&#8203;daniel-mohedano](https://github.com/daniel-mohedano) - thanks
for the contribution!)
- ✨ Improve Git commit info building
([#&#8203;9210](DataDog/dd-trace-java#9210) -
[@&#8203;daniel-mohedano](https://github.com/daniel-mohedano))
- ✨ Update Attempt to Fix to v5
([#&#8203;9145](DataDog/dd-trace-java#9145) -
[@&#8203;daniel-mohedano](https://github.com/daniel-mohedano))

#### Crash tracking

- βœ¨πŸ“– Automatically register crashtracking via native
extensions
([#&#8203;8851](DataDog/dd-trace-java#8851) -
[@&#8203;MattAlp](https://github.com/MattAlp))

#### Data Streams Monitoring

- ✨ Reduce DSM CPU overheard
([#&#8203;9151](DataDog/dd-trace-java#9151) -
[@&#8203;kr-igor](https://github.com/kr-igor))
- ✨⚑ DSM optimizations for high throughput scenarios
([#&#8203;9137](DataDog/dd-trace-java#9137) -
[@&#8203;kr-igor](https://github.com/kr-igor))

#### Database Monitoring

- πŸ› Fix duplicate trace injection for SQL Server and Oracle DBM full
propagation mode
([#&#8203;9224](DataDog/dd-trace-java#9224) -
[@&#8203;lu-zhengda](https://github.com/lu-zhengda))

#### Dynamic Instrumentation

- πŸ› Add URI in string primitives
([#&#8203;9285](DataDog/dd-trace-java#9285) -
[@&#8203;jpbempel](https://github.com/jpbempel))
- ✨ Increase SourceFile tracking max queue size
([#&#8203;9271](DataDog/dd-trace-java#9271) -
[@&#8203;jpbempel](https://github.com/jpbempel))
- ✨ Add capping on SourceFile tracking queue
([#&#8203;9245](DataDog/dd-trace-java#9245) -
[@&#8203;jpbempel](https://github.com/jpbempel))
- ✨ Add third-party filtering in SourceFile tracking
([#&#8203;9205](DataDog/dd-trace-java#9205) -
[@&#8203;jpbempel](https://github.com/jpbempel))

#### ML Observability (LLMObs)

- ✨ Add methods to capture embedding and retrieval spans
([#&#8203;9297](DataDog/dd-trace-java#9297) -
[@&#8203;nayeem-kamal](https://github.com/nayeem-kamal))

#### Metrics

- ✨ Change primary client stats configuration key
([#&#8203;9196](DataDog/dd-trace-java#9196) -
[@&#8203;amarziali](https://github.com/amarziali))
- ✨ Calculate client stats also if the span kind is eligible
([#&#8203;9157](DataDog/dd-trace-java#9157) -
[@&#8203;amarziali](https://github.com/amarziali))
- ✨ Backpropagate peer tags
([#&#8203;9144](DataDog/dd-trace-java#9144) -
[@&#8203;bric3](https://github.com/bric3))
- πŸ› Make client stats reliable in case of downgrade
([#&#8203;9136](DataDog/dd-trace-java#9136) -
[@&#8203;amarziali](https://github.com/amarziali))

#### Platform components

- πŸ› Fix VM options parsing from /proc/fs
([#&#8203;9255](DataDog/dd-trace-java#9255) -
[@&#8203;PerfectSlayer](https://github.com/PerfectSlayer))

#### Profiling

- ✨ Switch profile compression to zstd default
([#&#8203;9293](DataDog/dd-trace-java#9293) -
[@&#8203;jbachorik](https://github.com/jbachorik))

- ✨ Bump ddprof to 1.29.0
([#&#8203;9262](DataDog/dd-trace-java#9262) -
[@&#8203;zhengyu123](https://github.com/zhengyu123))
- Potential memory leak and race with the JVMTI wallclock sampler by
[@&#8203;zhengyu123](https://github.com/zhengyu123) in
DataDog/java-profiler#234
- Downport async-profiler no-allocation changes by
[@&#8203;zhengyu123](https://github.com/zhengyu123) in
DataDog/java-profiler#245
- Adopt openjdk safefetch by
[@&#8203;zhengyu123](https://github.com/zhengyu123) in
DataDog/java-profiler#246
- Safe fetch 64-bit value and pointer by
[@&#8203;zhengyu123](https://github.com/zhengyu123) in
DataDog/java-profiler#247
- Rebase on Async-Profiler 4.1 by
[@&#8203;jbachorik](https://github.com/jbachorik) in
DataDog/java-profiler#252
- Patch upstream stackWalker.cpp not to fail on unaligned access by
[@&#8203;jbachorik](https://github.com/jbachorik) in
DataDog/java-profiler#218
- Remap thread id to avoid bitmap contention by
[@&#8203;zhengyu123](https://github.com/zhengyu123) in
DataDog/java-profiler#229
- Improve performance using Unsafe to activate/deactivate thread filter
by [@&#8203;zhengyu123](https://github.com/zhengyu123) in
DataDog/java-profiler#230
- Unify context propagation by
[@&#8203;zhengyu123](https://github.com/zhengyu123) in
DataDog/java-profiler#231

- πŸ› Fix the profiler stackdepth setting propagation in recent (22+)
Java versions
([#&#8203;9130](DataDog/dd-trace-java#9130) -
[@&#8203;jbachorik](https://github.com/jbachorik))

#### Realtime User Monitoring

- ✨ Wrap servlet original PrintWriter on rum injector
([#&#8203;9146](DataDog/dd-trace-java#9146) -
[@&#8203;amarziali](https://github.com/amarziali))

#### Telemetry

- ✨ Create activation origin config for telemetry
([#&#8203;9064](DataDog/dd-trace-java#9064) -
[@&#8203;sezen-datadog](https://github.com/sezen-datadog))

#### Tracer core

- ✨⚑ Reduce span construction overhead by switching to
optimized TagMap
([#&#8203;8589](DataDog/dd-trace-java#8589) -
[@&#8203;dougqh](https://github.com/dougqh))
- πŸ› Match Hands Off Config selectors on process\_arguments value
([#&#8203;9201](DataDog/dd-trace-java#9201) -
[@&#8203;paullegranddc](https://github.com/paullegranddc))
- ✨ Move JSON generation to sender thread to improve startup
time.
([#&#8203;9197](DataDog/dd-trace-java#9197) -
[@&#8203;AlexeyKuznetsov-DD](https://github.com/AlexeyKuznetsov-DD))
- ✨ Improve agent to avoid loading global config on main thread
([#&#8203;9190](DataDog/dd-trace-java#9190) -
[@&#8203;PerfectSlayer](https://github.com/PerfectSlayer))
- ✨ add injection metadata fields to telemetry forwarder
([#&#8203;9185](DataDog/dd-trace-java#9185) -
[@&#8203;sydney-tung](https://github.com/sydney-tung))
- πŸ› Avoid race conditions on feature discovery during Writer
creation
([#&#8203;9173](DataDog/dd-trace-java#9173) -
[@&#8203;daniel-mohedano](https://github.com/daniel-mohedano))
- ✨ Surface potential root cause when agent initialization
errors
([#&#8203;9170](DataDog/dd-trace-java#9170) -
[@&#8203;AlexeyKuznetsov-DD](https://github.com/AlexeyKuznetsov-DD))
- πŸ’‘ Support adding W3C baggage as span tags
([#&#8203;9169](DataDog/dd-trace-java#9169) -
[@&#8203;rachelyangdog](https://github.com/rachelyangdog))
- ✨⚑ Align our default classloader excludes with OTel
([#&#8203;9161](DataDog/dd-trace-java#9161) -
[@&#8203;mcculls](https://github.com/mcculls))
- ✨ Backpropagate container tags hash coming from the info
endpoint
([#&#8203;9156](DataDog/dd-trace-java#9156) -
[@&#8203;amarziali](https://github.com/amarziali))
- πŸ› Avoid race conditions and multiple agent discovery feature
states
([#&#8203;9135](DataDog/dd-trace-java#9135) -
[@&#8203;amarziali](https://github.com/amarziali))

### Instrumentations

#### AWS SDK instrumentation

- ✨ Enhance Service Representation for Serverless
([#&#8203;9203](DataDog/dd-trace-java#9203) -
[@&#8203;zarirhamza](https://github.com/zarirhamza))

#### gRPC instrumentation

- πŸ› Add check to prevent injection of repeated GRPC headers
([#&#8203;9246](DataDog/dd-trace-java#9246) -
[@&#8203;mhlidd](https://github.com/mhlidd))

#### JDBC instrumentation

- πŸ› Fix duplicate trace injection for SQL Server and Oracle DBM full
propagation mode
([#&#8203;9224](DataDog/dd-trace-java#9224) -
[@&#8203;lu-zhengda](https://github.com/lu-zhengda))

#### Play Framework instrumentation

- πŸ› Fix AppSec play.mvc.StatusHeader instrumentation for play 2.6
([#&#8203;9160](DataDog/dd-trace-java#9160) -
[@&#8203;manuel-alvarez-alvarez](https://github.com/manuel-alvarez-alvarez))

</details>

---

### Configuration

πŸ“… **Schedule**: Branch creation - "after 6pm every weekday,before 2am
every weekday" in timezone Australia/Melbourne, Automerge - At any time
(no schedule defined).

🚦 **Automerge**: Enabled.

β™» **Rebasing**: Never, or you tick the rebase/retry checkbox.

πŸ‘» **Immortal**: This PR will be recreated if closed unmerged. Get
[config help](https://github.com/renovatebot/renovate/discussions) if
that's undesired.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR has been generated by [Renovate
Bot](https://github.com/renovatebot/renovate).

GitOrigin-RevId: 9da36329ffa552291a640381780b608ef6513e29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
comp: core Tracer core tag: performance Performance related changes type: enhancement Enhancements and improvements
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants