Skip to content

Reducing memory allocation from client-side stats#10705

Merged
gh-worker-dd-mergequeue-cf854d[bot] merged 8 commits intomasterfrom
dougqh/client-side-stats-overhead
Mar 11, 2026
Merged

Reducing memory allocation from client-side stats#10705
gh-worker-dd-mergequeue-cf854d[bot] merged 8 commits intomasterfrom
dougqh/client-side-stats-overhead

Conversation

@dougqh
Copy link
Copy Markdown
Contributor

@dougqh dougqh commented Feb 27, 2026

What Does This Do

Introduces DDCache-s around UTF8BytesString construction

Motivation

UTF8BytesString are advantageous for serialization, but that only applies to the MetricKey instance that is actually serialized

Most MetricKey instances are only created to do a look-up into the map. so the UTF8BytesString creation was just extra work

This change reduces allocation by 6% and GC time by 7% in span creation stress test.
This change reduces impact on application throughput by 5-20% depending on heap size.

Additional Notes

This change is intended as a quick fix. I think there's still a lot of room for improvement by restructuring the code further, but that is left for a future PR.

Contributor Checklist

Jira ticket: [PROJ-IDENT]

Note: Once your PR is ready to merge, add it to the merge queue by commenting /merge. /merge -c cancels the queue request. /merge -f --reason "reason" skips all merge queue checks; please use this judiciously, as some checks do not run at the PR-level. For more information, see this doc.

Introduced DDCache-s around UTF8BytesString construction

UTF8BytesString are advantageous for serialization, but that only applies to the key instance that is actually serialized

Most key instances here are being created to do a look-up into the map. so the UTF8BytesString creation was extra work.

This change is intended as a quick fix.  I think there's still a lot of room for improvement by restructuring the code further, but that is left for a future PR.

As is this changer reduces the impact on application throughput by 5-20% depending on the heap size.
@dougqh dougqh requested a review from a team as a code owner February 27, 2026 21:19
@dougqh dougqh requested a review from amarziali February 27, 2026 21:19
@dougqh dougqh added type: enhancement Enhancements and improvements tag: performance Performance related changes comp: metrics Metrics labels Feb 27, 2026
@pr-commenter
Copy link
Copy Markdown

pr-commenter bot commented Feb 27, 2026

Benchmarks

Startup

Parameters

Baseline Candidate
baseline_or_candidate baseline candidate
git_branch master dougqh/client-side-stats-overhead
git_commit_date 1773240310 1773247913
git_commit_sha 92d7ae6 4098c5d
release_version 1.61.0-SNAPSHOT~92d7ae699c 1.60.0-SNAPSHOT~4098c5d13e
See matching parameters
Baseline Candidate
application insecure-bank insecure-bank
ci_job_date 1773249799 1773249799
ci_job_id 1497518477 1497518477
ci_pipeline_id 101939042 101939042
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-ey1tes3i 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-ey1tes3i 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 61 metrics, 10 unstable metrics.

Startup time reports for petclinic
gantt
    title petclinic - global startup overhead: candidate=1.60.0-SNAPSHOT~4098c5d13e, baseline=1.61.0-SNAPSHOT~92d7ae699c

    dateFormat X
    axisFormat %s
section tracing
Agent [baseline] (1.068 s) : 0, 1068378
Total [baseline] (11.09 s) : 0, 11090408
Agent [candidate] (1.065 s) : 0, 1065068
Total [candidate] (11.043 s) : 0, 11043042
section appsec
Agent [baseline] (1.247 s) : 0, 1247380
Total [baseline] (11.137 s) : 0, 11137446
Agent [candidate] (1.249 s) : 0, 1249124
Total [candidate] (11.159 s) : 0, 11158836
section iast
Agent [baseline] (1.227 s) : 0, 1226988
Total [baseline] (11.326 s) : 0, 11326187
Agent [candidate] (1.237 s) : 0, 1236577
Total [candidate] (11.416 s) : 0, 11415590
section profiling
Agent [baseline] (1.183 s) : 0, 1183285
Total [baseline] (10.95 s) : 0, 10950418
Agent [candidate] (1.182 s) : 0, 1181968
Total [candidate] (11.004 s) : 0, 11004273
Loading
  • baseline results
Module Variant Duration Δ tracing
Agent tracing 1.068 s -
Agent appsec 1.247 s 179.002 ms (16.8%)
Agent iast 1.227 s 158.61 ms (14.8%)
Agent profiling 1.183 s 114.907 ms (10.8%)
Total tracing 11.09 s -
Total appsec 11.137 s 47.039 ms (0.4%)
Total iast 11.326 s 235.78 ms (2.1%)
Total profiling 10.95 s -139.99 ms (-1.3%)
  • candidate results
