Skip to content

bench: add plugin-graphql-long sirun benchmark#8089

Merged
BridgeAR merged 9 commits into
masterfrom
crysmags/bench-graphql-long
May 1, 2026
Merged

bench: add plugin-graphql-long sirun benchmark#8089
BridgeAR merged 9 commits into
masterfrom
crysmags/bench-graphql-long

Conversation

@crysmags

@crysmags crysmags commented Apr 23, 2026

Copy link
Copy Markdown
Collaborator

Summary

Replaces benchmark/sirun/plugin-graphql/ (6-query, startup-dominated) with benchmark/sirun/plugin-graphql-long/ (100 queries per process), so per-query cost dominates the measurement rather than one-time setup cost.

Motivated by #7757 (graphql plugin refactor), where the 6-query bench reports a regression that inverts into a large improvement under production-like workloads.

Why

The existing plugin-graphql bench fired 6 queries per process then exited. At 6 queries, load was ~80% of the CPU budget — any change that traded startup cost for steady-state cost looked like a regression on this benchmark even when it made real applications faster. Keeping the 6-query bench preserved a misleading signal that reviewers had already learned to discount, so this PR removes it outright rather than running both.

Case study: #7757 — master vs PR branch

Same sirun setup, same variants, two different process sizes (Node 22.10.0, user.time metric, median):

variant master @ 6q #7757 @ 6q Δ @ 6q master @ 100q #7757 @ 100q Δ @ 100q
with-depth-off 282.5 ms 294.4 ms 🟥 +4.2% 1632.6 ms 1210.3 ms 🟩 −25.9%
with-depth-on-max 278.0 ms 292.2 ms 🟥 +5.1% 1605.7 ms 1169.4 ms 🟩 −27.2%
with-depth-and-collapse-off 402.7 ms 449.3 ms 🟥 +11.6% 2437.9 ms 2358.2 ms 🟩 −3.3%
with-depth-and-collapse-on 280.2 ms 291.9 ms 🟥 +4.2% 1612.4 ms 1187.6 ms 🟩 −26.3%

Break-even: ~15–20 queries per process. Past that, #7757 is strictly faster. The 6-query bench was reporting only the 🟥 column.

Why load share matters

variant load share @ 6q load share @ 100q Δ
with-depth-on-max 🟥 83% 🟩 23% −60pp
with-depth-and-collapse-off 🟥 77% 🟩 16% −61pp

At QUERIES=100, load drops from 🟥 ~80% to 🟩 ~16–23% — per-query cost dominates. QUERIES is parametric so the same directory can be re-aimed at larger sizes (e.g. QUERIES=500 for load <6%) without forking.

What's in the change

  • Adds benchmark/sirun/plugin-graphql-long/:
    • index.js — parametric on QUERIES (default 100); env-var truthy checks use process.env.X so WITH_DEPTH=0 reads as configured (Codex review fix).
    • meta.json — same six variants as the old bench, iterations: 5.
    • schema.js — moved from the old plugin-graphql/ location since it's the only consumer.
    • README.md — short sibling-style description.
  • Removes benchmark/sirun/plugin-graphql/ entirely.

CI impact

benchmark/sirun/runall.sh auto-discovers subdirs (DIRS=($(ls -d */ | sed 's:/$::'))) and runs the 6 variants in parallel as backgrounded jobs pinned to separate cores ((time node ../run-one-variant.js …) &). Wall time per Node version equals the slowest variant, not the sum.

After this PR:

  • scenario:plugin-graphql-* — removed.
  • scenario:plugin-graphql-long-* — new steady-state signal.
bench per-Node wall (parallel-by-core) bottleneck variant
old plugin-graphql (6q × 30 iters) ~45 s with-depth-and-collapse-off
new plugin-graphql-long (100q × 5 iters) ~15 s with-depth-and-collapse-off

Per iteration the long bench is ~3 s for the slowest variant; 5 iterations × 1 process per iteration ≈ 15 s on the busy core. Light variants (control, async-hooks) finish in ~3 s and idle.

Test plan

  • Verified locally with sirun meta-temp.json on Node 22.10.0 / Node 25 — all 6 variants run.
  • Load/steady-state ratio measured; QUERIES=100 keeps load 🟩 ≤23% across all variants (worst case: with-depth-on-max).
  • iterations=5 chosen as the smallest count where stddev/mean stays acceptable post-warmup; confirmed in local sirun output.
  • Lint passes (eslint).

