Skip to content

chore(deps): pin the Sentry SDK to 10.56.0 to fix the span/scope memory leak - #2101

Merged
nevo-david merged 1 commit into
mainfrom
chore/sentry-sdk-10.56.0
Sep 30, 2026
Merged

nevo-david merged 1 commit into
mainfrom
chore/sentry-sdk-10.56.0

Conversation

@giladresisi

@giladresisi giladresisi commented Sep 18, 2026 •

Copy link
Copy Markdown
Collaborator

What kind of change does this PR introduce?

Dependency update (backend, orchestrator and frontend, Sentry SDK). Pins @sentry/nestjs, @sentry/nextjs, @sentry/profiling-node and @sentry/react to exactly 10.56.0 in the root package.json (previously ^10.2x, locked at 10.45.0) and regenerates pnpm-lock.yaml. No application code changes. The lockfile was regenerated from the committed one with only these four specifiers changed; the rest of its diff is Sentry's own dependency tree, where several OpenTelemetry instrumentations are now vendored and drop out. @sentry/webpack-plugin keeps its own build-time copy of @sentry/core.

Why was this change needed?

To fix the SDK memory leak at the source. The locked SDK (10.45.0) has a leak in @sentry/core: spans and scopes reference each other circularly and cannot be garbage collected, and the span exporter keeps sent spans in an unbounded map. Upstream tracked it as "Memory leak with high tracesSampleRate" (getsentry/sentry-javascript#18339) and fixed it in 10.56.0 (getsentry/sentry-javascript#21242). 10.56.0 also includes the 10.49.0 fix for contexts retained through scopes on pooled connections (getsentry/sentry-javascript#20328).

This matches what we saw in production. The MCP service climbed to V8's heap limit (about 3.4 GB) roughly once a day while trace sampling was 100%, and the climb stopped on the day #2082 cut sampling to 20%. Sampling less only slows the leak. The leak is in the core package, so the backend, the orchestrator and the frontend server all carry it; the MCP service showed it first because it holds hundreds of long-lived transactions open (see #1850 and #2100).

Other information:

The pin is exact on purpose. 10.56.0 is the first release with the fix, and later minors change behaviour we have not evaluated: 10.61.0 streams gen_ai spans by default and stops truncating AI message data, 10.71.0 enables logs by default, and 10.72.0 stops reporting AI errors that propagate to the caller. A caret range would let a later pnpm up pull those in silently.

Behaviour changes that do come along between 10.46.0 and 10.56.0, from the changelog (https://github.com/getsentry/sentry-javascript/blob/develop/CHANGELOG.md):

  • 10.48.0 renames OpenAI span attributes from openai.* to gen_ai.*. Only matters if a Sentry dashboard or alert filters on the old names.
  • 10.54.0 vendors the NestJS instrumentation inside the SDK and sends array attribute values as arrays.
  • sendDefaultPii, which the frontend init uses, is deprecated in 10.57.0 and is not affected by this PR.

This PR is independent of #1850 (answer MCP stream GETs with 405) and #2100 (stop tracing those GETs) and can merge in any order relative to them.

Leak test: 10.45.0 vs 10.56.0

To confirm the fix rather than take the changelog's word for it, both versions of @sentry/node were installed in isolation and run side by side: the same small HTTP server, each request creating one span with four nested child spans, tracesSampleRate: 1.0, events sent to a sink that accepts and discards them. Both received identical load, 200 requests per second for 6 minutes (71,280 requests each, 0 errors), followed by more than 6 minutes idle. Heap is heapUsed measured right after a forced garbage collection, so it is retained memory, not garbage waiting to be collected.

Time Requests served 10.45.0 heap 10.56.0 heap
start 0 13.9 MB 12.4 MB
1 min 10,900 21.1 MB 16.4 MB
2 min 22,780 29.8 MB 16.6 MB
3 min 34,660 33.1 MB 16.7 MB
4 min 46,540 43.8 MB 16.7 MB
5 min 58,420 47.1 MB 16.7 MB
6 min (load ends) 70,300 47.3 MB 16.7 MB
6.5 min idle later 71,280 46.8 MB 16.1 MB
  • 10.45.0 retained memory grew by about 33 MB under load and gave none of it back after more than 6 minutes without traffic. 10.56.0 stayed flat at about 16.7 MB under the same load and dropped to 16.1 MB when idle.
  • On 10.45.0 the growth levelled off after about 5 minutes, which fits the upstream description of sent spans being kept for 5 minutes: at a constant request rate the retained amount scales with throughput over that window, and it is only cleaned up while traffic keeps flowing.
  • This is a synthetic test. It shows the retention is gone in 10.56.0, it does not reproduce the size of the production climb. Production has much larger and much longer-lived transactions than this test (requests carrying scope data and a profiler, and MCP streams held open for minutes), so the amount retained per span there is not comparable.

QA

  1. Run pnpm install --frozen-lockfile and confirm it passes, then confirm node_modules/@sentry/nestjs/package.json and node_modules/@sentry/nextjs/package.json both say 10.56.0
  2. Start the backend, the orchestrator and the frontend with a Sentry DSN for a non-production environment and confirm all three boot without Sentry-related errors
  3. Log in, open the calendar, and in the browser console run setTimeout(() => { throw new Error('sdk-bump-check') }, 0). The "It looks like we're having issues" report dialog should appear; close it
  4. Click the Feedback button in the top bar and confirm the "Report a Bug" form opens; cancel it
  5. Call a few API routes, including one public API route such as GET /public/v1/integrations with an API key
  6. After about 5 minutes, in Sentry for that environment confirm: the sdk-bump-check error is present with the user, the organization.id tag and a linked replay; backend http.server transactions and frontend pageload transactions with sdk.version:10.56.0; backend log entries; the public_api_request metric
  7. Run pnpm run build:frontend and confirm it exits 0

Results of the testing already done on 10.56.0 (against a Sentry development environment unless noted):

  • Backend, orchestrator and frontend type-check. Backend and orchestrator boot. Production next build passes, also when the source-map upload fails (the next.config.js error handler absorbs it).
  • Backend: HTTP transactions, console logs, an unhandled controller 500 through the Nest global filter with the organization tag, a process-level crash, Sentry.metrics counters, profiler ids on spans.
  • Frontend: client init with every configured integration, user and organization tag, an uncaught browser error linked to its session replay, the crash report dialog, the feedback form, pageload spans with browser profiles.
  • OpenAI integration against a local stub: the wrapped client works for chat.completions.create and .parse, and create emits a gen_ai.chat span. .parse and images.generate are not instrumented on 10.45.0 either, so nothing changes there.
  • MCP flows (initialize, tools/list, tools/call) unchanged.
  • Leak comparison between 10.45.0 and 10.56.0: see "Leak test" above.
  • Not tested: a successful source-map upload to the real Sentry project.

Checklist:

Put a "X" in the boxes below to indicate you have followed the checklist;

  • I have read the CONTRIBUTING guide.
  • I have signed the Contributor License Agreement (CLA) (ICLA for individuals, CCLA for entities).
  • I confirm I have not used AI to submit this PR or generate code for it.
  • I checked that there were no similar issues or PRs already open for this.
  • This PR fixes just ONE issue
  • I have filled in the QA section above with real steps to verify this change.

🤖 Generated with Claude Code

…leak fix

The installed SDK (10.45.0) has a memory leak in @sentry/core: spans and
scopes reference each other circularly and cannot be garbage collected,
and the span exporter keeps sent spans in an unbounded map. Upstream
tracked it as "Memory leak with high tracesSampleRate"
(getsentry/sentry-javascript#18339) and fixed it in 10.56.0
(getsentry/sentry-javascript#21242). 10.56.0 also carries the 10.49.0
fix for contexts retained through scopes on pooled connections
(getsentry/sentry-javascript#20328).

This matches what we saw in production: the MCP service climbed to the
V8 heap limit about once a day while trace sampling was 100%, and the
climb stopped when #2082 cut sampling to 20%. Sampling less only slows
the leak; this fixes it at the source, for the backend, the orchestrator
and the frontend server alike.

Pinned exactly, not with a caret, on purpose. 10.56.0 is the first
release with the fix, and later minors change behaviour we have not
evaluated: 10.61.0 streams gen_ai spans by default and stops truncating
AI message data, 10.71.0 enables logs by default, 10.72.0 stops
reporting AI errors that propagate to the caller. The lockfile was
regenerated from the committed one with only these four specifiers
changed; the rest of the diff is Sentry's own dependency tree (several
OpenTelemetry instrumentations are now vendored and drop out).
@sentry/webpack-plugin keeps its own build-time @sentry/core copy.

Behaviour changes that do ride along (10.46.0 to 10.56.0): OpenAI span
attributes are renamed from openai.* to gen_ai.* (10.48.0), the NestJS
instrumentation is vendored inside the SDK (10.54.0), array attribute
values are sent as arrays (10.54.0). sendDefaultPii, which the frontend
init uses, is deprecated in 10.57.0 and is untouched here.

Testing on 10.56.0, against a Sentry development environment unless
noted:
- backend, orchestrator and frontend type-check; backend and
  orchestrator boot; production `next build` passes, also when the
  source-map upload fails (the next.config error handler absorbs it)
- backend: HTTP transactions, console logs, an unhandled controller 500
  through the Nest global filter with the organization tag, a process
  level crash, Sentry.metrics counters and profiler ids on spans
- frontend: client init with every configured integration, user and
  organization tag, an uncaught browser error linked to its session
  replay, the crash report dialog, the feedback form, pageload spans
  with browser profiles
- OpenAI integration against a local stub: the wrapped client works for
  chat.completions.create and .parse; create emits a gen_ai.chat span;
  .parse and images.generate are not instrumented on 10.45.0 either
- MCP flows (initialize, tools/list, tools/call) unchanged

Not tested: a successful source-map upload to the real project.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@strix-security

strix-security Bot commented Sep 18, 2026 •

Copy link
Copy Markdown

Strix Security Review

No security issues found.

Updated for c38f8ed.


Reviewed by Strix
Re-run review · Configure security review settings

@postiz-contribution postiz-contribution Bot added the contribution:approved Approved contributor label Sep 18, 2026
@postiz-agent

postiz-agent Bot commented Sep 18, 2026 •

Copy link
Copy Markdown

✅ Snyk checks have passed. No issues have been found so far.

Status Scan Engine Critical High Medium Low Total (0)
✅ Open Source Security 0 0 0 0 0 issues
✅ Licenses 0 0 0 0 0 issues
✅ Code Security 0 0 0 0 0 issues

💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse.

@nevo-david
nevo-david added this pull request to the merge queue Sep 30, 2026
Merged via the queue into main with commit 9c4524e Sep 30, 2026
13 checks passed
@nevo-david
nevo-david deleted the chore/sentry-sdk-10.56.0 branch September 30, 2026 02:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants