or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

context-management.mderror-capture.mdindex.mdintegrations.mdperformance-monitoring.mdsdk-initialization.mdsession-management.mdsession-replay.mdtransport.mduser-feedback.md

performance-monitoring.mddocs/

0

# Performance Monitoring

1

2

Browser performance monitoring with distributed tracing capabilities. The Sentry Browser SDK provides comprehensive performance tracking for web applications including page loads, navigation, user interactions, and custom operations.

3

4

## Capabilities

5

6

### Span Management

7

8

Create and manage performance spans to track operations.

9

10

```typescript { .api }

11

/**

12

* Start a new span to track an operation

13

* @param context - Span context configuration

14

* @returns Span instance for the created span

15

*/

16

function startSpan<T>(context: SpanContext, callback: (span: Span) => T): T;

17

18

/**

19

* Start an inactive span that must be manually activated

20

* @param context - Span context configuration

21

* @returns Span instance

22

*/

23

function startInactiveSpan(context: SpanContext): Span;

24

25

/**

26

* Start a span with manual lifecycle control

27

* @param context - Span context configuration

28

* @returns Span instance that must be manually ended

29

*/

30

function startSpanManual(context: SpanContext): Span;

31

```

32

33

**Usage Examples:**

34

35

```typescript

36

import { startSpan, startInactiveSpan } from "@sentry/browser";

37

38

// Automatic span management

39

const result = startSpan(

40

{ name: "data_processing", op: "function" },

41

(span) => {

42

span.setTag("data_type", "user_analytics");

43

span.setData("record_count", 1000);

44

45

// Your operation here

46

const processedData = processAnalyticsData();

47

48

span.setData("processed_count", processedData.length);

49

return processedData;

50

}

51

);

52

53

// Manual span management

54

const span = startInactiveSpan({

55

name: "file_upload",

56

op: "http.client",

57

});

58

59

span.setTag("file_type", "image");

60

span.setData("file_size", fileSize);

61

62

try {

63

const response = await uploadFile(file);

64

span.setData("response_size", response.size);

65

span.setStatus("ok");

66

} catch (error) {

67

span.setStatus("internal_error");

68

throw error;

69

} finally {

70

span.end();

71

}

72

```

73

74

### Active Span Management

75

76

Work with the currently active span.

77

78

```typescript { .api }

79

/**

80

* Get the currently active span

81

* @returns Active span instance or undefined if no span is active

82

*/

83

function getActiveSpan(): Span | undefined;

84

85

/**

86

* Get the root span of the current trace

87

* @returns Root span instance or undefined

88

*/

89

function getRootSpan(): Span | undefined;

90

91

/**

92

* Execute callback with a specific span as the active span

93

* @param span - Span to make active (or null to clear active span)

94

* @param callback - Function to execute with the active span

95

* @returns Result of the callback function

96

*/

97

function withActiveSpan<T>(span: Span | null, callback: () => T): T;

98

```

99

100

**Usage Examples:**

101

102

```typescript

103

import { getActiveSpan, withActiveSpan, startSpan } from "@sentry/browser";

104

105

// Get current active span

106

const currentSpan = getActiveSpan();

107

if (currentSpan) {

108

currentSpan.setTag("has_active_span", true);

109

}

110

111

// Execute code with specific active span

112

const parentSpan = startInactiveSpan({ name: "parent_operation" });

113

114

withActiveSpan(parentSpan, () => {

115

// Any spans created here will be children of parentSpan

116

startSpan({ name: "child_operation" }, () => {

117

// This span is a child of parentSpan

118

performChildOperation();

119

});

120

});

121

```

122

123

### Trace Management

124

125

Manage distributed traces across different contexts.

126

127

```typescript { .api }

128

/**

129

* Start a new trace, isolating it from any existing trace

130

* @param callback - Function to execute in the new trace context

131

* @returns Result of the callback function

132

*/

133

function startNewTrace<T>(callback: () => T): T;

134

135

/**

136

* Continue a trace from incoming headers (e.g., HTTP requests)

137

* @param headers - Headers containing trace information

138

* @param callback - Function to execute in the continued trace context

139

* @returns Result of the callback function

140

*/

141

function continueTrace<T>(

142

headers: { [key: string]: string | string[] | undefined },

143

callback: () => T

144

): T;

145

146

/**

147

* Get trace data for the current span/transaction

148

* @returns Object containing trace and baggage headers

149

*/

150

function getTraceData(): { "sentry-trace"?: string; baggage?: string };

151

152

/**

153

* Suppress tracing for the given callback

154

* @param callback - Function to execute without tracing

155

* @returns Result of the callback function

156

*/

157

function suppressTracing<T>(callback: () => T): T;

158

```