Follow-up on #7757: once this lands, #7757 will rebase to inherit the bench from master, and CI will produce comparable plugin-graphql-long-* numbers against the master baseline.

🤖 Generated with Claude Code

@github-actions

github-actions Bot commented Apr 23, 2026

Copy link
Copy Markdown
Contributor

Overall package size

Self size: 5.67 MB
Deduped: 6.52 MB
No deduping: 6.52 MB

Dependency sizes | name | version | self size | total size | |------|---------|-----------|------------| | import-in-the-middle | 3.0.1 | 82.56 kB | 817.39 kB | | dc-polyfill | 0.1.10 | 26.73 kB | 26.73 kB |

🤖 This report was automatically generated by heaviest-objects-in-the-universe

@datadog-prod-us1-4

datadog-prod-us1-4 Bot commented Apr 23, 2026

Copy link
Copy Markdown

Tests

Fix all issues with BitsAI or with Cursor

⚠️ Warnings

🧪 1 Test failed

Plugin kafkajs with kafkajs >=1.4 (1.4.0) without configuration "before each" hook for "should compute peer service" from peer service computation   View in Datadog   (Fix with Cursor)
This server does not host this topic-partition

KafkaJSProtocolError: This server does not host this topic-partition
    at createErrorFromCode (versions/[email protected]/node_modules/kafkajs/src/protocol/error.js:472:10)
    at Object.parse (versions/[email protected]/node_modules/kafkajs/src/protocol/requests/metadata/v0/response.js:56:11)
    at Connection.send (versions/[email protected]/node_modules/kafkajs/src/network/connection.js:250:35)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async Broker.metadata (versions/[email protected]/node_modules/kafkajs/src/broker/index.js:144:12)
    at async retryOnLeaderNotAvailable.delay (versions/[email protected]/node_modules/kafkajs/src/admin/index.js:98:55)
    at async callback (versions/[email protected]/node_modules/kafkajs/src/admin/index.js:20:14)
...

ℹ️ Info

No other issues found (see more)

❄️ No new flaky tests detected

🎯 Code Coverage (details)
Patch Coverage: 100.00%
Overall Coverage: 71.50% (+6.41%)

Useful? React with 👍 / 👎

