Why the Sentry bill jumped during the outage
why did my sentry bill jump
A crash loop and tracing left on turn a quiet Team plan into a spike invoice. What to cut first.
On this pageShowHide
The bill jumped in the same hour the site broke. That is not a coincidence on a usage-priced error product. An outage is a spike of the same event. The meter runs hottest while you need the count.
What I opened first
Checkout returned 500s. I opened Sentry. The issue count was climbing. Tracing was still sampled. Replay was still armed on the browser SDK. The projected month moved while I was still reading chargeCard. The stack was enough to patch. The invoice was a second problem.
Tracing left on
Distributed tracing is the right tool when nothing threw and you need the slow hop. It is the wrong default tax when the page is a 500 and you already have the exception. On official Sentry SDKs, set tracesSampleRate (or traces_sample_rate / TracesSampleRate / setTracesSampleRate) to 0 when you are not using the waterfall today. On Epure, transaction items are discarded anyway. Shipping them wastes client CPU and, on Sentry Cloud, burns span budget. Guide: Disable Sentry tracing.
Crash loop arithmetic
A tight retry loop is how a quiet Team plan becomes the crash-loop scenario on Sentry cost calculator. Team is about $26 a month with 50k errors included (annual default fetched 2026-10-05 from sentry.io/pricing), then pay-as-you-go. The calculator's worked examples on this site put one tracing-on case near $171 and a crash-loop case near $713. Your numbers will differ. The shape will not: the outage is the invoice.
What to cut first
- Set traces, replay, and profile sample rates to 0 in
Sentry.initif you are not using those products in the incident. - Fix the loop or add server-side rejection for the bad payload.
- If you need the count without the meter, dual-send exceptions to a self-hosted DSN for a week, then cut the dual-send when you trust the box.
Example Node init aimed at Epure during a dual-send test:
import * as Sentry from "@sentry/node"; · Sentry.init({ · dsn: process.env.EPURE_DSN, · tracesSampleRate: 0, · profilesSampleRate: 0, · });
Pin @sentry/node at 7.120.0 when you match this site's CI line. Expect HTTP 202 and an Issues row on Epure for exception events. Verify.
Lived dual-send week
We left Sentry on for a week with rates at 0 and pointed a second init path at Epure for exceptions only. The Epure box was two containers on an existing small VPS. Spike valve kept HTTP 202 while dropping excess bodies on the hottest fingerprint; the counter still moved. Nobody negotiated an overage while patching. Gotcha: an old Epure image returned 401 invalid_dsn until we pulled current. Gotcha: environment chips hid the issue when the SDK sent staging and the UI filter was production.
Stay on Sentry when
You use replays to close support tickets, you live in traces daily, or mobile symbolication is the job. Those are real. They are not "the API is 500ing and I need the stack." Self-host Sentry if you want the suite on your metal; budget for about 16 GB and read COMPOSE_PROFILES=errors-only before you claim a smaller footprint. Sentry self-hosted RAM. Sentry out of memory.
Leave the meter when
The daily screen is exception, count, stack. You refuse a bill that spikes with the outage. You can run Docker Compose and own backups. Epure is Apache 2.0, Rust plus PostgreSQL 16, two containers, DSN swap for exceptions. Cloud list prices exist and Cloud is not live. Self-host is the path. Cheapest error tracking. Best free.
Wrong then right on the browser too
Wrong (still sampling replay while debugging a 500):
Sentry.init({ · dsn: process.env.SENTRY_DSN, · tracesSampleRate: 0.2, · replaysSessionSampleRate: 0.1, · replaysOnErrorSampleRate: 1.0, · });
Right for an errors-only week:
Sentry.init({ · dsn: process.env.SENTRY_DSN, · tracesSampleRate: 0, · profilesSampleRate: 0, · replaysSessionSampleRate: 0, · replaysOnErrorSampleRate: 0, · });
Pin @sentry/browser at 7.120.0 when matching this site's CI line. If the DSN points at Epure, replay and profile items are discarded even when rates stay high. Set them to 0 anyway so the tab stops recording. Disable session replay. Disable profiling.
Limits of the escape hatch
Self-hosting does not delete the bug. It deletes the meter. You still patch chargeCard, still own disk, still schedule upgrades. Epure grouping is a hash of exception type plus top in-app frame; a missing source map still poisons the group key. Cloud list prices are not a live checkout. If you need Sentry's suite features daily, stay and budget the meter with the calculator, or self-host Sentry with eyes open on RAM.
Decision tree after the spike
- Is the spike one fingerprint? Fix that code path first. The bill is a symptom.
- Are traces or replays sampled above zero? Zero them before you negotiate a plan upgrade.
- Do you need the suite next month? Stay on Sentry and raise the reserved volume with eyes open.
- Do you only need exceptions? Dual-send to a $0 self-host, then cut the metered DSN when Issues match.
This tree is how we stopped arguing about feeling "betrayed" by pricing and started arguing about the job. Pricing did what usage pricing does. The product scope was the real fork.
Mesh without remaking the shortlist
Do not paste the five-tool matrix here. Link Best self-hosted for installs, Best free for quotas, Cheapest for TCO. This URL owns the incident invoice story only.
Takeaway
The bill jumped because the product metered the fire. Cut unused sample rates, fix the loop, and only then decide whether the suite is still the right buy. If exceptions are the job, a $0 self-host removes the meter and leaves you the box. That is a fair trade for many SaaS and indie production teams. It is a bad trade if you needed replay all along.