Module Variant Duration Δ tracing
Agent tracing 1.065 s -
Agent appsec 1.249 s 184.056 ms (17.3%)
Agent iast 1.237 s 171.51 ms (16.1%)
Agent profiling 1.182 s 116.901 ms (11.0%)
Total tracing 11.043 s -
Total appsec 11.159 s 115.794 ms (1.0%)
Total iast 11.416 s 372.547 ms (3.4%)
Total profiling 11.004 s -38.77 ms (-0.4%)
gantt
    title petclinic - break down per module: candidate=1.60.0-SNAPSHOT~4098c5d13e, baseline=1.61.0-SNAPSHOT~92d7ae699c

    dateFormat X
    axisFormat %s
section tracing
crashtracking [baseline] (1.21 ms) : 0, 1210
crashtracking [candidate] (1.221 ms) : 0, 1221
BytebuddyAgent [baseline] (632.319 ms) : 0, 632319
BytebuddyAgent [candidate] (631.648 ms) : 0, 631648
AgentMeter [baseline] (29.379 ms) : 0, 29379
AgentMeter [candidate] (29.366 ms) : 0, 29366
GlobalTracer [baseline] (258.967 ms) : 0, 258967
GlobalTracer [candidate] (258.459 ms) : 0, 258459
AppSec [baseline] (31.859 ms) : 0, 31859
AppSec [candidate] (31.819 ms) : 0, 31819
Debugger [baseline] (59.839 ms) : 0, 59839
Debugger [candidate] (59.807 ms) : 0, 59807
Remote Config [baseline] (595.538 µs) : 0, 596
Remote Config [candidate] (592.628 µs) : 0, 593
Telemetry [baseline] (8.709 ms) : 0, 8709
Telemetry [candidate] (8.677 ms) : 0, 8677
Flare Poller [baseline] (9.344 ms) : 0, 9344
Flare Poller [candidate] (7.198 ms) : 0, 7198
section appsec
crashtracking [baseline] (1.21 ms) : 0, 1210
crashtracking [candidate] (1.197 ms) : 0, 1197
BytebuddyAgent [baseline] (658.031 ms) : 0, 658031
BytebuddyAgent [candidate] (659.853 ms) : 0, 659853
AgentMeter [baseline] (12.075 ms) : 0, 12075
AgentMeter [candidate] (12.019 ms) : 0, 12019
GlobalTracer [baseline] (258.948 ms) : 0, 258948
GlobalTracer [candidate] (258.905 ms) : 0, 258905
AppSec [baseline] (177.714 ms) : 0, 177714
AppSec [candidate] (177.84 ms) : 0, 177840
Debugger [baseline] (65.943 ms) : 0, 65943
Debugger [candidate] (65.684 ms) : 0, 65684
Remote Config [baseline] (567.68 µs) : 0, 568
Remote Config [candidate] (571.107 µs) : 0, 571
Telemetry [baseline] (9.009 ms) : 0, 9009
Telemetry [candidate] (9.081 ms) : 0, 9081
Flare Poller [baseline] (3.571 ms) : 0, 3571
Flare Poller [candidate] (3.591 ms) : 0, 3591
IAST [baseline] (23.999 ms) : 0, 23999
IAST [candidate] (24.022 ms) : 0, 24022
section iast
crashtracking [baseline] (1.186 ms) : 0, 1186
crashtracking [candidate] (1.227 ms) : 0, 1227
BytebuddyAgent [baseline] (795.824 ms) : 0, 795824
BytebuddyAgent [candidate] (802.859 ms) : 0, 802859
AgentMeter [baseline] (11.375 ms) : 0, 11375
AgentMeter [candidate] (11.632 ms) : 0, 11632
GlobalTracer [baseline] (247.138 ms) : 0, 247138
GlobalTracer [candidate] (249.049 ms) : 0, 249049
AppSec [baseline] (26.476 ms) : 0, 26476
AppSec [candidate] (26.625 ms) : 0, 26625
Debugger [baseline] (64.663 ms) : 0, 64663
Debugger [candidate] (64.004 ms) : 0, 64004
Remote Config [baseline] (538.021 µs) : 0, 538
Remote Config [candidate] (553.931 µs) : 0, 554
Telemetry [baseline] (14.15 ms) : 0, 14150
Telemetry [candidate] (14.557 ms) : 0, 14557
Flare Poller [baseline] (4.307 ms) : 0, 4307
Flare Poller [candidate] (4.571 ms) : 0, 4571
IAST [baseline] (25.139 ms) : 0, 25139
IAST [candidate] (25.331 ms) : 0, 25331
section profiling
crashtracking [baseline] (1.179 ms) : 0, 1179
crashtracking [candidate] (1.179 ms) : 0, 1179
BytebuddyAgent [baseline] (683.451 ms) : 0, 683451
BytebuddyAgent [candidate] (682.516 ms) : 0, 682516
AgentMeter [baseline] (8.609 ms) : 0, 8609
AgentMeter [candidate] (8.609 ms) : 0, 8609
GlobalTracer [baseline] (215.802 ms) : 0, 215802
GlobalTracer [candidate] (215.777 ms) : 0, 215777
AppSec [baseline] (32.064 ms) : 0, 32064
AppSec [candidate] (31.98 ms) : 0, 31980
Debugger [baseline] (64.592 ms) : 0, 64592
Debugger [candidate] (61.369 ms) : 0, 61369
Remote Config [baseline] (579.375 µs) : 0, 579
Remote Config [candidate] (581.988 µs) : 0, 582
Telemetry [baseline] (8.977 ms) : 0, 8977
Telemetry [candidate] (11.37 ms) : 0, 11370
Flare Poller [baseline] (3.442 ms) : 0, 3442
Flare Poller [candidate] (4.26 ms) : 0, 4260
ProfilingAgent [baseline] (93.748 ms) : 0, 93748
ProfilingAgent [candidate] (93.452 ms) : 0, 93452
Profiling [baseline] (94.306 ms) : 0, 94306
Profiling [candidate] (94.011 ms) : 0, 94011
Loading
Startup time reports for insecure-bank
gantt
    title insecure-bank - global startup overhead: candidate=1.60.0-SNAPSHOT~4098c5d13e, baseline=1.61.0-SNAPSHOT~92d7ae699c

    dateFormat X
    axisFormat %s