159

160

**Usage Examples:**

161

162

```typescript

163

import { startNewTrace, continueTrace, getTraceData } from "@sentry/browser";

164

165

// Start completely new trace

166

startNewTrace(() => {

167

// This creates a new trace, disconnected from any parent

168

startSpan({ name: "independent_operation" }, () => {

169

performIndependentWork();

170

});

171

});

172

173

// Continue trace from incoming request

174

function handleIncomingRequest(headers: Record<string, string>) {

175

continueTrace(headers, () => {

176

startSpan({ name: "request_handler" }, () => {

177

processRequest();

178

});

179

});

180

}

181

182

// Get trace data for outgoing requests

183

const traceData = getTraceData();

184

fetch("/api/data", {

185

headers: {

186

...traceData, // Includes sentry-trace and baggage headers

187

},

188

});

189

```

190

191

### Span Utilities

192

193

Utility functions for working with spans.

194

195

```typescript { .api }

196

/**

197

* Convert span to JSON representation

198

* @param span - Span to convert

199

* @returns JSON representation of the span

200

*/

201

function spanToJSON(span: Span): SpanJSON;

202

203

/**

204

* Create sentry-trace header from span

205

* @param span - Span to create header from

206

* @returns sentry-trace header value

207

*/

208

function spanToTraceHeader(span: Span): string;

209

210

/**

211

* Create baggage header from span

212

* @param span - Span to create header from

213

* @returns baggage header value

214

*/

215

function spanToBaggageHeader(span: Span): string | undefined;

216

217

/**

218

* Update the name of a span

219

* @param span - Span to update

220

* @param name - New name for the span

221

*/

222

function updateSpanName(span: Span, name: string): void;

223

224

/**

225

* Get all descendant spans of a given span

226

* @param span - Parent span

227

* @returns Array of descendant spans

228

*/

229

function getSpanDescendants(span: Span): Span[];

230

```

231

232

### Performance Measurements

233

234

Set custom performance measurements.

235

236

```typescript { .api }

237

/**

238

* Set a custom measurement on the current transaction

239

* @param name - Measurement name

240

* @param value - Measurement value

241

* @param unit - Measurement unit (optional)

242

*/

243

function setMeasurement(name: string, value: number, unit?: MeasurementUnit): void;

244

```

245

246

**Usage Example:**

247

248

```typescript

249

import { setMeasurement } from "@sentry/browser";

250

251

// Custom performance metrics

252

setMeasurement("custom.database.query.duration", 150, "millisecond");

253

setMeasurement("custom.cache.hit.ratio", 0.85, "ratio");

254

setMeasurement("custom.memory.usage", 1024 * 1024, "byte");

255

```

256

257

### HTTP Status Handling

258

259

Utilities for handling HTTP status codes in spans.

260

261

```typescript { .api }

262

/**

263

* Get span status from HTTP status code

264

* @param httpStatus - HTTP status code

265

* @returns Appropriate span status

266

*/

267

function getSpanStatusFromHttpCode(httpStatus: number): SpanStatus;

268

269

/**

270

* Set HTTP status on a span

271

* @param span - Span to update

272

* @param httpStatus - HTTP status code

273

*/

274

function setHttpStatus(span: Span, httpStatus: number): void;

275

```

276

277

### Browser-Specific Tracing

278

279

Browser-specific performance monitoring integrations.

280

281

```typescript { .api }

282

/**

283

* Create browser tracing integration for automatic performance monitoring

284

* @param options - Configuration options for browser tracing

285

* @returns Browser tracing integration

286

*/

287

function browserTracingIntegration(options?: BrowserTracingOptions): Integration;

288

289

/**

290

* Start a browser navigation span manually

291

* @param context - Navigation span context

292

* @returns Navigation span

293

*/

294

function startBrowserTracingNavigationSpan(context: NavigationSpanContext): Span;

295

296

/**

297

* Start a browser page load span manually

298

* @param context - Page load span context

299

* @returns Page load span

300

*/

301

function startBrowserTracingPageLoadSpan(context: PageLoadSpanContext): Span;

302

```

303

304

**Usage Example:**

305

306

