sentry-rate-limits
Tools and configuration strategies to optimize Sentry event volume.
Install
mkdir -p .claude/skills/sentry-rate-limits && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/4214" && unzip -o skill.zip -d .claude/skills/sentry-rate-limits && rm skill.zipInstalls to .claude/skills/sentry-rate-limits
Activation
This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.
Manage Sentry rate limits, quotas, and event volume optimization.Key capabilities
- →Configure client-side event sampling for errors and transactions
- →Filter noisy errors using `beforeSend` to prevent them from reaching Sentry
- →Enable server-side inbound data filters for free event filtering
- →Set per-key rate limits for Sentry DSNs
- →Monitor Sentry quota usage via the stats API
- →Implement dynamic transaction sampling based on route characteristics
How it works
The skill manages Sentry rate limits and quota by configuring client-side sampling, filtering events with `beforeSend`, enabling server-side inbound filters, and setting per-key rate limits. It also provides methods to monitor quota usage.
Inputs & outputs
When to use sentry-rate-limits
- →Resolve Sentry 429 rate limit errors
- →Configure client-side event sampling
- →Filter noisy browser errors
- →Monitor and adjust project quotas
About this skill
Sentry Rate Limits & Quota Optimization
Overview
Manage Sentry rate limits, sampling strategies, and quota usage to control costs without losing visibility into critical errors. Covers client-side sampling, beforeSend filtering, server-side inbound filters, per-key rate limits, spike protection, and the usage stats API.
Prerequisites
- Sentry account with a project DSN configured
SENTRY_AUTH_TOKENwithorg:readandproject:writescopes (Settings > Auth Tokens)SENTRY_ORGandSENTRY_PROJECTslugs known- SDK installed:
@sentry/node(npm) orsentry-sdk(pip) - Current event volume visible at
sentry.io/stats/
Instructions
Step 1 — Understand Rate Limit Behavior
When your project exceeds its quota, Sentry returns 429 Too Many Requests with a Retry-After header. The SDK automatically stops sending events until the cooldown expires. Events generated during this window are permanently lost — there is no replay mechanism.
Rate limit tiers by plan:
| Plan | API Rate Limit | Notes |
|---|---|---|
| Developer | 50 RPM | Shared quota, no reserved volume |
| Team | 1,000 RPM | Per-organization, includes spike protection |
| Business | 10,000 RPM | Per-organization, custom quotas available |
| Enterprise | Custom | Negotiated per contract |
Quota categories (billed separately):
- Errors — exceptions and log messages
- Transactions — performance monitoring spans
- Replays — session replay recordings
- Attachments — file uploads (crash dumps, minidumps)
- Profiles — continuous profiling data
- Cron monitors — scheduled job check-ins
Rate limit headers returned on 429:
HTTP/1.1 429 Too Many Requests
Retry-After: 60
X-Sentry-Rate-Limit-Limit: 50
X-Sentry-Rate-Limit-Remaining: 0
X-Sentry-Rate-Limit-Reset: 1711324800
Step 2 — Configure Client-Side Sampling
Sampling is the first line of defense. Set sampleRate for errors and tracesSampleRate for performance transactions.
TypeScript / Node.js:
import * as Sentry from '@sentry/node';
Sentry.init({
dsn: process.env.SENTRY_DSN,
// Error sampling: 0.0 (drop all) to 1.0 (capture all)
sampleRate: 0.25, // Capture 25% of errors
// Transaction sampling: 0.0 to 1.0
tracesSampleRate: 0.1, // Capture 10% of transactions
// Dynamic transaction sampling — route-aware cost control
tracesSampler: (samplingContext) => {
const { name, parentSampled } = samplingContext;
// Respect parent sampling decision in distributed traces
if (parentSampled !== undefined) return parentSampled;
// Drop health checks and readiness probes entirely
if (name === 'GET /health' || name === 'GET /readiness') return 0;
if (name?.includes('/health')) return 0;
// High-value: payment and auth flows at 100%
if (name?.includes('/api/payment') || name?.includes('/api/auth')) return 1.0;
// Medium-value: API routes at 20%
if (name?.startsWith('GET /api/') || name?.startsWith('POST /api/')) return 0.2;
// Low-value: static assets — never trace
if (name?.startsWith('GET /static/') || name?.startsWith('GET /assets/')) return 0;
// Default fallback: 5%
return 0.05;
},
});
Python:
import sentry_sdk
def traces_sampler(sampling_context):
tx_name = sampling_context.get("transaction_context", {}).get("name", "")
# Drop health checks
if "/health" in tx_name or "/readiness" in tx_name:
return 0
# High-value flows
if "/api/payment" in tx_name or "/api/auth" in tx_name:
return 1.0
# API routes
if tx_name.startswith(("GET /api/", "POST /api/")):
return 0.2
# Static assets
if tx_name.startswith(("GET /static/", "GET /assets/")):
return 0
return 0.05
sentry_sdk.init(
dsn=os.environ["SENTRY_DSN"],
sample_rate=0.25, # 25% of errors
traces_sample_rate=0.1, # 10% of transactions (fallback if no sampler)
traces_sampler=traces_sampler,
)
Step 3 — Filter Noisy Errors with beforeSend
Use beforeSend to drop events before they count against your quota. This runs client-side, so filtered events never reach Sentry.
TypeScript / Node.js:
Sentry.init({
dsn: process.env.SENTRY_DSN,
beforeSend(event, hint) {
const error = hint?.originalException as Error | undefined;
// Drop browser extension errors (common in frontend SDKs)
if (event.exception?.values?.some(e =>
e.stacktrace?.frames?.some(f =>
f.filename?.includes('extensions://') ||
f.filename?.includes('moz-extension://') ||
f.filename?.includes('chrome-extension://')
)
)) {
return null; // Drop the event
}
// Drop known noisy browser errors
if (error?.message?.match(/ResizeObserver loop/)) return null;
if (error?.message?.match(/Non-Error promise rejection/)) return null;
if (error?.name === 'AbortError') return null;
if (error?.message?.match(/Load failed/)) return null;
// CRITICAL: Always capture payment errors regardless of sampleRate
if (error?.message?.includes('PaymentError') ||
event.tags?.['transaction.type'] === 'payment') {
return event; // Force capture
}
return event;
},
// Pattern-based error filtering (faster than beforeSend for known strings)
ignoreErrors: [
'ResizeObserver loop completed with undelivered notifications',
'Non-Error promise rejection captured',
/Loading chunk \d+ failed/,
'Network request failed',
'Failed to fetch',
'AbortError',
/^Script error\.?$/,
'TypeError: cancelled',
'TypeError: NetworkError when attempting to fetch resource',
],
// Block errors originating from third-party scripts
denyUrls: [
/extensions\//i,
/^chrome:\/\//i,
/^chrome-extension:\/\//i,
/^moz-extension:\/\//i,
/hotjar\.com/,
/google-analytics\.com/,
/googletagmanager\.com/,
/intercom\.io/,
],
});
Python:
def before_send(event, hint):
if "exc_info" in hint:
exc_type, exc_value, _ = hint["exc_info"]
# Drop known noisy exceptions
if exc_type.__name__ in ("ConnectionResetError", "BrokenPipeError"):
return None
# Drop health check 404s
msg = str(exc_value)
if "health" in msg.lower() and "404" in msg:
return None
# Always capture payment errors
if event.get("tags", {}).get("transaction.type") == "payment":
return event
return event
sentry_sdk.init(
dsn=os.environ["SENTRY_DSN"],
before_send=before_send,
ignore_errors=[
"ConnectionResetError",
"BrokenPipeError",
],
)
Step 4 — Enable Server-Side Inbound Data Filters
Inbound filters run on Sentry's servers before quota counting. Filtered events do not consume quota — this is free filtering.
Configure at Project Settings > Inbound Filters:
| Filter | What it blocks | Recommended |
|---|---|---|
| Legacy browsers | IE 9/10, old Safari, old Android | Enable |
| Browser extensions | Errors from browser extension code | Enable |
| Localhost events | Events from localhost / 127.0.0.1 | Enable for production projects |
| Web crawlers | Bot-generated errors (Googlebot, etc.) | Enable |
| Filtered releases | Specific release versions | Use for deprecated releases |
| Error message patterns | Custom regex patterns | Add known false-positive patterns |
Configure via API:
# Enable legacy browser filter
curl -X PUT \
-H "Authorization: Bearer $SENTRY_AUTH_TOKEN" \
-H "Content-Type: application/json" \
-d '{"active": true}' \
"https://sentry.io/api/0/projects/$SENTRY_ORG/$SENTRY_PROJECT/filters/legacy-browsers/"
# Enable browser extension filter
curl -X PUT \
-H "Authorization: Bearer $SENTRY_AUTH_TOKEN" \
-H "Content-Type: application/json" \
-d '{"active": true}' \
"https://sentry.io/api/0/projects/$SENTRY_ORG/$SENTRY_PROJECT/filters/browser-extensions/"
# Enable web crawler filter
curl -X PUT \
-H "Authorization: Bearer $SENTRY_AUTH_TOKEN" \
-H "Content-Type: application/json" \
-d '{"active": true}' \
"https://sentry.io/api/0/projects/$SENTRY_ORG/$SENTRY_PROJECT/filters/web-crawlers/"
Step 5 — Set Per-Key Rate Limits
Each DSN (Client Key) can have its own rate limit. This prevents a single project from exhausting the organization's entire quota.
Configure at Project Settings > Client Keys > Configure > Rate Limiting.
# Set rate limit to 1000 events per hour on a specific client key
# First, list client keys to find the key ID
curl -s -H "Authorization: Bearer $SENTRY_AUTH_TOKEN" \
"https://sentry.io/api/0/projects/$SENTRY_ORG/$SENTRY_PROJECT/keys/" \
| python3 -m json.tool
# Then set the rate limit
curl -X PUT \
-H "Authorization: Bearer $SENTRY_AUTH_TOKEN" \
-H "Content-Type: application/json" \
-d '{"rateLimit": {"window": 3600, "count": 1000}}' \
"https://sentry.io/api/0/projects/$SENTRY_ORG/$SENTRY_PROJECT/keys/$KEY_ID/"
Strategy for multi-environment setups:
- Production DSN: 5,000 events/hour (critical errors matter)
- Staging DSN: 500 events/hour (only need representative sample)
- Development DSN: 100 events/hour (prevent local debugging floods)
Step 6 — Enable Spike Protection
Spike protection is auto-enabled on Team and Business plans. It detects sudden event volume increases and temporarily rate-limits the project to prevent quota exhaustion from error storms.
Configure at Organization Settings > Spike Protection.
When spike protection triggers:
- Sentry detects volume exceeding 10x normal baseline
- Events are temporarily dropped (429 returned to SDK)
- An email notification is sent to organization owners
- Protection auto-disables after the spike subsides
For programmatic spike alerts, set up a Sentry alert rule:
- Condition: Number of events in project exceeds threshold
- **Ac
Content truncated.
Prerequisites
Limitations
- →Events generated during a rate limit cooldown are permanently lost
- →Incorrect `beforeSend` logic can drop critical events
- →Overly aggressive sampling can lead to loss of visibility into errors
How it compares
This skill provides a structured approach to managing Sentry event volume and costs through various filtering and sampling mechanisms, offering more control than relying on default Sentry behavior.
Compared to similar skills
sentry-rate-limits side by side with the closest alternatives in the catalog.
| Skill | Installs | Updated | Safety | Difficulty |
|---|---|---|---|---|
| sentry-rate-limits (this skill) | 1 | 27d | Caution | Intermediate |
| optimizing-performance | 1 | 2mo | Review | Intermediate |
| langfuse | 7 | 6mo | No flags | Intermediate |
| agent-v3-performance-engineer | 3 | 6mo | No flags | Advanced |
Try saying
Example prompts that trigger this skill in your AI assistant.
More by jeremylongshore
View all by jeremylongshore →You might also like
optimizing-performance
CloudAI-X
Analyzes and optimizes application performance across frontend, backend, and database layers. Use when diagnosing slowness, improving load times, optimizing queries, reducing bundle size, or when asked about performance issues.
langfuse
davila7
Expert in Langfuse - the open-source LLM observability platform. Covers tracing, prompt management, evaluation, datasets, and integration with LangChain, LlamaIndex, and OpenAI. Essential for debugging, monitoring, and improving LLM applications in production. Use when: langfuse, llm observability, llm tracing, prompt management, llm evaluation.
agent-v3-performance-engineer
ruvnet
Agent skill for v3-performance-engineer - invoke with $agent-v3-performance-engineer
managing-api-cache
jeremylongshore
Implement intelligent API response caching with Redis, Memcached, and CDN integration. Use when optimizing API performance with caching. Trigger with phrases like "add caching", "optimize API performance", or "implement cache layer".
openrouter-streaming-setup
jeremylongshore
Implement streaming responses with OpenRouter. Use when building real-time chat interfaces or reducing time-to-first-token. Trigger with phrases like 'openrouter streaming', 'openrouter sse', 'stream response', 'real-time openrouter'.
sentry-multi-env-setup
jeremylongshore
Configure Sentry across multiple environments. Use when setting up Sentry for dev/staging/production, managing environment-specific configurations, or isolating data. Trigger with phrases like "sentry environments", "sentry staging setup", "multi-environment sentry", "sentry dev vs prod".