section tracing
Agent [baseline] (1.061 s) : 0, 1061113
Total [baseline] (8.835 s) : 0, 8834857
Agent [candidate] (1.057 s) : 0, 1057104
Total [candidate] (8.839 s) : 0, 8839384
section iast
Agent [baseline] (1.226 s) : 0, 1226073
Total [baseline] (9.558 s) : 0, 9558086
Agent [candidate] (1.234 s) : 0, 1233754
Total [candidate] (9.621 s) : 0, 9620848
Loading
  • baseline results
Module Variant Duration Δ tracing
Agent tracing 1.061 s -
Agent iast 1.226 s 164.96 ms (15.5%)
Total tracing 8.835 s -
Total iast 9.558 s 723.229 ms (8.2%)
  • candidate results
Module Variant Duration Δ tracing
Agent tracing 1.057 s -
Agent iast 1.234 s 176.65 ms (16.7%)
Total tracing 8.839 s -
Total iast 9.621 s 781.465 ms (8.8%)
gantt
    title insecure-bank - break down per module: candidate=1.60.0-SNAPSHOT~4098c5d13e, baseline=1.61.0-SNAPSHOT~92d7ae699c

    dateFormat X
    axisFormat %s
section tracing
crashtracking [baseline] (1.196 ms) : 0, 1196
crashtracking [candidate] (1.208 ms) : 0, 1208
BytebuddyAgent [baseline] (628.772 ms) : 0, 628772
BytebuddyAgent [candidate] (628.239 ms) : 0, 628239
AgentMeter [baseline] (29.118 ms) : 0, 29118
AgentMeter [candidate] (29.109 ms) : 0, 29109
GlobalTracer [baseline] (257.368 ms) : 0, 257368
GlobalTracer [candidate] (257.285 ms) : 0, 257285
AppSec [baseline] (31.585 ms) : 0, 31585
AppSec [candidate] (31.519 ms) : 0, 31519
Debugger [baseline] (58.833 ms) : 0, 58833
Debugger [candidate] (58.77 ms) : 0, 58770
Remote Config [baseline] (587.007 µs) : 0, 587
Remote Config [candidate] (588.375 µs) : 0, 588
Telemetry [baseline] (8.661 ms) : 0, 8661
Telemetry [candidate] (8.607 ms) : 0, 8607
Flare Poller [baseline] (8.842 ms) : 0, 8842
Flare Poller [candidate] (5.688 ms) : 0, 5688
section iast
crashtracking [baseline] (1.194 ms) : 0, 1194
crashtracking [candidate] (1.221 ms) : 0, 1221
BytebuddyAgent [baseline] (795.473 ms) : 0, 795473
BytebuddyAgent [candidate] (800.805 ms) : 0, 800805
AgentMeter [baseline] (11.328 ms) : 0, 11328
AgentMeter [candidate] (11.577 ms) : 0, 11577
GlobalTracer [baseline] (247.567 ms) : 0, 247567
GlobalTracer [candidate] (248.606 ms) : 0, 248606
AppSec [baseline] (26.32 ms) : 0, 26320
AppSec [candidate] (26.513 ms) : 0, 26513
Debugger [baseline] (62.824 ms) : 0, 62824
Debugger [candidate] (63.021 ms) : 0, 63021
Remote Config [baseline] (544.43 µs) : 0, 544
Remote Config [candidate] (542.615 µs) : 0, 543
Telemetry [baseline] (15.334 ms) : 0, 15334
Telemetry [candidate] (15.395 ms) : 0, 15395
Flare Poller [baseline] (4.388 ms) : 0, 4388
Flare Poller [candidate] (4.622 ms) : 0, 4622
IAST [baseline] (25.056 ms) : 0, 25056
IAST [candidate] (25.277 ms) : 0, 25277
Loading