This comment will be updated automatically if new data arrives.
🔗 Commit SHA: 9c18f04 | Docs | Datadog PR Page | Give us feedback!

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 91ed816b48

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines +10 to +11
if (Number(process.env.WITH_DEPTH)) {
tracer.use('graphql', { depth: Number(process.env.WITH_DEPTH) })

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Treat WITH_DEPTH=0 as a configured depth value

The with-depth-off variant in meta.json sets WITH_DEPTH="0", but this condition uses Number(process.env.WITH_DEPTH) so 0 is treated as falsy and tracer.use('graphql', { depth: 0 }) is never called. In this benchmark, that means the “depth-off” scenario runs with default GraphQL plugin settings instead of depth explicitly disabled, so this variant’s measurements are mislabeled and comparisons against other variants become unreliable.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Addressed in 9294277: switched the four env-var truthy checks (WITH_TRACER, WITH_DEPTH, WITH_ASYNC_HOOKS, QUERIES) from Number(process.env.X) to plain process.env.X. WITH_DEPTH="0" now reads as "set" and the with-depth-off variant correctly calls tracer.use('graphql', { depth: 0 }) instead of falling through to plugin defaults.

@crysmags
crysmags force-pushed the crysmags/bench-graphql-long branch 2 times, most recently from e712b5c to a1f5c1d Compare April 23, 2026 20:04
@pr-commenter

pr-commenter Bot commented Apr 23, 2026

Copy link
Copy Markdown

Benchmarks

Benchmark execution time: 2026-04-30 15:22:24

Comparing candidate commit 9c18f04 in PR branch crysmags/bench-graphql-long with baseline commit a9013ae in branch master.

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

@codecov

codecov Bot commented Apr 23, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 77.19%. Comparing base (a9013ae) to head (9c18f04).
⚠️ Report is 13 commits behind head on master.

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #8089      +/-   ##
==========================================
+ Coverage   71.83%   77.19%   +5.36%     
==========================================
  Files         732      813      +81     
  Lines       33452    37652    +4200     
==========================================
+ Hits        24029    29065    +5036     
+ Misses       9423     8587     -836     
Flag Coverage Δ
aiguard-macos 35.82% <ø> (-0.09%) ⬇️
aiguard-ubuntu 35.93% <ø> (-0.09%) ⬇️
aiguard-windows 35.72% <ø> (-0.09%) ⬇️
apm-capabilities-tracing-macos 48.20% <ø> (?)
apm-capabilities-tracing-ubuntu-active 48.23% <ø> (?)
apm-capabilities-tracing-ubuntu-latest 48.20% <ø> (?)
apm-capabilities-tracing-ubuntu-maintenance 48.23% <ø> (?)
apm-capabilities-tracing-ubuntu-oldest 48.21% <ø> (?)
apm-capabilities-tracing-windows 47.98% <ø> (?)
apm-integrations-aerospike-18-gte.5.2.0 34.97% <ø> (-0.09%) ⬇️
apm-integrations-aerospike-20-gte.5.5.0 34.99% <ø> (-0.09%) ⬇️
apm-integrations-aerospike-22-gte.5.12.1 34.99% <ø> (-0.09%) ⬇️
apm-integrations-aerospike-22-gte.6.0.0 34.99% <ø> (-0.09%) ⬇️
apm-integrations-aerospike-eol- 34.89% <ø> (-0.09%) ⬇️
apm-integrations-child-process 36.15% <ø> (-0.09%) ⬇️
apm-integrations-confluentinc-kafka-javascript-18 41.83% <ø> (-0.09%) ⬇️
apm-integrations-confluentinc-kafka-javascript-20 41.85% <ø> (-0.09%) ⬇️
apm-integrations-confluentinc-kafka-javascript-22 41.85% <ø> (-0.09%) ⬇️
apm-integrations-confluentinc-kafka-javascript-24 41.78% <ø> (-0.09%) ⬇️
apm-integrations-couchbase-18 35.15% <ø> (-0.09%) ⬇️
apm-integrations-couchbase-eol 35.23% <ø> (-0.07%) ⬇️
apm-integrations-dns 35.00% <ø> (-0.09%) ⬇️
apm-integrations-elasticsearch 35.55% <ø> (-0.09%) ⬇️
apm-integrations-http-latest 42.98% <ø> (-0.08%) ⬇️
apm-integrations-http-maintenance 43.04% <ø> (-0.08%) ⬇️
apm-integrations-http-oldest 43.05% <ø> (-0.08%) ⬇️
apm-integrations-http2 40.35% <ø> (-0.09%) ⬇️
apm-integrations-kafkajs-latest 41.72% <ø> (-0.09%) ⬇️
apm-integrations-kafkajs-oldest 41.77% <ø> (-0.09%) ⬇️
apm-integrations-net 35.66% <ø> (-0.09%) ⬇️
apm-integrations-next-11.1.4 29.43% <ø> (-0.10%) ⬇️
apm-integrations-next-13.2.0 31.28% <ø> (-0.09%) ⬇️
apm-integrations-next-gte.10.2.0.and.lt.11 23.33% <ø> (ø)
apm-integrations-next-gte.11.0.0.and.lt.13 31.29% <ø> (-0.09%) ⬇️
apm-integrations-next-gte.13.0.0.and.lt.14 31.54% <ø> (-0.09%) ⬇️
apm-integrations-next-gte.14.0.0.and.lte.14.2.6 31.36% <ø> (-0.09%) ⬇️
apm-integrations-next-gte.14.2.7.and.lt.15 31.36% <ø> (-0.11%) ⬇️
apm-integrations-next-gte.15.0.0 31.42% <ø> (-0.11%) ⬇️
apm-integrations-prisma-18-gte.6.16.0.and.lt.7.0.0 35.52% <ø> (-0.09%) ⬇️
apm-integrations-prisma-latest-all 35.85% <ø> (-0.09%) ⬇️
apm-integrations-sharedb 34.57% <ø> (-0.09%) ⬇️
apm-integrations-tedious 35.13% <ø> (-0.09%) ⬇️
appsec-express 52.78% <ø> (-0.07%) ⬇️
appsec-fastify 49.29% <ø> (-0.04%) ⬇️
appsec-graphql 49.47% <ø> (-0.04%) ⬇️
appsec-kafka 42.07% <ø> (-0.08%) ⬇️
appsec-ldapjs 41.30% <ø> (-0.08%) ⬇️
appsec-lodash 41.42% <ø> (-0.08%) ⬇️
appsec-macos 56.79% <ø> (-0.07%) ⬇️
appsec-mongodb-core 45.69% <ø> (-0.08%) ⬇️
appsec-mongoose 46.57% <ø> (-0.07%) ⬇️
appsec-mysql 48.74% <ø> (-0.07%) ⬇️
appsec-next-latest-11.1.4 29.60% <ø> (-0.08%) ⬇️
appsec-next-latest-13.2.0 31.49% <ø> (-0.09%) ⬇️
appsec-next-latest-gte.10.2.0.and.lt.11 31.60% <ø> (ø)
appsec-next-latest-gte.11.0.0.and.lt.13 31.47% <ø> (-0.09%) ⬇️
appsec-next-latest-gte.13.0.0.and.lt.14 31.67% <ø> (-0.09%) ⬇️
appsec-next-latest-gte.14.0.0.and.lte.14.2.6 31.52% <ø> (-0.09%) ⬇️
appsec-next-latest-gte.14.2.7.and.lt.15 31.52% <ø> (-0.09%) ⬇️
appsec-next-latest-gte.15.0.0 31.52% <ø> (-0.09%) ⬇️
appsec-next-oldest-11.1.4 29.62% <ø> (-0.08%) ⬇️
appsec-next-oldest-13.2.0 31.73% <ø> (-0.09%) ⬇️
appsec-next-oldest-gte.10.2.0.and.lt.11 31.76% <ø> (ø)
appsec-next-oldest-gte.11.0.0.and.lt.13 31.49% <ø> (-0.09%) ⬇️
appsec-next-oldest-gte.13.0.0.and.lt.14 31.92% <ø> (-0.09%) ⬇️
appsec-next-oldest-gte.14.0.0.and.lte.14.2.6 31.77% <ø> (-0.09%) ⬇️
appsec-next-oldest-gte.14.2.7.and.lt.15 31.77% <ø> (-0.09%) ⬇️
appsec-next-oldest-gte.15.0.0 31.77% <ø> (-0.09%) ⬇️
appsec-node-serialize 40.60% <ø> (-0.08%) ⬇️
appsec-passport 44.59% <ø> (-0.08%) ⬇️
appsec-postgres 48.33% <ø> (-0.07%) ⬇️
appsec-sourcing 40.09% <ø> (-0.08%) ⬇️
appsec-stripe 42.35% <ø> (-0.05%) ⬇️
appsec-template 40.76% <ø> (-0.08%) ⬇️
appsec-ubuntu 56.87% <ø> (-0.07%) ⬇️
appsec-windows 56.68% <ø> (-0.07%) ⬇️
debugger-ubuntu-active 62.13% <ø> (-0.33%) ⬇️
debugger-ubuntu-latest 62.03% <ø> (-0.33%) ⬇️
debugger-ubuntu-maintenance 62.13% <ø> (-0.33%) ⬇️
debugger-ubuntu-oldest 62.23% <ø> (-0.33%) ⬇️
instrumentations-instrumentation-bluebird 29.88% <ø> (-0.09%) ⬇️
instrumentations-instrumentation-body-parser 37.74% <ø> (-0.09%) ⬇️
instrumentations-instrumentation-child_process 35.53% <ø> (-0.09%) ⬇️
instrumentations-instrumentation-cookie-parser 31.81% <ø> (-0.09%) ⬇️
instrumentations-instrumentation-express 32.03% <ø> (-0.09%) ⬇️
instrumentations-instrumentation-express-mongo-sanitize 31.93% <ø> (-0.09%) ⬇️
instrumentations-instrumentation-express-session 37.38% <ø> (-0.09%) ⬇️
instrumentations-instrumentation-fs 29.56% <ø> (-0.09%) ⬇️
instrumentations-instrumentation-generic-pool 30.59% <ø> (ø)
instrumentations-instrumentation-http 36.99% <ø> (-0.09%) ⬇️
instrumentations-instrumentation-knex 29.85% <ø> (-0.09%) ⬇️
instrumentations-instrumentation-light-my-request 37.30% <ø> (-0.09%) ⬇️
instrumentations-instrumentation-mongoose 30.94% <ø> (-0.17%) ⬇️
instrumentations-instrumentation-multer 37.52% <ø> (-0.09%) ⬇️
instrumentations-instrumentation-mysql2 35.49% <ø> (-0.09%) ⬇️
instrumentations-instrumentation-passport 41.17% <ø> (-0.08%) ⬇️
instrumentations-instrumentation-passport-http 40.95% <ø> (-0.08%) ⬇️
instrumentations-instrumentation-passport-local 41.46% <ø> (-0.08%) ⬇️
instrumentations-instrumentation-pg 35.03% <ø> (-0.09%) ⬇️
instrumentations-instrumentation-promise 29.82% <ø> (-0.09%) ⬇️
instrumentations-instrumentation-promise-js 29.83% <ø> (-0.09%) ⬇️
instrumentations-instrumentation-q 29.86% <ø> (-0.09%) ⬇️
instrumentations-instrumentation-url 29.83% <ø> (-0.09%) ⬇️
instrumentations-instrumentation-when 29.84% <ø> (-0.09%) ⬇️
llmobs-ai 38.45% <ø> (-0.09%) ⬇️
llmobs-anthropic 37.94% <ø> (-0.09%) ⬇️
llmobs-bedrock 37.15% <ø> (-0.08%) ⬇️
llmobs-google-genai 37.58% <ø> (-0.08%) ⬇️
llmobs-langchain 37.09% <ø> (-0.07%) ⬇️
llmobs-openai 41.26% <ø> (-0.08%) ⬇️
llmobs-vertex-ai 37.77% <ø> (-0.09%) ⬇️
openfeature-unit-active 50.43% <ø> (-0.52%) ⬇️
openfeature-unit-latest 50.28% <ø> (-0.52%) ⬇️
openfeature-unit-maintenance 50.43% <ø> (-0.52%) ⬇️
openfeature-unit-oldest 50.43% <ø> (-0.52%) ⬇️
platform-core 36.53% <ø> (ø)
platform-esbuild 40.80% <ø> (ø)
platform-instrumentations-misc 31.34% <ø> (ø)
platform-shimmer 42.11% <ø> (ø)
platform-unit-guardrails 35.88% <ø> (ø)
platform-webpack 20.79% <ø> (+<0.01%) ⬆️
plugins-azure-durable-functions 25.36% <ø> (ø)
plugins-azure-event-hubs 25.51% <ø> (ø)
plugins-azure-service-bus 24.92% <ø> (ø)
plugins-bullmq 40.79% <ø> (+0.02%) ⬆️
plugins-cassandra 35.26% <ø> (-0.09%) ⬇️
plugins-cookie 26.47% <ø> (ø)
plugins-cookie-parser 26.28% <ø> (ø)
plugins-crypto 27.32% <ø> (ø)
plugins-dd-trace-api 35.48% <ø> (-0.09%) ⬇️
plugins-express-mongo-sanitize 26.42% <ø> (ø)
plugins-express-session 26.24% <ø> (ø)
plugins-fastify 39.41% <ø> (-0.06%) ⬇️
plugins-fetch 35.87% <ø> (-0.09%) ⬇️
plugins-fs 35.75% <ø> (-0.09%) ⬇️
plugins-generic-pool 25.40% <ø> (ø)
plugins-google-cloud-pubsub 43.07% <ø> (-0.08%) ⬇️
plugins-grpc 38.12% <ø> (-0.09%) ⬇️
plugins-handlebars 26.46% <ø> (ø)
plugins-hapi 37.36% <ø> (-0.09%) ⬇️
plugins-hono 37.61% <ø> (-0.09%) ⬇️
plugins-ioredis 35.80% <ø> (-0.09%) ⬇️
plugins-knex 26.14% <ø> (ø)
plugins-langgraph 35.14% <ø> (-0.09%) ⬇️
plugins-ldapjs 24.02% <ø> (ø)
plugins-light-my-request 25.88% <ø> (ø)
plugins-limitd-client 30.12% <ø> (-0.09%) ⬇️
plugins-lodash 25.47% <ø> (ø)
plugins-mariadb 36.67% <ø> (-0.09%) ⬇️
plugins-memcached 35.45% <ø> (-0.09%) ⬇️
plugins-microgateway-core 36.45% <ø> (-0.09%) ⬇️
plugins-modelcontextprotocol-sdk 34.39% <ø> (-0.09%) ⬇️
plugins-moleculer 38.14% <ø> (-0.09%) ⬇️
plugins-mongodb 36.64% <ø> (-0.09%) ⬇️
plugins-mongodb-core 36.27% <ø> (-0.09%) ⬇️
plugins-mongoose 36.12% <ø> (-0.09%) ⬇️
plugins-multer 26.24% <ø> (ø)
plugins-mysql 36.53% <ø> (-0.09%) ⬇️
plugins-mysql2 36.50% <ø> (-0.09%) ⬇️
plugins-node-serialize 26.51% <ø> (ø)
plugins-opensearch 35.11% <ø> (-0.09%) ⬇️
plugins-passport-http 26.30% <ø> (ø)
plugins-pino 31.84% <ø> (-0.17%) ⬇️
plugins-postgres 34.50% <ø> (-0.09%) ⬇️
plugins-process 27.32% <ø> (ø)
plugins-pug 26.47% <ø> (ø)
plugins-redis 36.01% <ø> (-0.09%) ⬇️
plugins-router 39.90% <ø> (+0.04%) ⬆️
plugins-sequelize 25.18% <ø> (ø)
plugins-test-and-upstream-amqp10 35.77% <ø> (-0.09%) ⬇️
plugins-test-and-upstream-amqplib 40.92% <ø> (-0.09%) ⬇️
plugins-test-and-upstream-apollo 36.61% <ø> (-0.08%) ⬇️
plugins-test-and-upstream-avsc 35.10% <ø> (-0.09%) ⬇️
plugins-test-and-upstream-bunyan 31.26% <ø> (-0.09%) ⬇️
plugins-test-and-upstream-connect 37.95% <ø> (-0.09%) ⬇️
plugins-test-and-upstream-graphql 37.29% <ø> (-0.09%) ⬇️
plugins-test-and-upstream-koa 37.56% <ø> (-0.09%) ⬇️
plugins-test-and-upstream-protobufjs 35.32% <ø> (-0.09%) ⬇️
plugins-test-and-upstream-rhea 41.00% <ø> (-0.09%) ⬇️
plugins-undici 36.62% <ø> (-0.09%) ⬇️
plugins-url 27.32% <ø> (ø)
plugins-valkey 35.49% <ø> (-0.09%) ⬇️
plugins-vm 27.32% <ø> (ø)
plugins-winston 31.73% <ø> (-0.09%) ⬇️
plugins-ws 39.07% <ø> (-0.09%) ⬇️
profiling-macos 40.69% <ø> (-0.08%) ⬇️
profiling-ubuntu 41.30% <ø> (-0.08%) ⬇️
profiling-windows 40.87% <ø> (-0.08%) ⬇️
serverless-azure-functions-client 25.25% <ø> (ø)
serverless-azure-functions-eventhubs 25.25% <ø> (ø)
serverless-azure-functions-servicebus 25.25% <ø> (ø)
serverless-lambda 33.56% <ø> (-0.09%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

The existing plugin-graphql bench runs exactly 6 queries per process,
so on Node 22.10.0 master ~80% of measured CPU is one-time startup
(tracer init + graphql require + schema walk). At that workload, any
change that trades startup cost for steady-state cost (e.g. module
rewriting, JIT-warmup-heavy instrumentation) registers as a regression
even when it makes real applications faster.

Add plugin-graphql-long: a sibling benchmark that runs 150 sequential
queries per process using the same variant matrix. At N=150, load drops
to ~12-17% of measured CPU, so per-query cost dominates -- the metric
that matters for servers handling many requests per process lifetime.

- QUERIES env var is parametric (defaults to 150); same directory can be
  re-aimed at larger sizes without forking.
- Reuses the existing plugin-graphql schema module.
- Picked up automatically by benchmark/sirun/runall.sh via subdir scan
  (no runner changes needed).
- Budget: ~4 min per Node version across the 6-variant x 30-iteration
  matrix (roughly 5-6x the existing plugin-graphql bench).

The existing plugin-graphql bench is preserved unchanged, so startup /
init regressions remain covered. plugin-graphql-long complements it by
catching steady-state regressions that the 6-query shape hides.
@crysmags
crysmags force-pushed the crysmags/bench-graphql-long branch from a1f5c1d to cc9e233 Compare April 23, 2026 22:21
Comment on lines +3 to +5
// Long-workload graphql bench. Runs QUERIES sequential queries per process
// (default 100) so the fixed startup cost doesn't dominate the measurement.
// See ./README.md.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I wanted to have another benchmark type as well where we can deduct the startup time. Right now, that is dominant in almost all our benchmarks and that is why they are not useful.

I asked @bengl a long time ago about implementing the type and he opened a PR in dd-trace-js (look at the oldest ones). It just needs to be tracked in our benchmark backend as a known type. That way this would also be solved while not needing to increase the runtime drastically. While having a combined view is also helpful.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Thanks for the context — looked at @bengl's older work to understand the shape of the "deduct startup" approach. The two relevant ones I found:

shimmer-startup doesn't deduct startup from another bench; it amortizes startup away by running 100,000 iterations of a trivial wrapped function so per-call cost dwarfs init. Same idea as what plugin-graphql-long does, just at a different scale because graphql's per-query work is much heavier than a single shimmer wrap (we top out at ~100 queries before per-Node CI time becomes a problem).

If you'd still rather see startup subtracted from the per-query measurement (e.g., a separate plugin-graphql-startup bench tracked alongside, with the bench backend computing plugin-graphql-long − plugin-graphql-startup), I'm happy to add that as a follow-up — let me know if that matches what you had in mind. For now this PR sticks with amortization, which I think gets us most of the way there: at QUERIES=100, startup load drops from ~80% on the 6-query bench to ~16–23% on the long bench, so per-query cost is the dominant signal even without a separate subtraction step.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I meant #5606

Drops per-Node bench runtime from ~4 min to ~1 min by lowering
QUERIES default 150 -> 100 and iterations 30 -> 10. At Q=100, startup
share is ~16-23% on the typical tracer-on variants -- well below the
~77-83% of the existing 6-query bench, so per-query cost still
dominates the measurement.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>

@BridgeAR BridgeAR left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Almost LGTM. The envs do not need the number parsing in most situations (we just need the existence check) and the README.md should likely be removed. I don't think it is good to land that in our repo. Instead, that could be part of the commit message :)

Comment thread benchmark/sirun/plugin-graphql-long/README.md Outdated
Comment thread benchmark/sirun/plugin-graphql-long/index.js Outdated
Comment thread benchmark/sirun/plugin-graphql-long/index.js Outdated
Comment thread benchmark/sirun/plugin-graphql-long/index.js Outdated
Comment thread benchmark/sirun/plugin-graphql-long/index.js Outdated
crysmags and others added 2 commits April 29, 2026 13:06
Number(process.env.WITH_DEPTH) returns 0 when WITH_DEPTH="0", which is
falsy, so the with-depth-off variant skipped tracer.use() entirely and
ran with default plugin config (depth defaults, collapse=true) instead
of the intended depth=0/collapse=true configuration. Variant labels and
cross-variant comparisons were misleading because of this.

Switch the four env-var truthy checks (WITH_TRACER, WITH_DEPTH,
WITH_ASYNC_HOOKS, QUERIES) from Number(env) to plain env so the string
"0" reads as "set". Number() conversion still happens at use sites that
need the integer value.

Addresses chatgpt-codex-connector and BridgeAR review comments.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
Sibling sirun benches (plugin-graphql, shimmer-runtime, encoding) keep
their READMEs to a 1-3 paragraph description of what the bench does;
methodology and case-study numbers go in the PR description that
introduces the bench. The plugin-graphql-long README was carrying that
methodology in-tree, which goes stale and sits outside its real
audience.

Drop the methodology tables and rationale; keep the terse description
matching the other sirun READMEs.

Addresses BridgeAR review comment.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
@crysmags
crysmags requested a review from BridgeAR April 29, 2026 17:34
BridgeAR
BridgeAR previously approved these changes Apr 29, 2026

@BridgeAR BridgeAR left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

LGTM

@BridgeAR
BridgeAR enabled auto-merge (squash) April 29, 2026 17:41
BridgeAR and others added 2 commits April 29, 2026 20:46
The 6-query plugin-graphql bench reports startup-dominated numbers (load
share ~80%) that consistently mislabel per-query trade-offs as
regressions, which is exactly the problem this directory exists to
solve. Keeping it alongside the long bench bloats CI runtime and
preserves a misleading signal that reviewers were already discounting.

- Remove benchmark/sirun/plugin-graphql/ entirely (index.js, meta.json,
  README.md). Schema moves into plugin-graphql-long/ since it's the only
  remaining consumer.
- Drop iterations from 10 to 5 in plugin-graphql-long/meta.json. With
  ~3s per iteration on the heaviest variant and ~3 of those discarded
  as warmup, 5 leaves 2 measurement points which is on the thin side
  but acceptable given sirun reports stddev and the bench infra
  aggregates across runs.
- Update plugin-graphql-long/index.js schema require to ./schema.

After this: only scenario:plugin-graphql-long-* runs on CI; the
scenario:plugin-graphql-* scenarios stop reporting.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
crysmags and others added 2 commits April 30, 2026 09:56
Resolves the mergegate "files not properly owned" failure for the new
benchmark/sirun/plugin-graphql-long/ files. The graphql plugin itself
is owned by apm-idm-js via the /packages/datadog-plugin-*/ wildcard;
the bench that exercises it gets the same owner.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
Long-workload graphql bench. Runs QUERIES sequential queries per process
(default 100) so the fixed startup + plugin-setup cost (tracer init,
orchestrion rewrite of graphql/execution/execute.js, schema parse,
instrumentation one-time work) is dominated by per-query work. The
query and variants mirror the previous plugin-graphql bench exactly;
only the loop size differs (default 100 vs the old 6). QUERIES is
parametric so the same bench can be re-aimed at larger sizes (e.g.
QUERIES=500) without forking the directory.

Removes the in-tree README per review — context belongs in the commit
message and PR description rather than alongside the bench files.

Also simplifies the QUERIES line: process.env.QUERIES || 100. The for
loop coerces the string in i < queries, so the explicit Number() was
redundant once the existence check moved to a plain truthy guard.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
@BridgeAR
BridgeAR merged commit 63adfd5 into master May 1, 2026
1080 of 1084 checks passed
@BridgeAR
BridgeAR deleted the crysmags/bench-graphql-long branch May 1, 2026 14:40
dd-octo-sts Bot pushed a commit that referenced this pull request May 1, 2026
The existing plugin-graphql bench runs exactly 6 queries per process,
so on Node 22.10.0 master ~80% of measured CPU is one-time startup
(tracer init + graphql require + schema walk). At that workload, any
change that trades startup cost for steady-state cost (e.g. module
rewriting, JIT-warmup-heavy instrumentation) registers as a regression
even when it makes real applications faster.

Add plugin-graphql-long: a sibling benchmark that runs 100 sequential
queries per process using the same variant matrix. At N=100, load drops
to ~16-23% of measured CPU, so per-query cost dominates -- the metric
that matters for servers handling many requests per process lifetime.

- QUERIES env var is parametric (defaults to 100); same directory can be
  re-aimed at larger sizes without forking.
- Reuses the existing plugin-graphql schema module.
- Picked up automatically by benchmark/sirun/runall.sh via subdir scan
  (no runner changes needed).
- Budget: ~1 min per Node version across the 6-variant x 30-iteration
  matrix.

The existing plugin-graphql bench is preserved unchanged, so startup /
init regressions remain covered. plugin-graphql-long complements it by
catching steady-state regressions that the 6-query shape hides.
@dd-octo-sts dd-octo-sts Bot mentioned this pull request May 1, 2026
pabloerhard pushed a commit that referenced this pull request May 1, 2026
The existing plugin-graphql bench runs exactly 6 queries per process,
so on Node 22.10.0 master ~80% of measured CPU is one-time startup
(tracer init + graphql require + schema walk). At that workload, any
change that trades startup cost for steady-state cost (e.g. module
rewriting, JIT-warmup-heavy instrumentation) registers as a regression
even when it makes real applications faster.

Add plugin-graphql-long: a sibling benchmark that runs 100 sequential
queries per process using the same variant matrix. At N=100, load drops
to ~16-23% of measured CPU, so per-query cost dominates -- the metric
that matters for servers handling many requests per process lifetime.

- QUERIES env var is parametric (defaults to 100); same directory can be
  re-aimed at larger sizes without forking.
- Reuses the existing plugin-graphql schema module.
- Picked up automatically by benchmark/sirun/runall.sh via subdir scan
  (no runner changes needed).
- Budget: ~1 min per Node version across the 6-variant x 30-iteration
  matrix.

The existing plugin-graphql bench is preserved unchanged, so startup /
init regressions remain covered. plugin-graphql-long complements it by
catching steady-state regressions that the 6-query shape hides.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants