Skip to content
121 changes: 31 additions & 90 deletions docs/platforms/javascript/common/tracing/configure-sampling/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,15 @@ Sentry's tracing functionality helps you monitor application performance by capt
The JavaScript SDK provides two main options for controlling the sampling rate:

1. Uniform Sample Rate (`tracesSampleRate`)
This option sets a fixed percentage of transactions to be captured:
`tracesSampleRate` is floating point value 0.0 and 1.0, which controls the probability that a transaction will be sampled.

<PlatformContent includePath="/tracing/sample-rate" />

With `tracesSampleRate` set to `0.25`, approximately 25% of transactions will be recorded and sent to Sentry. This provides an even cross-section of transactions regardless of where in your app they occur.
With `tracesSampleRate` set to `0.25`, each transaction in your application is randomly sampled with a probability of `0.25`, so you can expect that one in every four transactions will be sent to Sentry.

2. Sampling Function (`tracesSampler`)

For more granular control, you can use the `tracesSampler` function. This approach allows you to:
For more granular control, you provide a `tracesSampler` function. This approach allows you to:

- Apply different sampling rates to different types of transactions
- Filter out specific transactions entirely
Expand All @@ -28,6 +28,29 @@ For more granular control, you can use the `tracesSampler` function. This approa

<PlatformContent includePath="/tracing/trace-sampler" />

### The Sampling Context Object

When the `tracesSampler` function is called, it receives a `samplingContext` object with valuable information to help make sampling decisions:

```typescript
typescriptCopyinterface SamplingContext {
// Name of the span/transaction
name: string;

// Initial attributes of the span/transaction
attributes: SpanAttributes | undefined;

// Whether the parent span was sampled (undefined if no incoming trace)
parentSampled: boolean | undefined;

// Sample rate from incoming trace (undefined if no incoming trace)
parentSampleRate: number | undefined;

// Utility function to inherit parent decision or fallback
inheritOrSampleWith: (fallbackRate: number) => number;
}
```

### Trace Sampler Examples

1. Prioritizing Critical User Flows
Expand Down Expand Up @@ -96,98 +119,16 @@ tracesSampler: (samplingContext) => {
}
```

## The Sampling Context Object

When the `tracesSampler` function is called, it receives a `samplingContext` object with valuable information to help make sampling decisions:

```typescript
typescriptCopyinterface SamplingContext {
// Name of the span/transaction
name: string;

// Initial attributes of the span/transaction
attributes: SpanAttributes | undefined;

// Whether the parent span was sampled (undefined if no incoming trace)
parentSampled: boolean | undefined;

// Sample rate from incoming trace (undefined if no incoming trace)
parentSampleRate: number | undefined;

// Utility function to inherit parent decision or fallback
inheritOrSampleWith: (fallbackRate: number) => number;
}
```

The sampling context contains:

- `name`: The name of the transaction/span
- `attributes`: Initial tags and attributes set on the transaction
- `parentSampled`: Whether the parent transaction was sampled (for distributed tracing)
- `parentSampleRate`: The sample rate used in the parent transaction
- `inheritOrSampleWith`: A utility function to handle inheritance logic (recommended)

## Inheritance in Distributed Tracing

In distributed systems, trace information is propagated between services. The inheritOrSampleWith function simplifies handling parent sampling decisions:

```javascript
tracesSampler: (samplingContext) => {
const { name, inheritOrSampleWith } = samplingContext;

// Apply specific rules first
if (name.includes('critical-path')) {
return 1.0; // Always sample
}

// Otherwise inherit parent sampling decision or fall back to 0.1
return inheritOrSampleWith(0.1);
}
```
This approach ensures consistent sampling decisions across your entire distributed trace. All transactions in a given trace will share the same sampling decision, preventing broken or incomplete traces.

**Note:** The `inheritOrSampleWith` helper was introduced in version 9 of the SDK. For earlier versions, you can implement similar logic manually using the `parentSampled` property.

## Sampling Decision Precedence

When multiple sampling mechanisms could apply, Sentry follows this order of precedence:

- If `tracesSampler` is defined, its decision is used (can consider parent sampling)
- If no `tracesSampler` but parent sampling is available, parent decision is used
- If a sampling decision is passed to `startSpan`, that decision is used
- If `tracesSampler` is defined, its decision is used. Although the `tracesSampler` can override the parent sampling decision, most users will want to ensure their `tracesSampler` respects the parent sampling decision.
- If no `tracesSampler` is defined, but there is a parent sampling decision from an incoming distributed trace, we use the parent sampling decision
- If neither of the above, `tracesSampleRate` is used
- If none of the above are set, no transactions are sampled (0%)

## How Sampling Propagates in Distributed Traces

Sentry uses a "head-based" sampling approach:

- A sampling decision is made in the originating service (the "head")
- This decision is propagated to all downstream services via HTTP headers

The two key headers are:
- `sentry-trace`: Contains trace ID, span ID, and sampling decision
- `baggage`: Contains additional trace metadata including sample rate

Sentry automatically attaches these headers to outgoing HTTP requests when using the `browserTracingIntegration`. For other communication channels like WebSockets, you can manually propagate trace information:

```javascript
// Extract trace data from the current scope
const traceData = Sentry.getTraceData();
const sentryTraceHeader = traceData["sentry-trace"];
const sentryBaggageHeader = traceData["baggage"];