Load

Parameters

Baseline Candidate
baseline_or_candidate baseline candidate
git_branch master dougqh/client-side-stats-overhead
git_commit_date 1773240310 1773247913
git_commit_sha 92d7ae6 4098c5d
release_version 1.61.0-SNAPSHOT~92d7ae699c 1.60.0-SNAPSHOT~4098c5d13e
See matching parameters
Baseline Candidate
application insecure-bank insecure-bank
ci_job_date 1773250407 1773250407
ci_job_id 1497518478 1497518478
ci_pipeline_id 101939042 101939042
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-6wtti6lk 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-6wtti6lk 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 2 performance improvements and 2 performance regressions! Performance is the same for 15 metrics, 17 unstable metrics.

scenario Δ mean agg_http_req_duration_p50 Δ mean agg_http_req_duration_p95 Δ mean throughput candidate mean agg_http_req_duration_p50 candidate mean agg_http_req_duration_p95 candidate mean throughput baseline mean agg_http_req_duration_p50 baseline mean agg_http_req_duration_p95 baseline mean throughput
scenario:load:petclinic:code_origins:high_load worse
[+0.865ms; +1.661ms] or [+4.991%; +9.578%]
worse
[+0.890ms; +2.236ms] or [+3.123%; +7.846%]
unstable
[-42.467op/s; +12.217op/s] or [-16.214%; +4.665%]
18.604ms 30.064ms 246.781op/s 17.341ms 28.501ms 261.906op/s
scenario:load:petclinic:profiling:high_load better
[-1.444ms; -0.708ms] or [-7.559%; -3.708%]
better
[-2.364ms; -1.159ms] or [-7.639%; -3.746%]
unstable
[-13.086op/s; +38.711op/s] or [-5.447%; +16.113%]
18.032ms 29.180ms 253.062op/s 19.108ms 30.941ms 240.250op/s
Request duration reports for insecure-bank
gantt
    title insecure-bank - request duration [CI 0.99] : candidate=1.60.0-SNAPSHOT~4098c5d13e, baseline=1.61.0-SNAPSHOT~92d7ae699c
    dateFormat X
    axisFormat %s
section baseline
no_agent (1.185 ms) : 1173, 1197
.   : milestone, 1185,
iast (3.267 ms) : 3221, 3312
.   : milestone, 3267,
iast_FULL (5.792 ms) : 5734, 5850
.   : milestone, 5792,
iast_GLOBAL (3.526 ms) : 3463, 3588
.   : milestone, 3526,
profiling (2.091 ms) : 2070, 2112
.   : milestone, 2091,
tracing (1.805 ms) : 1790, 1820
.   : milestone, 1805,
section candidate
no_agent (1.219 ms) : 1205, 1233
.   : milestone, 1219,
iast (3.324 ms) : 3284, 3364
.   : milestone, 3324,
iast_FULL (5.887 ms) : 5829, 5946
.   : milestone, 5887,
iast_GLOBAL (3.53 ms) : 3474, 3586
.   : milestone, 3530,
profiling (2.005 ms) : 1985, 2025
.   : milestone, 2005,
tracing (1.845 ms) : 1827, 1862
.   : milestone, 1845,
Loading
  • baseline results
Variant Request duration [CI 0.99] Δ no_agent
no_agent 1.185 ms [1.173 ms, 1.197 ms] -
iast 3.267 ms [3.221 ms, 3.312 ms] 2.082 ms (175.7%)
iast_FULL 5.792 ms [5.734 ms, 5.85 ms] 4.607 ms (388.9%)
iast_GLOBAL 3.526 ms [3.463 ms, 3.588 ms] 2.341 ms (197.6%)
profiling 2.091 ms [2.07 ms, 2.112 ms] 906.118 µs (76.5%)
tracing 1.805 ms [1.79 ms, 1.82 ms] 620.357 µs (52.4%)
  • candidate results
