|
| 1 | +--- |
| 2 | +title: Sampling Transactions |
| 3 | +sidebar_order: 20 |
| 4 | +description: "Learn how to configure the volume of transactions sent to Sentry." |
| 5 | +--- |
| 6 | + |
| 7 | +There are two ways to control the volume of transactions sent to Sentry. |
| 8 | + |
| 9 | +## Uniform Sample Rate |
| 10 | + |
| 11 | +Setting a uniform sample rate is a good option if you want an even cross-section of transactions, no matter where in your app or under what circumstances they occur, and are happy with the default inheritance and precedence behavior described below. |
| 12 | + |
| 13 | +To do this, set the `tracesSampleRate` option in your `Sentry.init()` to a number between 0 and 1, and every transaction created will have that percentage chance of being sent to Sentry. (So, for example, if you set `tracesSampleRate` to `0.2`, approximately 20% of your transactions will get recorded and sent.) That looks like this: |
| 14 | + |
| 15 | +```javascript {tabTitle: ESM} |
| 16 | +// If you're using one of our integration packages, like `@sentry/react` or `@sentry/angular`, |
| 17 | +// substitute its name for `@sentry/browser` here |
| 18 | +import * as Sentry from "@sentry/browser"; |
| 19 | + |
| 20 | +// If taking advantage of automatic instrumentation (highly recommended) |
| 21 | +import { Integrations as TracingIntegrations } from "@sentry/tracing"; |
| 22 | +// Or, if only doing manual tracing |
| 23 | +// import * as _ from "@sentry/tracing" |
| 24 | +// Note: You MUST import the package in some way for tracing to work |
| 25 | + |
| 26 | +Sentry.init({ |
| 27 | + dsn: "___PUBLIC_DSN___", |
| 28 | + |
| 29 | + // This enables automatic instrumentation (highly recommeneded), but is not |
| 30 | + // necessary for purely manual usage |
| 31 | + integrations: [new TracingIntegrations.BrowserTracing()], |
| 32 | + |
| 33 | + // Each transaction has a 20% chance of being sent to Sentry |
| 34 | + tracesSampleRate: 0.2, |
| 35 | +}); |
| 36 | +``` |
| 37 | + |
| 38 | +```javascript {tabTitle: CDN} |
| 39 | +Sentry.init({ |
| 40 | + dsn: "___PUBLIC_DSN___", |
| 41 | + |
| 42 | + // This enables automatic instrumentation (highly recommeneded), but is not |
| 43 | + // necessary for purely manual usage |
| 44 | + integrations: [new Sentry.Integrations.BrowserTracing()], |
| 45 | + |
| 46 | + // Each transaction has a 20% chance of being sent to Sentry |
| 47 | + tracesSampleRate: 0.2, |
| 48 | +}); |
| 49 | +``` |
| 50 | + |
| 51 | +## Dynamic Sampling Function |
| 52 | + |
| 53 | +Providing a sampling function is a good option if you |
| 54 | + |
| 55 | +- want to sample different transactions at different rates |
| 56 | +- want to filer out some transactions entirely |
| 57 | +- want to modify the default precedence and inheritance behavior described below |
| 58 | + |
| 59 | +To sample dynamically, set the `tracesSampler` option in your `Sentry.init()` to a function which will accept a `samplingContext` object and return a sample rate between 0 and 1. For example: |
| 60 | + |
| 61 | +```javascript |
| 62 | +tracesSampler: samplingContext => { |
| 63 | + // Examine provided context data (including parent decision, if any) along with anything |
| 64 | + // in the global namespace to compute the sample rate or sampling decision for this transaction. |
| 65 | + |
| 66 | + if ("...") { |
| 67 | + return 0.5; // These are important - take a big sample |
| 68 | + } else if ("...") { |
| 69 | + return 0.01; // These are less important or happen much more frequently - only take 1% of them |
| 70 | + } else if ("...") { |
| 71 | + return 0; // These aren't something worth tracking - drop all transactions like this |
| 72 | + } else { |
| 73 | + return 0.1; // Default sample rate |
| 74 | + } |
| 75 | +}; |
| 76 | +``` |
| 77 | + |
| 78 | +For convenience, the function can also return a boolean. Returning `true` is equivalent to returning `1`, and will guarantee the transaction will be sent to Sentry. Returning `false` is equivalent to returning `0` and will guarantee the transaction witll **not** be sent to Sentry. |
| 79 | + |
| 80 | +### Default Sampling Context Data |
| 81 | + |
| 82 | +The information contained in the `samplingContext` object passed to the `tracesSampler` when a transaction is created varies by platform. |
| 83 | + |
| 84 | +<PlatformContent includePath="performance/default-sampling-context" /> |
| 85 | + |
| 86 | +### Custom Sampling Context Data |
| 87 | + |
| 88 | +When manually creating a transaction, you can add data to the `samplingContext` by passing it as an optional second argument to `startTransaction()`. This is useful if there's data to which you want the sampler to have access but which you don't want to attach to the transaction as `tags` or `data`, such as information that's sensitive or that’s too large to send with the transaction. For example: |
| 89 | + |
| 90 | +<PlatformContent includePath="performance/custom-sampling-context" /> |
| 91 | + |
| 92 | +## Inheritance |
| 93 | + |
| 94 | +Whatever a transaction's sampling decision, that decision will be passed to its child spans and from there to any transactions they subsequently cause in other services. (See [Connecting Backend and Frontend Transactions](/platforms/javascript/performance/) for more about how that propogation is done.) |
| 95 | + |
| 96 | +If the transaction currently being created is one of those subsequent transactions (in other words, if it has a parent transaction), the upstream (parent) sampling decision will always be included in the sampling context data, so that your `tracesSampler` can choose whether and when to inherit that decision. (In most cases, inheritance is the right choice, so that you don't end up with partial traces.) |
| 97 | + |
| 98 | +For convenience, the `tracesSampler` function can return a boolean, so that a parent's decision can be returned directly if that's the desired behavior. |
| 99 | + |
| 100 | +```javascript |
| 101 | +tracesSampler: samplingContext => { |
| 102 | + // always inherit |
| 103 | + if (samplingContext.parentSampled !== undefined) { |
| 104 | + return samplingContext.parentSampled |
| 105 | + } |
| 106 | + |
| 107 | + ... |
| 108 | + // rest of sampling logic here |
| 109 | +} |
| 110 | +``` |
| 111 | + |
| 112 | +If you're using a `tracesSampleRate` rather than a `tracesSampler`, the decision will always be inherited. |
| 113 | + |
| 114 | +## Forcing a Sampling Decision |
| 115 | + |
| 116 | +If you know at transaction creation time whether or not you want the transaction sent to Sentry, you also have the option of passing a sampling decision directly to the transaction in the `transactionContext` object (note, not the `customSamplingContext` object). If you do that, the transaction won't be subject to the `tracesSampleRate`, nor will `tracesSampler` be run, so you can count on the decision that's passed not to be overwritten. |
| 117 | + |
| 118 | +```javascript |
| 119 | +Sentry.startTransaction({ |
| 120 | + name: "Search from navbar", |
| 121 | + sampled: true, |
| 122 | +}); |
| 123 | +``` |
| 124 | + |
| 125 | +## Precedence |
| 126 | + |
| 127 | +There are multiple ways for a transaction to end up with a sampling decision. |
| 128 | + |
| 129 | +- Random sampling according to a static sample rate set in `tracesSampleRate` |
| 130 | +- Random sampling according to a dynamic sample rate returned by `tracesSampler` |
| 131 | +- Absolute decision (100% chance or 0% chance) returned by `tracesSampler` |
| 132 | +- If the transaction has a parent, inheriting its parent's sampling decision |
| 133 | +- Absolute decision passed to `startTransaction` |
| 134 | + |
| 135 | +When there's the potential for more than one of these to come into play, the decision is resolved according to the following precedence rules: |
| 136 | + |
| 137 | +1. If a sampling decision is passed to `startTransaction` (`startTransaction({name: "my transaction", sampled: true})`), that decision will be used, regardlesss of anything else |
| 138 | +2. If `tracesSampleRate` is defined, its decision will be used. It can choose to keep or ignore any parent sampling decision, or use the sampling context data to make its own decision or choose a sample rate for the transaction. |
| 139 | +3. If `tracesSampler` is not defined, but there's a parent sampling decision, it will be used. |
| 140 | +4. If `tracesSampler` is not defined and there's no parent sampling decision, `tracesSampleRate` will be used. |
0 commit comments