```typescript

307

import { browserTracingIntegration } from "@sentry/browser";

308

309

// Enable automatic browser tracing

310

Sentry.init({

311

dsn: "YOUR_DSN",

312

integrations: [

313

browserTracingIntegration({

314

enableLongTask: true,

315

enableInp: true,

316

enableUserTimingApi: true,

317

tracePropagationTargets: ["localhost", "api.example.com"],

318

}),

319

],

320

tracesSampleRate: 0.1,

321

});

322

```

323

324

### Request Instrumentation

325

326

Instrument outgoing HTTP requests for performance monitoring.

327

328

```typescript { .api }

329

/**

330

* Default options for request instrumentation

331

*/

332

const defaultRequestInstrumentationOptions: RequestInstrumentationOptions;

333

334

/**

335

* Instrument outgoing requests for performance tracking

336

* @param options - Configuration options for request instrumentation

337

*/

338

function instrumentOutgoingRequests(options?: RequestInstrumentationOptions): void;

339

```

340

341

## Types

342

343

### Span Interface

344

345

```typescript { .api }

346

interface Span {

347

/** Set a tag on this span */

348

setTag(key: string, value: string): void;

349

350

/** Set data on this span */

351

setData(key: string, value: any): void;

352

353

/** Set the status of this span */

354

setStatus(status: SpanStatus): void;

355

356

/** Set HTTP status on this span */

357

setHttpStatus(code: number): void;

358

359

/** Update the name of this span */

360

updateName(name: string): void;

361

362

/** End this span */

363

end(timestamp?: number): void;

364

365

/** Get the span context */

366

spanContext(): SpanContext;

367

368

/** Check if span is recording */

369

isRecording(): boolean;

370

371

/** Add an event to this span */

372

addEvent(name: string, attributes?: Record<string, any>, timestamp?: number): void;

373

}

374

```

375

376

### Span Context

377

378

```typescript { .api }

379

interface SpanContext {

380

/** Name of the operation being tracked */

381

name: string;

382

383

/** Operation type (e.g., "http.client", "db.query") */

384

op?: string;

385

386

/** Description of the operation */

387

description?: string;

388

389

/** Start timestamp */

390

startTimestamp?: number;

391

392

/** End timestamp */

393

endTimestamp?: number;

394

395

/** Parent span ID */

396

parentSpanId?: string;

397

398

/** Trace ID */

399

traceId?: string;

400

401

/** Span ID */

402

spanId?: string;

403

404

/** Tags for this span */

405

tags?: Record<string, string>;

406

407

/** Data for this span */

408

data?: Record<string, any>;

409

410

/** Origin of this span */

411

origin?: string;

412

413

/** Instrumentation library info */

414

instrumenter?: string;

415

}

416

```

417

418

### Span Status

419

420

```typescript { .api }

421

type SpanStatus =

422

| "ok"

423

| "cancelled"

424

| "unknown"

425

| "invalid_argument"

426

| "deadline_exceeded"

427

| "not_found"

428

| "already_exists"

429

| "permission_denied"

430

| "resource_exhausted"

431

| "failed_precondition"

432

| "aborted"

433

| "out_of_range"

434

| "unimplemented"

435

| "internal_error"

436

| "unavailable"

437

| "data_loss"

438

| "unauthenticated";

439

```

440

441

### Browser Tracing Options

442

443

```typescript { .api }

444

interface BrowserTracingOptions {

445

/** Enable Long Task API instrumentation */

446

enableLongTask?: boolean;

447

448

/** Enable Interaction to Next Paint (INP) tracking */

449

enableInp?: boolean;

450

451

/** Enable User Timing API marks and measures */

452

enableUserTimingApi?: boolean;

453

454

/** URLs to propagate trace headers to */

455

tracePropagationTargets?: (string | RegExp)[];

456

457

/** Sample rate for navigation transactions */

458

routingInstrumentation?: (

459

customStartTransaction: (context: TransactionContext) => Transaction,

460

startTransactionOnPageLoad?: boolean,

461

startTransactionOnLocationChange?: boolean

462

) => void;

463

464

/** Maximum transaction duration in seconds */

465

maxTransactionDuration?: number;

466

467

/** Idle timeout for transactions in seconds */

468

idleTimeout?: number;

469

470

/** Enable heart beat for long running transactions */

471

heartbeatInterval?: number;

472

473

/** Mark transactions as failed if they exceed this duration */

474

finalTimeout?: number;

475

476

/** Enable automatic span creation for fetch requests */

477

traceFetch?: boolean;

478

479

/** Enable automatic span creation for XHR requests */

480

traceXHR?: boolean;

481

482

/** Before navigation callback */

483

beforeNavigate?: (context: TransactionContext) => TransactionContext | undefined;

484

}

485

```