Variant Request duration [CI 0.99] Δ no_agent
no_agent 1.219 ms [1.205 ms, 1.233 ms] -
iast 3.324 ms [3.284 ms, 3.364 ms] 2.105 ms (172.6%)
iast_FULL 5.887 ms [5.829 ms, 5.946 ms] 4.668 ms (382.9%)
iast_GLOBAL 3.53 ms [3.474 ms, 3.586 ms] 2.31 ms (189.5%)
profiling 2.005 ms [1.985 ms, 2.025 ms] 785.914 µs (64.5%)
tracing 1.845 ms [1.827 ms, 1.862 ms] 625.399 µs (51.3%)
Request duration reports for petclinic
gantt
    title petclinic - request duration [CI 0.99] : candidate=1.60.0-SNAPSHOT~4098c5d13e, baseline=1.61.0-SNAPSHOT~92d7ae699c
    dateFormat X
    axisFormat %s
section baseline
no_agent (18.181 ms) : 17991, 18372
.   : milestone, 18181,
appsec (18.244 ms) : 18057, 18431
.   : milestone, 18244,
code_origins (17.815 ms) : 17637, 17992
.   : milestone, 17815,
iast (17.652 ms) : 17477, 17827
.   : milestone, 17652,
profiling (19.427 ms) : 19232, 19623
.   : milestone, 19427,
tracing (17.817 ms) : 17641, 17994
.   : milestone, 17817,
section candidate
no_agent (18.234 ms) : 18048, 18421
.   : milestone, 18234,
appsec (18.702 ms) : 18516, 18887
.   : milestone, 18702,
code_origins (18.914 ms) : 18723, 19106
.   : milestone, 18914,
iast (17.78 ms) : 17603, 17958
.   : milestone, 17780,
profiling (18.443 ms) : 18261, 18624
.   : milestone, 18443,
tracing (17.874 ms) : 17698, 18050
.   : milestone, 17874,
Loading
  • baseline results
Variant Request duration [CI 0.99] Δ no_agent
no_agent 18.181 ms [17.991 ms, 18.372 ms] -
appsec 18.244 ms [18.057 ms, 18.431 ms] 63.152 µs (0.3%)
code_origins 17.815 ms [17.637 ms, 17.992 ms] -366.392 µs (-2.0%)
iast 17.652 ms [17.477 ms, 17.827 ms] -529.219 µs (-2.9%)
profiling 19.427 ms [19.232 ms, 19.623 ms] 1.246 ms (6.9%)
tracing 17.817 ms [17.641 ms, 17.994 ms] -364.006 µs (-2.0%)
  • candidate results
Variant Request duration [CI 0.99] Δ no_agent
no_agent 18.234 ms [18.048 ms, 18.421 ms] -
appsec 18.702 ms [18.516 ms, 18.887 ms] 467.173 µs (2.6%)
code_origins 18.914 ms [18.723 ms, 19.106 ms] 679.67 µs (3.7%)
iast 17.78 ms [17.603 ms, 17.958 ms] -454.031 µs (-2.5%)
profiling 18.443 ms [18.261 ms, 18.624 ms] 208.119 µs (1.1%)
tracing 17.874 ms [17.698 ms, 18.05 ms] -360.523 µs (-2.0%)

Dacapo

Parameters

Baseline Candidate
baseline_or_candidate baseline candidate
git_branch master dougqh/client-side-stats-overhead
git_commit_date 1773240310 1773247913
git_commit_sha 92d7ae6 4098c5d
release_version 1.61.0-SNAPSHOT~92d7ae699c 1.60.0-SNAPSHOT~4098c5d13e
See matching parameters
Baseline Candidate
application biojava biojava
ci_job_date 1773250129 1773250129
ci_job_id 1497518481 1497518481
ci_pipeline_id 101939042 101939042
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-emtfegaa 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-emtfegaa 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 11 metrics, 1 unstable metrics.

Execution time for tomcat
gantt
    title tomcat - execution time [CI 0.99] : candidate=1.60.0-SNAPSHOT~4098c5d13e, baseline=1.61.0-SNAPSHOT~92d7ae699c
    dateFormat X
    axisFormat %s
