fix(sentry): sample traces and session replays to stay under quota - #2082
Merged
Merged
Conversation
Backend traces were sent at 100% (about 77M spans/day) and every browser session was recorded. Sample /public/v1/analytics/* at 1% and all other backend traces at 20%, frontend traces at 20% and session replays at 40%. Error events and error-session replays stay at 100%. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Strix Security ReviewNo security issues found. Updated for Reviewed by Strix |
✅ Snyk checks have passed. No issues have been found so far.
💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse. |
pull Bot
pushed a commit
to dubbypanda/postiz-app
that referenced
this pull request
Sep 21, 2026
The MCP server is stateless, so the GET that streamable-HTTP clients send to open a server-to-client stream is not a supported route: nothing is ever pushed on it. It is still about a quarter of MCP traffic (roughly 180k-214k of ~750k requests per day), and each one became a Sentry transaction that stayed open for the life of the held connection (avg ~5 min, p95 15 min). Sentry usage is already near its limits, which is why gitroomhq#2082 recently cut trace sampling from 100% to 20%. There is nothing to learn from traces of an unsupported route, so tracesSampler now returns 0 for GET on /mcp, /mcp/:id and the /mcp-oauth* mounts. POST traffic on the same routes, the legacy /sse/:id transport and the /.well-known discovery routes keep the existing sample rates. Pairs with the change that answers these GETs with 405. Deploy this one after that change has been verified in Sentry, because the verification reads the GET transactions this commit removes. Testing: - Called the real tracesSampler with request contexts shaped like the http instrumentation passes them (method and URL via normalizedRequest and via span attributes only): GET on the MCP routes returns 0; POST on the same routes 0.2; unrelated GETs 0.2; analytics 0.01; legacy /sse 0.2; /.well-known/.../mcp-oauth discovery 0.2; /mcpfoo 0.2. - Ran the backend against a Sentry development environment and sent 140+ GETs and 60+ POSTs to /mcp, /mcp/:id and /mcp-oauth-claude: zero GET transactions recorded, POST /mcp and POST /mcp/:id recorded as before. Same result on SDK 10.45.0 and 10.56.0. - Backend type-check passes. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What kind of change does this PR introduce?
Config change (backend, orchestrator, frontend Sentry init). In
initialize.sentry.tsthe fixedtracesSampleRate: 1.0becomes atracesSampler: requests whose path contains/public/v1/analytics/are sampled at 1%, all other backend and orchestrator traces (public API, MCP, app API, background jobs) at 20%, and an incoming sampled parent trace keeps its decision. FrontendtracesSampleRategoes from 1.0 to 0.2 (browser and Next.js server), andreplaysSessionSampleRatefrom 1.0 to 0.4. Error events are not sampled,replaysOnErrorSampleRatestays 1.0, and self-hosted setups without a DSN are unaffected.Why was this change needed?
Every trace and every browser session was sent to Sentry, and at the current rate we are projected to exceed our plan's span and replay quotas this billing period unless usage drops significantly.
Current usage (24h measured on 2026-09-15):
Expected usage after this change (extrapolated from the same day):
Sentry recommends lowering the trace sample rate for high-load production backends (https://docs.sentry.io/platforms/javascript/guides/nestjs/configuration/sampling/) and keeping on-error replays at 100% (https://docs.sentry.io/platforms/javascript/session-replay/).
Other information:
Rates were agreed with the team. Possible follow-ups, not in this PR: restoring the Redis cache read for post analytics and not sending spans for cached responses (could allow higher rates), and dropping Prisma internal child spans via
ignoreSpans.QA
@sentry/nestjsand thistracesSampler, collecting transactions inbeforeSendTransaction, and send 3,000 requests each to /public/v1/analytics/post/:id, /public/v1/analytics/:integration, /public/v1/posts, /mcp/:id and /user/selfsentry-traceheader marked sampled; all 200 should produce transactionstracesSampleRate0.2,replaysSessionSampleRate0.4,replaysOnErrorSampleRate1sessionStorage.sentryReplaySessionhassampled: "buffer", capture an exception; the replay for that session should appear in Sentry with 1 error (verified with the previous 0.25 session rate; the on-error path is unchanged)Checklist:
🤖 Generated with Claude Code