486

487

### Request Instrumentation Options

488

489

```typescript { .api }

490

interface RequestInstrumentationOptions {

491

/** URLs to track for performance */

492

tracePropagationTargets?: (string | RegExp)[];

493

494

/** Enable tracing for fetch requests */

495

traceFetch?: boolean;

496

497

/** Enable tracing for XHR requests */

498

traceXHR?: boolean;

499

500

/** Function to determine if request should be traced */

501

shouldCreateSpanForRequest?: (url: string) => boolean;

502

503

/** Callback before creating span for request */

504

beforeSpan?: (span: Span, request: { method?: string; url: string }) => void;

505

}

506

```

507

508

### Measurement Unit

509

510

```typescript { .api }

511

type MeasurementUnit =

512

| "nanosecond"

513

| "microsecond"

514

| "millisecond"

515

| "second"

516

| "minute"

517

| "hour"

518

| "day"

519

| "week"

520

| "byte"

521

| "kilobyte"

522

| "kibibyte"

523

| "megabyte"

524

| "mebibyte"

525

| "gigabyte"

526

| "gibibyte"

527

| "terabyte"

528

| "tebibyte"

529

| "petabyte"

530

| "pebibyte"

531

| "bit"

532

| "kilobit"

533

| "megabit"

534

| "gigabit"

535

| "terabit"

536

| "petabit"

537

| "percent"

538

| "ratio"

539

| "none";

540

```

541

542

## Automatic Instrumentation

543

544

The browser tracing integration automatically creates spans for:

545

546

- **Page loads**: Complete page load performance

547

- **Navigation**: Client-side route changes

548

- **HTTP requests**: Fetch and XHR requests

549

- **User interactions**: Click events and form submissions

550

- **Long tasks**: Tasks that block the main thread

551

- **Layout shifts**: Cumulative Layout Shift (CLS) tracking

552

- **Paint timings**: First Paint, First Contentful Paint

553

- **Web Vitals**: LCP, FID, CLS metrics

554

555

## Custom Instrumentation Patterns

556

557

### Database Operations

558

559

```typescript

560

import { startSpan } from "@sentry/browser";

561

562

async function queryDatabase(query: string) {

563

return startSpan(

564

{

565

name: "db.query",

566

op: "db",

567

data: {

568

query: query.substring(0, 100), // Truncate long queries

569

db_type: "postgresql",

570

},

571

},

572

async (span) => {

573

try {

574

const result = await executeQuery(query);

575

span.setData("row_count", result.rows.length);

576

span.setStatus("ok");

577

return result;

578

} catch (error) {

579

span.setStatus("internal_error");

580

throw error;

581

}

582

}

583

);

584

}

585

```

586

587

### API Calls

588

589

```typescript

590

import { startSpan, getTraceData } from "@sentry/browser";

591

592

async function callExternalAPI(endpoint: string, data: any) {

593

return startSpan(

594

{

595

name: `API ${endpoint}`,

596

op: "http.client",

597

data: { endpoint, method: "POST" },

598

},

599

async (span) => {

600

const traceHeaders = getTraceData();

601

602

try {

603

const response = await fetch(endpoint, {

604

method: "POST",

605

headers: {

606

"Content-Type": "application/json",

607

...traceHeaders,

608

},

609

body: JSON.stringify(data),

610

});

611

612

span.setHttpStatus(response.status);

613

span.setData("response_size", response.headers.get("content-length"));

614

615

return response.json();

616

} catch (error) {

617

span.setStatus("internal_error");

618

throw error;

619

}

620

}

621

);

622

}

623

```

624

625

### Background Tasks

626

627

```typescript

628

import { startSpan } from "@sentry/browser";

629

630

function processInBackground(items: any[]) {

631

startSpan(

632

{

633

name: "background_processing",

634

op: "task",

635

data: { item_count: items.length },

636

},

637

(span) => {

638

let processed = 0;

639

640

items.forEach((item, index) => {

641

try {

642

processItem(item);

643

processed++;

644

} catch (error) {

645

span.setTag("has_errors", "true");

646

// Continue processing other items

647

}

648

649

// Update progress

650

if (index % 100 === 0) {

651

span.setData("progress", `${index}/${items.length}`);

652

}

653

});

654

655

span.setData("processed_count", processed);

656

span.setData("failed_count", items.length - processed);

657

}

658

);

659

}

660

```