section baseline
no_agent (1.476 ms) : 1464, 1487
.   : milestone, 1476,
appsec (3.804 ms) : 3581, 4026
.   : milestone, 3804,
iast (2.264 ms) : 2194, 2333
.   : milestone, 2264,
iast_GLOBAL (2.311 ms) : 2241, 2381
.   : milestone, 2311,
profiling (2.11 ms) : 2053, 2168
.   : milestone, 2110,
tracing (2.087 ms) : 2032, 2141
.   : milestone, 2087,
section candidate
no_agent (1.477 ms) : 1465, 1488
.   : milestone, 1477,
appsec (3.793 ms) : 3573, 4014
.   : milestone, 3793,
iast (2.27 ms) : 2200, 2340
.   : milestone, 2270,
iast_GLOBAL (2.301 ms) : 2231, 2371
.   : milestone, 2301,
profiling (2.118 ms) : 2060, 2175
.   : milestone, 2118,
tracing (2.087 ms) : 2033, 2141
.   : milestone, 2087,
Loading
  • baseline results
Variant Execution Time [CI 0.99] Δ no_agent
no_agent 1.476 ms [1.464 ms, 1.487 ms] -
appsec 3.804 ms [3.581 ms, 4.026 ms] 2.328 ms (157.7%)
iast 2.264 ms [2.194 ms, 2.333 ms] 787.697 µs (53.4%)
iast_GLOBAL 2.311 ms [2.241 ms, 2.381 ms] 835.296 µs (56.6%)
profiling 2.11 ms [2.053 ms, 2.168 ms] 634.592 µs (43.0%)
tracing 2.087 ms [2.032 ms, 2.141 ms] 610.621 µs (41.4%)
  • candidate results
Variant Execution Time [CI 0.99] Δ no_agent
no_agent 1.477 ms [1.465 ms, 1.488 ms] -
appsec 3.793 ms [3.573 ms, 4.014 ms] 2.317 ms (156.9%)
iast 2.27 ms [2.2 ms, 2.34 ms] 793.307 µs (53.7%)
iast_GLOBAL 2.301 ms [2.231 ms, 2.371 ms] 823.913 µs (55.8%)
profiling 2.118 ms [2.06 ms, 2.175 ms] 640.72 µs (43.4%)
tracing 2.087 ms [2.033 ms, 2.141 ms] 610.165 µs (41.3%)
Execution time for biojava
gantt
    title biojava - execution time [CI 0.99] : candidate=1.60.0-SNAPSHOT~4098c5d13e, baseline=1.61.0-SNAPSHOT~92d7ae699c
    dateFormat X
    axisFormat %s
section baseline
no_agent (15.751 s) : 15751000, 15751000
.   : milestone, 15751000,
appsec (14.998 s) : 14998000, 14998000
.   : milestone, 14998000,
iast (18.048 s) : 18048000, 18048000
.   : milestone, 18048000,
iast_GLOBAL (18.261 s) : 18261000, 18261000
.   : milestone, 18261000,
profiling (14.926 s) : 14926000, 14926000
.   : milestone, 14926000,
tracing (15.127 s) : 15127000, 15127000
.   : milestone, 15127000,
section candidate
no_agent (14.954 s) : 14954000, 14954000
.   : milestone, 14954000,
appsec (14.858 s) : 14858000, 14858000
.   : milestone, 14858000,
iast (17.873 s) : 17873000, 17873000
.   : milestone, 17873000,
iast_GLOBAL (17.549 s) : 17549000, 17549000
.   : milestone, 17549000,
profiling (14.926 s) : 14926000, 14926000
.   : milestone, 14926000,
tracing (15.24 s) : 15240000, 15240000
.   : milestone, 15240000,
Loading
  • baseline results
Variant Execution Time [CI 0.99] Δ no_agent
no_agent 15.751 s [15.751 s, 15.751 s] -
appsec 14.998 s [14.998 s, 14.998 s] -753.0 ms (-4.8%)
iast 18.048 s [18.048 s, 18.048 s] 2.297 s (14.6%)
iast_GLOBAL 18.261 s [18.261 s, 18.261 s] 2.51 s (15.9%)
profiling 14.926 s [14.926 s, 14.926 s] -825.0 ms (-5.2%)
tracing 15.127 s [15.127 s, 15.127 s] -624.0 ms (-4.0%)
  • candidate results
Variant Execution Time [CI 0.99] Δ no_agent
no_agent 14.954 s [14.954 s, 14.954 s] -
appsec 14.858 s [14.858 s, 14.858 s] -96.0 ms (-0.6%)
iast 17.873 s [17.873 s, 17.873 s] 2.919 s (19.5%)
iast_GLOBAL 17.549 s [17.549 s, 17.549 s] 2.595 s (17.4%)
profiling 14.926 s [14.926 s, 14.926 s] -28.0 ms (-0.2%)
tracing 15.24 s [15.24 s, 15.24 s] 286.0 ms (1.9%)

