Skip to main content Início Criadores jeremylongshore tons-of-skills-marketplace sentry-load-scale
sentry-load-scale Scale Sentry for high-traffic applications handling millions of events per day.
Use when optimizing SDK performance at high volume, implementing adaptive sampling,
managing quotas and costs at scale, or deploying Sentry across multi-region infrastructure.
Trigger with phrases like "sentry high traffic", "scale sentry", "sentry millions events",
"sentry high volume", "sentry quota management", "sentry load test".
Ir para a instalação Skills Marketplace Descubra e explore skills de IA criadas pela comunidade.
Instalar com Codex ou Claude Copie este prompt, cole no Codex, Claude ou outro assistente e deixe que ele revise a página da skill e instale para você.
Copiar promptMostrar detalhes do prompt Um comando direto ignora o prompt de revisão. Verifique a origem antes de executá-lo.
npx skills add https://github.com/jeremylongshore/tons-of-skills-marketplace --skill sentry-load-scaleO comando permanece em uma só linha. Role horizontalmente para revisá-lo antes de copiar.
Prefere uma cópia local? Baixe os arquivos disponíveis atualmente no SkillsMP.
Baixar Zip Baixando... Mais deste repositório langchain-deploy-integration Deploy a LangChain 1.0 / LangGraph 1.0 app to Cloud Run, Vercel, or LangServe correctly — with timeouts sized for chain length, cold-start mitigation, SSE anti-buffering headers, and Secret Manager over .env. Use when prepping a first production deploy, debugging a stream that hangs behind a proxy, or diagnosing p99 latency spikes. Trigger with "langchain deploy", "langchain cloud run", "langchain vercel python", "langchain langserve", or "langchain docker".
langchain-langgraph-agents Build a correct LangGraph 1.0 ReAct agent with create_react_agent — typed tools, error propagation, recursion caps, and stop conditions that actually stop. Use when writing a first tool-calling agent, migrating from AgentExecutor or initialize_agent, or diagnosing an agent that loops on vague prompts. Trigger with "langgraph agent", "create_react_agent", "langgraph tool calling", "AgentExecutor migration", or "agent loop cost".
langchain-langgraph-human-in-loop Build LangGraph 1.0 human-in-the-loop approval flows with interrupt_before /
interrupt_after and Command(resume=...) — JSON-serializable state, clean
resume semantics, and UI wiring for approval decisions. Use when adding an
approval gate before an expensive tool call, wiring a Slack/web UI for agent
approvals, or debugging a graph that crashes on interrupt.
Trigger with "langgraph human in loop", "langgraph interrupt_before",
"langgraph approval flow", "Command resume", "langgraph HITL".
Explorador de arquivos
7 arquivos name sentry-load-scale description Scale Sentry for high-traffic applications handling millions of events per day.
Use when optimizing SDK performance at high volume, implementing adaptive sampling,
managing quotas and costs at scale, or deploying Sentry across multi-region infrastructure.
Trigger with phrases like "sentry high traffic", "scale sentry", "sentry millions events",
"sentry high volume", "sentry quota management", "sentry load test".
allowed-tools Read, Write, Edit, Grep, Bash(node:*), Bash(npx:*), Bash(k6:*) version 1.51.0 license MIT author Jeremy Longshore <jeremy@intentsolutions.io> tags ["saas","sentry","performance","scaling","high-traffic","enterprise"] compatibility Designed for Claude Code
Sentry Load & Scale
Overview
Configure Sentry for applications processing 1M+ requests/day without sacrificing error visibility, burning through quota, or adding measurable SDK overhead. Covers adaptive sampling, connection pooling, multi-region tagging, quota management, SDK benchmarking, batch submission, load testing, and self-hosted deployment considerations.
Prerequisites
Application handling sustained high traffic (>10K requests/min or >1M events/day)
Sentry organization with quota and billing access (Settings > Subscription)
@sentry/node v8+ installed (npm ls @sentry/node)
Performance baseline established (p50/p95/p99 latency without Sentry)
Event volume estimates calculated per category (errors, transactions, replays, attachments)
Instructions
Step 1 — Implement Adaptive Sampling
Static tracesSampleRate wastes quota at scale because it treats a health check the same as a checkout. Replace it with a traffic-aware tracesSampler that adjusts rates based on endpoint criticality and current load.
Traffic-aware tracesSampler:
import * as Sentry from '@sentry/node' ;
const endpointVolume = new Map <string , { count : number ; resetAt : number }>();
const WINDOW_MS = 60_000 ;
function getAdaptiveRate (name : string , baseRate : number ): number {
const now = Date .now ();
entry = endpointVolume. (name);
(!entry || now > entry. ) {
entry = { : , : now + };
endpointVolume. (name, entry);
}
entry. ++;
(entry. > ) baseRate * ;
(entry. > ) baseRate * ;
baseRate;
}
. ({
: process. . ,
: {
{ name, parentSampled } = samplingContext;
(parentSampled !== ) parentSampled ? : ;
(name?. ( )) ;
(name?. ( )) ;
(name?. ( ) || name?. ( )) ;
(name?. ( )) ( , );
(name?. ( )) (name, );
(name?. ( )) (name, );
(name?. ( )) (name, );
(name?. ( )) (name, );
(name?. ( ) || name?. ( )) {
(name, );
}
(name || , );
},
});
let
get
if
resetAt
count
0
resetAt
WINDOW_MS
set
count
if
count
1000
return
0.25
if
count
100
return
0.5
return
Sentry
init
dsn
env
SENTRY_DSN
tracesSampler
(samplingContext ) =>
const
if
undefined
return
1.0
0
if
match
/\/(health|ready|alive|ping|metrics|favicon)/
return
0
if
match
/\.(css|js|png|jpg|svg|woff2?|ico)$/
return
0
if
includes
'/payment'
includes
'/checkout'
return
1.0
if
includes
'/auth/login'
return
getAdaptiveRate
'auth'
0.5
if
startsWith
'POST /api/'
return
getAdaptiveRate
0.05
if
startsWith
'PUT /api/'
return
getAdaptiveRate
0.05
if
startsWith
'DELETE /api/'
return
getAdaptiveRate
0.05
if
startsWith
'GET /api/'
return
getAdaptiveRate
0.02
if
startsWith
'job:'
startsWith
'queue:'
return
getAdaptiveRate
0.01
return
getAdaptiveRate
'default'
0.005
Adaptive error deduplication with beforeSend:
const errorCounts = new Map <string , number >();
const ERROR_WINDOW_MS = 60_000 ;
setInterval (() => errorCounts.clear (), ERROR_WINDOW_MS );
Sentry .init ({
dsn : process.env .SENTRY_DSN ,
beforeSend (event, hint ) {
const error = hint?.originalException ;
const key = error instanceof Error
? `${error.name} :${error.message?.substring(0 , 100 )} `
: `unknown:${String (event.message || '' ).substring(0 , 100 )} ` ;
const count = (errorCounts.get (key) || 0 ) + 1 ;
errorCounts.set (key, count);
if (count === 1 ) return event;
if (count <= 10 ) return count % 5 === 0 ? event : null ;
if (count <= 100 ) return count % 25 === 0 ? event : null ;
return count % 100 === 0 ? event : null ;
},
});
Step 2 — Optimize SDK for Minimal Overhead At high throughput, every byte and every millisecond of SDK processing matters. This configuration reduces memory footprint, payload size, and CPU time.
import * as Sentry from '@sentry/node' ;
import os from 'node:os' ;
Sentry .init ({
dsn : process.env .SENTRY_DSN ,
environment : process.env .NODE_ENV || 'production' ,
release : `${process.env.SERVICE_NAME} @${process.env.VERSION || 'unknown' } ` ,
maxBreadcrumbs : 15 ,
maxValueLength : 200 ,
integrations : (defaults ) => defaults.filter (i =>
!['Console' , 'ContextLines' ].includes (i.name )
),
profilesSampleRate : 0 ,
transportOptions : {
bufferSize : 100 ,
},
beforeSend (event ) {
if (event.contexts ) {
for (const [key, ctx] of Object .entries (event.contexts )) {
const str = JSON .stringify (ctx);
if (str.length > 2000 ) {
event.contexts [key] = { _truncated : true , originalSize : str.length };
}
}
}
if (event.request ?.headers ) {
const keep = ['content-type' , 'accept' , 'user-agent' , 'x-request-id' ];
event.request .headers = Object .fromEntries (
Object .entries (event.request .headers )
.filter (([k] ) => keep.includes (k.toLowerCase ()))
);
}
return event;
},
serverName : process.env .HOSTNAME || process.env .POD_NAME || os.hostname (),
initialScope : {
tags : {
region : process.env .AWS_REGION || process.env .GCP_REGION || 'unknown' ,
cluster : process.env .K8S_CLUSTER || 'default' ,
pod : process.env .POD_NAME || 'unknown' ,
service : process.env .SERVICE_NAME || 'unknown' ,
},
},
});
Graceful shutdown ensuring event delivery:
import * as Sentry from '@sentry/node' ;
async function shutdown (signal : string ) {
console .log (`${signal} received — flushing Sentry events` );
server.close ();
const flushed = await Sentry .close (2000 );
if (!flushed) {
console .warn ('Sentry flush timed out — some events may be lost' );
}
process.exit (0 );
}
process.on ('SIGTERM' , () => shutdown ('SIGTERM' ));
process.on ('SIGINT' , () => shutdown ('SIGINT' ));
Step 3 — Manage Quotas, Test Under Load, and Plan for Scale Quota management and reserved volume pricing:
Application: 10M requests/day, 0.1% error rate, @sentry/node v8
Error events (with adaptive beforeSend):
Raw errors: 10M x 0.001 = 10,000/day
After dedup: ~1,000/day (90% reduction) = 30K/month
Transaction events (with tiered tracesSampler):
Health/static: 0% of 4M = 0
Payment (T1): 100% of 5K = 5,000/day
POST API (T2): 5% of 500K = 25,000/day
GET API (T3): 2% of 5M = 100,000/day
Other (T5): 0.5% of 500K = 2,500/day
Total: ~132K/day = 4M/month
Sentry Business plan ($26/mo base):
Errors: 30K included in base plan
Transactions: 100K included, overage 3.9M x $0.000025 = ~$97/mo
Estimated total: ~$123/month for 10M requests/day
Reserved volume (if predictable traffic):
5M txns/mo reserved = $80/mo (vs $97 on-demand)
Saves ~$17/mo, locks in price for 12 months
→ Total: ~$106/month
const initStart = performance.now ();
Sentry .init ({ });
const initMs = performance.now () - initStart;
console .log (`Sentry.init: ${initMs.toFixed(1 )} ms` );
import { performance, PerformanceObserver } from 'node:perf_hooks' ;
async function benchmarkOverhead (iterations : number = 1000 ) {
const baseStart = performance.now ();
for (let i = 0 ; i < iterations; i++) {
await handleRequest ({ path : '/api/test' , method : 'GET' });
}
const baseMs = (performance.now () - baseStart) / iterations;
const sentryStart = performance.now ();
for (let i = 0 ; i < iterations; i++) {
await Sentry .startSpan (
{ name : 'GET /api/test' , op : 'http.server' },
() => handleRequest ({ path : '/api/test' , method : 'GET' })
);
}
const sentryMs = (performance.now () - sentryStart) / iterations;
console .log (`Baseline: ${baseMs.toFixed(3 )} ms/req` );
console .log (`With Sentry: ${sentryMs.toFixed(3 )} ms/req` );
console .log (`Overhead: ${(sentryMs - baseMs).toFixed(3 )} ms (${(((sentryMs - baseMs) / baseMs) * 100 ).toFixed(1 )} %)` );
}
Load testing Sentry integration with k6:
import http from 'k6/http' ;
import { check, sleep } from 'k6' ;
import { Rate , Trend } from 'k6/metrics' ;
const errorRate = new Rate ('sentry_errors_captured' );
const latencyOverhead = new Trend ('sentry_latency_overhead_ms' );
export const options = {
stages : [
{ duration : '1m' , target : 50 },
{ duration : '3m' , target : 200 },
{ duration : '1m' , target : 0 },
],
thresholds : {
http_req_duration : ['p(95)<500' ],
sentry_latency_overhead_ms : ['p(95)<5' ],
},
};
const BASE_URL = __ENV.BASE_URL || 'http://localhost:3000' ;
export default function ( ) {
const readRes = http.get (`${BASE_URL} /api/products` );
check (readRes, { 'GET 200' : (r ) => r.status === 200 });
const sentryMs = readRes.headers ['Server-Timing' ]?.match (/sentry;dur=(\d+\.?\d*)/ );
if (sentryMs) latencyOverhead.add (parseFloat (sentryMs[1 ]));
if (Math .random () < 0.1 ) {
const writeRes = http.post (`${BASE_URL} /api/orders` , JSON .stringify ({
items : [{ sku : 'TEST-001' , qty : 1 }],
}), { headers : { 'Content-Type' : 'application/json' } });
check (writeRes, { 'POST 201' : (r ) => r.status === 201 });
}
if (Math .random () < 0.01 ) {
const errRes = http.get (`${BASE_URL} /api/nonexistent-route` );
errorRate.add (errRes.status === 404 );
}
sleep (0.1 );
}
Background worker batch patterns:
import * as Sentry from '@sentry/node' ;
async function processJobBatch (jobs : Job [] ) {
return Sentry .startSpan (
{
name : `batch.${jobs[0 ]?.type || 'unknown' } ` ,
op : 'queue.batch' ,
attributes : { 'batch.size' : jobs.length },
},
async () => {
const results = { success : 0 , failed : 0 };
for (const job of jobs) {
try {
await Sentry .withScope (async (scope) => {
scope.setTag ('job.type' , job.type );
scope.setTag ('job.queue' , job.queue );
scope.setContext ('job' , {
id : job.id ,
attempts : job.attempts ,
});
await executeJob (job);
results.success ++;
});
} catch (error) {
results.failed ++;
Sentry .captureException (error, {
tags : { 'job.id' : job.id , 'job.type' : job.type },
level : job.attempts >= 3 ? 'error' : 'warning' ,
});
}
}
Sentry .setMeasurement ('batch.success_rate' ,
results.success / jobs.length , 'ratio' );
return results;
}
);
}
setInterval (async () => {
await Sentry .flush (2000 );
}, 30_000 );
Self-hosted Sentry for enterprise (>100M events/month):
Relay: RELAY_PROCESSING_MAX_RATE: 50000, RELAY_UPSTREAM_MAX_CONNECTIONS: 200
Kafka: KAFKA_NUM_PARTITIONS: 32 (match to consumer count)
Snuba: 4+ consumer replicas for Clickhouse ingestion parallelism
Clickhouse: 16G+ RAM, dedicated SSD volumes
Self-hosted vs SaaS break-even:
SaaS at 100M events/month: ~$2,500/mo (Business plan + overage)
Self-hosted (3x r6g.2xlarge): ~$1,200/mo infra + $800/mo ops (0.25 FTE)
Break-even: ~50M events/month
→ Use SaaS up to 50M events; evaluate self-hosted above that
Output
Adaptive sampling reducing duplicate error volume by 90%+ while preserving first-occurrence fidelity
Traffic-aware tracesSampler with 5 tiers adjusting dynamically based on endpoint volume
SDK memory and CPU footprint minimized (15 breadcrumbs, truncated contexts, filtered headers)
Connection pooling via persistent HTTPS agent for efficient event submission
Multi-region infrastructure tags for filtering by region/cluster/pod in Sentry dashboard
Cost model with reserved volume pricing showing $106/month for 10M requests/day
k6 load test script validating Sentry overhead stays under 5ms at p95
Batch job processing pattern with scope isolation and periodic flush
Self-hosted vs SaaS break-even analysis for enterprise decision-making
Error Handling Error Cause Solution Events silently dropped SDK buffer full during traffic spike Increase transportOptions.bufferSize to 200+, verify network to Sentry ingest 429 rate limit from Sentry Quota exhausted or spike protection triggered Enable spike protection in Settings > Subscription, reduce sample rates Memory growing linearly over time Breadcrumb or scope accumulation Reduce maxBreadcrumbs, verify withScope is used (not configureScope) Lost events on deploy/restart No Sentry.close() in shutdown handler Add SIGTERM/SIGINT handlers calling Sentry.close(2000) Distributed traces broken at scale Mixed sampling decisions across services Always check parentSampled first in tracesSampler Clickhouse OOM on self-hosted Insufficient memory for event volume Allocate 16G+ RAM, increase Snuba consumer replicas k6 shows >5ms Sentry overhead Too many integrations or large payloads Disable Console/ContextLines integrations, reduce maxValueLength Quota burn from replay/attachments Replays not rate-limited separately Set replaysSessionSampleRate: 0.01 and replaysOnErrorSampleRate: 0.1
Examples Minimal high-scale init (copy-paste ready):
import * as Sentry from '@sentry/node' ;
Sentry .init ({
dsn : process.env .SENTRY_DSN ,
environment : process.env .NODE_ENV ,
release : `${process.env.SERVICE_NAME} @${process.env.VERSION} ` ,
maxBreadcrumbs : 15 ,
maxValueLength : 200 ,
profilesSampleRate : 0 ,
tracesSampler : ({ name, parentSampled } ) => {
if (parentSampled !== undefined ) return parentSampled ? 1.0 : 0 ;
if (name?.match (/\/(health|ping|metrics)/ )) return 0 ;
if (name?.includes ('/payment' )) return 1.0 ;
if (name?.startsWith ('POST /api/' )) return 0.05 ;
return 0.005 ;
},
});
Verify sampling is working as expected:
Sentry .init ({
tracesSampler : (ctx ) => {
const rate = calculateRate (ctx);
if (process.env .DEBUG_SENTRY === 'true' ) {
console .log (`[sentry] ${ctx.name} → rate=${rate} ` );
}
return rate;
},
});
Resources
Next Steps
Run the k6 load test against staging to establish your baseline Sentry overhead
Set up Sentry Spike Protection (Settings > Subscription > Spike Protection) before going to production
Configure server-side sampling rules in Sentry Dynamic Sampling (Project Settings > Performance) to complement client-side tracesSampler
Create a Sentry dashboard with widgets for: events/hour by category, quota usage %, p95 SDK overhead
Review the sentry-cost-tuning skill for detailed quota optimization strategies