// Add to your custom request (example using WebSocket)
webSocket.send(JSON.stringify({
message: "Your data here",
metadata: {
sentryTrace: sentryTraceHeader,
baggage: sentryBaggageHeader
}
}));
```
- If none of the above are set, no transactions are sampled. This is equivalent to setting `tracesSampleRate` to `0.0`.

## Conclusion

Effective sampling is key to getting the most value from Sentry's performance monitoring while minimizing overhead. The `tracesSampler` function gives you precise control over which transactions to record, allowing you to focus on the most important parts of your application.

By implementing a thoughtful sampling strategy, you'll get the performance insights you need without overwhelming your systems or your Sentry quota.
Effective sampling is key to getting the most value from Sentry's performance monitoring while minimizing overhead. The `tracesSampler` function gives you precise control over which transactions to record, allowing you to focus on the most important parts of your application.
Original file line number Diff line number Diff line change
Expand Up @@ -60,3 +60,32 @@ Server-side SDKs handle traces automatically on a per-request basis. This means
</PlatformCategorySection>

If necessary, you can override the default trace duration by [manually starting a new trace](./custom-instrumentation#starting-a-new-trace).

## How Sampling Propagates in Distributed Traces

Sentry uses a "head-based" sampling approach:

- A sampling decision is made in the originating service (the "head")
- This decision is propagated to all downstream services

The two key headers are:
- `sentry-trace`: Contains trace ID, span ID, and sampling decision
- `baggage`: Contains additional trace metadata including sample rate

Sentry automatically attaches these headers to outgoing HTTP requests when using the `browserTracingIntegration`. For other communication channels like WebSockets, you can manually propagate trace information:

```javascript
// Extract trace data from the current scope
const traceData = Sentry.getTraceData();
const sentryTraceHeader = traceData["sentry-trace"];
const sentryBaggageHeader = traceData["baggage"];

// Add to your custom request (example using WebSocket)
webSocket.send(JSON.stringify({
message: "Your data here",
metadata: {
sentryTrace: sentryTraceHeader,
baggage: sentryBaggageHeader
}
}));
```
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: Instrumentation
description: "Learn how to configure spans to capture performance data on any action in your app."
description: "Learn how to configure spans to capture trace data on any action in your app."
sidebar_order: 40
---

Expand Down
96 changes: 0 additions & 96 deletions docs/platforms/javascript/common/tracing/span-metrics/examples.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -330,99 +330,3 @@ The frontend span tracks the user's checkout experience, while the backend span
- Monitor inventory availability impact on conversions
- Measure end-to-end order completion times
- Identify friction points in the user experience

## Job Scheduling and Processing Pipeline

**Challenge:** Understanding performance and reliability of distributed job processing systems, from job creation through completion.

**Solution:** Comprehensive tracking of job lifecycle across scheduling, queueing, and processing stages.

**Frontend Instrumentation:**
```javascript
// Client-side job submission and monitoring
Sentry.startSpan(
{
name: 'Job Submission Flow',
op: 'job.client',
attributes: {
// Job configuration
'job.type': 'video_transcoding',
'job.priority': 'high',
'job.estimated_duration_ms': 300000,

// Input metrics
'input.size_bytes': 52428800, // 50MB
'input.format': 'mp4',
'input.segments': 5,

// Client-side scheduling
'schedule.requested_start': '2024-03-15T10:00:00Z',
'schedule.deadline': '2024-03-15T11:00:00Z',

// Progress monitoring
'monitor.polling_interval_ms': 5000,
'monitor.status_updates_received': 12,
'monitor.last_progress_percent': 45
}
},
async () => {
// Job submission and progress tracking implementation
}
);
```

**Backend Instrumentation:**
```javascript
// Server-side job processing
Sentry.startSpan(
{
name: 'Job Processing Pipeline',
op: 'job.server',
attributes: {
// Queue metrics
'queue.name': 'video-processing',
'queue.provider': 'redis',
'queue.length_at_enqueue': 23,
'queue.wait_time_ms': 45000,

// Worker metrics
'worker.id': 'worker-pod-123',
'worker.current_load': 0.75,
'worker.memory_usage_mb': 1024,

// Processing stages
'processing.stages_completed': ['download', 'transcode', 'thumbnail'],
'processing.stage_durations_ms': {
'download': 12000,
'transcode': 180000,
'thumbnail': 5000
},

// Resource utilization
'resource.cpu_percent': 85,
'resource.gpu_utilization': 0.92,
'resource.memory_peak_mb': 2048,

// Job outcome
'outcome.status': 'completed',
'outcome.retry_count': 0,
'outcome.output_size_bytes': 31457280 // 30MB
}
},
async () => {
// Job processing implementation
}
)
);
```

**How the Trace Works Together:**
The frontend span tracks job submission and monitoring, while the backend span captures queue management and processing details. The distributed trace provides visibility into the entire job lifecycle, enabling you to:

- Monitor end-to-end job processing times and success rates
- Track queue health and worker resource utilization
- Identify bottlenecks in specific processing stages
- Analyze job scheduling efficiency and queue wait times
- Optimize resource allocation based on job characteristics

For more information about implementing these examples effectively, see our <PlatformLink to="/tracing/span-metrics/">Span Metrics guide</PlatformLink> which includes detailed best practices and implementation guidelines.
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,11 @@ When adding metrics as span attributes:

- Use consistent naming conventions (for example, `category.metric_name`)
- Keep attribute names concise but descriptive
- Use appropriate data types (string, number, boolean, or (non-mixed) arrays of these types)
- Use appropriate data types (string, number, boolean, or an array containing only one of these types)

## Creating Dedicated Metric Spans

For more detailed operations, task, or process tracking, you can create custom dedicated spans that focus on specific metrics or attributes that you want to track. This approach provides better discoverability and more precise span configurations, however it can also appear to create more noise in your trace waterfall.
For more detailed operations, tasks, or process tracking, you can create custom dedicated spans that focus on specific metrics or attributes that you want to track. This approach provides better discoverability and more precise span configurations, however it can also create more noise in your trace waterfall.

```javascript
Sentry.startSpan(
Expand Down