# Sentry: tracesSampleRate 1.0 is a dev setting, not a production one
## Why this matters
Every quickstart sets the sample rate to 1.0 so you see data immediately. In production, 1.0 means every transaction becomes a billed span. On a busy service that is the difference between a normal bill and an incident. Treat the docs example as scaffolding, not configuration.
## The shape to use
```js
tracesSampleRate: process.env.NODE_ENV === "development" ? 1.0 : 0.1,
```
```python
traces_sample_rate = 1.0 if os.environ.get("DEBUG") else 0.1
```
Start at 0.05-0.2 in production, watch the Usage stats page for a week, then tune. Sampling is probabilistic; low rates still catch recurring problems, they just take longer to reach significance.
## Dynamic sampling
When one rate does not fit (health checks vs checkout flow), use the sampler callback instead of a flat rate. It receives context about the transaction and returns a float 0-1; returning 0 drops it. Keep the function cheap: it runs for every transaction.
- Python: `traces_sampler`
- JS: `tracesSampler`
- Laravel: `traces_sampler` option, or the `SentryTracesSampleRate` job middleware to lower the rate for specific queued jobs that would otherwise dominate volume
## Know the zero semantics
- `0` = no new traces start (but incoming distributed traces from other services still continue).
- `None`/`undefined` (unset) = tracing fully disabled.
If transactions vanish after a config change, check you did not set 0 when you meant low, and remember v11 JS defaults to stream mode where `ignoreTransactions` no longer filters anything.
## Backstops
Enable spike protection per project (Settings > Spike Protection) so an anomaly cannot drain the quota in an hour. It drops excess volume instead of billing it.