public final class MetricKey {
static final DDCache<String, UTF8BytesString> RESOURCE_CACHE = DDCaches.newFixedSizeCache(32);
static final DDCache<String, UTF8BytesString> SERVICE_CACHE = DDCaches.newFixedSizeCache(8);
static final DDCache<String, UTF8BytesString> SERVICE_SOURCE_CACHE = DDCaches.newFixedSizeCache(4);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This should be already filled with UTF8BytesString. It can take values of the instrumentation name (that's should also be UTF8BytesString) so I suggest removing caching for this specific one. 4, is also too small

Copy link
Copy Markdown
Contributor Author

@dougqh dougqh Mar 9, 2026

Choose a reason for hiding this comment

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

The lookup logic accounts for receiving a UTF8BytesString and in that case bypasses the cache entirely.

Also, I erred on the side of keeping the caches small. I just want to eliminate most of the allocation - not all of the allocation.
That said, I may have misunderstood what "serviceSource" is so maybe that one should be larger. If it is instrumentations, then maybe we should increase it to 16. (The thinking being that only a few instrumentations are typically active in a given system.)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

If it can only be a UTF8BytesString, we could also tighten the type in the constructor. Although in that case, the JIT would dead code eliminate using the cache anyway (except for the initial allocation).

Comment on lines +18 to +21
static final DDCache<String, UTF8BytesString> TYPE_CACHE = DDCaches.newFixedSizeCache(8);
static final DDCache<String, UTF8BytesString> KIND_CACHE = DDCaches.newFixedSizeCache(8);
static final DDCache<String, UTF8BytesString> HTTP_METHOD_CACHE = DDCaches.newFixedSizeCache(8);
static final DDCache<String, UTF8BytesString> HTTP_ENDPOINT_CACHE = DDCaches.newFixedSizeCache(32);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Would it be possible to widen those a bit? Also, for the http endpoint, I'm wondering if we should just do that caching earlier to make other serialisation benefitting of this (i.e. in EndpointResolver)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I erred on the side of making the caches small.
The thinking is any object reuse is an improvement over what we were doing, but consuming too much memory could be harmful.

}

static UTF8BytesString utf8(DDCache<String, UTF8BytesString> cache, CharSequence charSeq) {
if ( charSeq == null ) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

There are things that are supposing to check nullity of this. Now if we replace with empty is not more the same semantic and this will break some code. I suggest to let the caller return the default value so it won't break the existing logic

Copy link
Copy Markdown
Contributor Author

@dougqh dougqh Mar 9, 2026

Choose a reason for hiding this comment

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

Nevermind - I see that I did accidentally change the semantics for method & endpoint. I'll fix that.

I kept the semantics that already existed. If you look at the prior code, null was replaced with EMPTY, so I did the same.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

well there are things that are OK to return empty but others needs to be literally null (i.e. service source, httpMethod, httpEndpoint)

Copy link
Copy Markdown
Contributor Author

@dougqh dougqh Mar 9, 2026

Choose a reason for hiding this comment

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

Yes, I realized after my initial reply. I'll double check all of them.

Copy link
Copy Markdown
Contributor Author

@dougqh dougqh Mar 9, 2026

Choose a reason for hiding this comment

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

Since the split of EMPTY vs null was about 50 / 50, I decided to just restore the null checks in the constructor.

dougqh added 4 commits March 9, 2026 13:19
- fix null handling for http method & endpoint
- increase service source cache size
Since it about a 50/50 split between cases that use EMPTY vs null, when a null is passed

I decided to just put the null handling back into the constructor.
That makes the choice more explicit, and makes the PR easier to review / compare to the prior logic
public final class MetricKey {
static final DDCache<String, UTF8BytesString> RESOURCE_CACHE = DDCaches.newFixedSizeCache(32);
static final DDCache<String, UTF8BytesString> SERVICE_CACHE = DDCaches.newFixedSizeCache(8);
static final DDCache<String, UTF8BytesString> SERVICE_SOURCE_CACHE =
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

That field does not need to be cached, for two main reasons:

  1. It is already either a UTF8BytesString or null. In fact, it comes from the component() method, which in helpers typically returns a UTF8BytesString.
  2. Its cardinality matches that of the instrumentations, the size of the cache is too small.

The constructor calling UTF8BytesString.create() may look confusing at first glance, but in this case it does not allocate a new object — it simply returns the existing instance. It was kept for consistency with the usual pattern.

Unless there are strong counterarguments, I would suggest removing the cache for this field.

Copy link
Copy Markdown
Contributor Author

@dougqh dougqh Mar 10, 2026

Choose a reason for hiding this comment

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

I think the key part here is "typically returns a UTF8BytesString".
The static typing doesn't currently guarantee it.

And the caching code accounts for the case of receiving a UTF8BytesString by bypassing the cache. In the same manner as UTF8BytesString.create did previously.

When a UTF8BytesString is passed, the cache incurs no overhead other than the static overhead of the cache array itself. But in the case where something other than UTF8BytesString is passed, the cache can significantly reduce memory consumption.

I think that's important because we need to curtail the worst case outcomes.

As for the size, the cardinality doesn't need to match total instrumentations. That would be too large. The size just needs to accommodate the active span producing instrumentations. As I said, I erred on the small side, since I want to avoid the worst case of consuming a lot of static memory.

And assuming a UTF8BytesString is introducing a subtle form of coupling that could easily be compromised by someone later on.

Copy link
Copy Markdown
Contributor

@amarziali amarziali left a comment

Choose a reason for hiding this comment

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

Thanks for that improvement. wrt service name source, as per our chat, we might simplify trying changing the signature of that constructor if possible and shortcut the cache if we ensure that every value is already an UTF8BytesString itself.

@dougqh dougqh enabled auto-merge March 11, 2026 12:26
@dougqh dougqh added this pull request to the merge queue Mar 11, 2026
@dd-octo-sts
Copy link
Copy Markdown
Contributor

dd-octo-sts bot commented Mar 11, 2026

/merge

@gh-worker-devflow-routing-ef8351
Copy link
Copy Markdown

gh-worker-devflow-routing-ef8351 bot commented Mar 11, 2026

View all feedbacks in Devflow UI.

2026-03-11 13:49:50 UTC ℹ️ Start processing command /merge


2026-03-11 13:49:54 UTC ℹ️ MergeQueue: waiting for PR to be ready

This pull request is not mergeable according to GitHub. Common reasons include pending required checks, missing approvals, or merge conflicts — but it could also be blocked by other repository rules or settings.
It will be added to the queue as soon as checks pass and/or get approvals. View in MergeQueue UI.
Note: if you pushed new commits since the last approval, you may need additional approval.
You can remove it from the waiting list with /remove command.


2026-03-11 14:08:16 UTC ℹ️ MergeQueue: merge request added to the queue

The expected merge time in master is approximately 2h (p90).


2026-03-11 16:03:26 UTC ℹ️ MergeQueue: Readding this merge request to the queue because another merge request processed with yours failed. No action is needed from your side.


2026-03-11 16:52:02 UTCMergeQueue: This merge request was updated

This PR is rejected because it was updated

@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to failed status checks Mar 11, 2026
Copy link
Copy Markdown
Contributor

@bric3 bric3 left a comment

Choose a reason for hiding this comment

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

Thanks for the optimization.

I think the only nitpick is comment explaining the choice of the cache sizes.

@dougqh dougqh added this pull request to the merge queue Mar 11, 2026
@dd-octo-sts
Copy link
Copy Markdown
Contributor

dd-octo-sts bot commented Mar 11, 2026

/merge

@gh-worker-devflow-routing-ef8351
Copy link
Copy Markdown

gh-worker-devflow-routing-ef8351 bot commented Mar 11, 2026

View all feedbacks in Devflow UI.

2026-03-11 18:46:39 UTC ℹ️ Start processing command /merge


2026-03-11 18:46:44 UTC ℹ️ MergeQueue: pull request added to the queue

The expected merge time in master is approximately 2h (p90).


2026-03-11 21:16:27 UTC ℹ️ MergeQueue: This merge request was merged

@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to failed status checks Mar 11, 2026
@dougqh dougqh added this pull request to the merge queue Mar 11, 2026
@dd-octo-sts
Copy link
Copy Markdown
Contributor

dd-octo-sts bot commented Mar 11, 2026

/merge

@gh-worker-devflow-routing-ef8351
Copy link
Copy Markdown

gh-worker-devflow-routing-ef8351 bot commented Mar 11, 2026

View all feedbacks in Devflow UI.

2026-03-11 19:13:49 UTC ℹ️ Start processing command /merge


2026-03-11 19:13:52 UTC ❌ MergeQueue

PR already in the queue with status queued

@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to failed status checks Mar 11, 2026
@gh-worker-dd-mergequeue-cf854d gh-worker-dd-mergequeue-cf854d bot merged commit 4368dcf into master Mar 11, 2026
575 checks passed
@gh-worker-dd-mergequeue-cf854d gh-worker-dd-mergequeue-cf854d bot deleted the dougqh/client-side-stats-overhead branch March 11, 2026 21:16
@github-actions github-actions bot added this to the 1.61.0 milestone Mar 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp: metrics Metrics tag: performance Performance related changes type: enhancement Enhancements and improvements

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants