Documentation Index
Fetch the complete documentation index at: https://mintlify.com/getsentry/sentry-javascript/llms.txt
Use this file to discover all available pages before exploring further.
Transport options control how the SDK sends events to Sentry, including buffering, headers, and custom endpoints.
BaseTransportOptions
From packages/core/src/types-hoist/transport.ts:
export interface BaseTransportOptions extends InternalBaseTransportOptions {
url: string;
headers?: { [key: string]: string };
}
export interface InternalBaseTransportOptions {
tunnel?: string;
bufferSize?: number;
recordDroppedEvent: Client['recordDroppedEvent'];
}
Options
url
The Sentry ingestion endpoint URL. Usually generated automatically from the DSN.{
url: 'https://o0.ingest.sentry.io/api/0/envelope/'
}
Custom HTTP headers to include in requests.Sentry.init({
dsn: 'your-dsn',
transportOptions: {
headers: {
'X-Custom-Header': 'value',
'X-API-Key': process.env.API_KEY
}
}
});
bufferSize
Maximum number of requests to buffer before dropping events.From packages/core/src/transports/base.ts:export const DEFAULT_TRANSPORT_BUFFER_SIZE = 64;
Example:Sentry.init({
dsn: 'your-dsn',
transportOptions: {
bufferSize: 30 // Limit concurrent requests
}
});
tunnel
Proxy endpoint for forwarding events. Useful for bypassing ad-blockers or CORS issues.Sentry.init({
dsn: 'your-dsn',
tunnel: '/api/tunnel'
});
Buffer Management
The transport uses a promise buffer to manage concurrent requests:
import { makePromiseBuffer } from '@sentry/core';
const buffer = makePromiseBuffer(
options.bufferSize || DEFAULT_TRANSPORT_BUFFER_SIZE
);
// Add request to buffer
buffer.add(requestTask).then(
result => result,
error => {
if (error === SENTRY_BUFFER_FULL_ERROR) {
// Buffer is full, event dropped
recordEnvelopeLoss('queue_overflow');
return Promise.resolve({});
}
throw error;
}
);
Custom Transport
Create a custom transport implementation:
import {
createTransport,
BaseTransportOptions,
TransportRequest,
TransportMakeRequestResponse
} from '@sentry/core';
function makeCustomRequest(
request: TransportRequest
): Promise<TransportMakeRequestResponse> {
return fetch(options.url, {
method: 'POST',
body: request.body,
headers: {
'Content-Type': 'application/x-sentry-envelope',
...options.headers
}
}).then(response => ({
statusCode: response.status,
headers: {
'x-sentry-rate-limits': response.headers.get('x-sentry-rate-limits'),
'retry-after': response.headers.get('retry-after')
}
}));
}
export function makeCustomTransport(
options: BaseTransportOptions
) {
return createTransport(options, makeCustomRequest);
}
Tunnel Endpoint
Implement a tunnel endpoint to proxy events:
Server-Side Tunnel
// Express.js example
import express from 'express';
import { IncomingMessage } from 'http';
const app = express();
app.post('/api/tunnel', express.raw({ type: '*/*' }), async (req, res) => {
const envelope = req.body;
const pieces = envelope.toString('utf8').split('\n');
const header = JSON.parse(pieces[0]);
// Forward to Sentry
const projectId = header.dsn?.match(/\/(\d+)$/)?.[1];
if (!projectId) {
return res.status(400).send('Invalid DSN');
}
const upstream = `https://o0.ingest.sentry.io/api/${projectId}/envelope/`;
try {
const response = await fetch(upstream, {
method: 'POST',
body: envelope,
headers: {
'Content-Type': 'application/x-sentry-envelope'
}
});
res.status(response.status).send();
} catch (error) {
res.status(500).send('Tunnel failed');
}
});
Client Configuration
import * as Sentry from '@sentry/browser';
Sentry.init({
dsn: 'your-dsn',
tunnel: '/api/tunnel'
});
HTTP Client Options
For Node.js, additional HTTP options can be configured:
import * as Sentry from '@sentry/node';
import { makeNodeTransport } from '@sentry/node';
import https from 'https';
Sentry.init({
dsn: 'your-dsn',
transport: makeNodeTransport,
transportOptions: {
headers: {
'User-Agent': 'my-app/1.0.0'
},
// Custom HTTP agent
agent: new https.Agent({
keepAlive: true,
maxSockets: 10
})
}
});
Offline Support
Implement offline queueing:
import { makeOfflineTransport, makeBrowserOfflineTransport } from '@sentry/core';
import { makeFetchTransport } from '@sentry/browser';
Sentry.init({
dsn: 'your-dsn',
transport: makeOfflineTransport(makeFetchTransport)
});
Multiplexed Transport
Send different event types to different DSNs:
import { makeMultiplexedTransport } from '@sentry/core';
import { makeFetchTransport } from '@sentry/browser';
Sentry.init({
dsn: 'default-dsn',
transport: makeMultiplexedTransport(
makeFetchTransport,
(args) => {
// Route errors to different DSN
if (args.getEvent().type === 'error') {
return [{ dsn: 'errors-dsn' }];
}
// Route transactions to different DSN
if (args.getEvent().type === 'transaction') {
return [{ dsn: 'transactions-dsn' }];
}
return [];
}
)
});
Rate Limiting
The transport automatically handles rate limiting:
// From packages/core/src/transports/base.ts
// Rate limited items are dropped
forEachEnvelopeItem(envelope, (item, type) => {
const dataCategory = envelopeItemTypeToDataCategory(type);
if (isRateLimited(rateLimits, dataCategory)) {
options.recordDroppedEvent('ratelimit_backoff', dataCategory);
} else {
filteredEnvelopeItems.push(item);
}
});
// Update rate limits from response
rateLimits = updateRateLimits(rateLimits, response);
Request Retry
Implement custom retry logic:
import { createTransport, BaseTransportOptions } from '@sentry/core';
function makeRequestWithRetry(
request: TransportRequest,
retries = 3
): Promise<TransportMakeRequestResponse> {
return fetch(options.url, {
method: 'POST',
body: request.body
})
.then(response => {
if (response.status >= 500 && retries > 0) {
// Retry on server errors
return new Promise(resolve => {
setTimeout(() => {
resolve(makeRequestWithRetry(request, retries - 1));
}, 1000 * (4 - retries)); // Exponential backoff
});
}
return {
statusCode: response.status,
headers: {
'x-sentry-rate-limits': response.headers.get('x-sentry-rate-limits'),
'retry-after': response.headers.get('retry-after')
}
};
});
}
Compression
Enable compression for smaller payloads:
import { gzipSync } from 'zlib';
import { createTransport } from '@sentry/core';
function makeCompressedRequest(
request: TransportRequest
): Promise<TransportMakeRequestResponse> {
const compressed = gzipSync(request.body);
return fetch(options.url, {
method: 'POST',
body: compressed,
headers: {
'Content-Type': 'application/x-sentry-envelope',
'Content-Encoding': 'gzip'
}
});
}
Monitor transport performance:
import { createTransport } from '@sentry/core';
function makeMonitoredRequest(
request: TransportRequest
): Promise<TransportMakeRequestResponse> {
const startTime = Date.now();
return fetch(options.url, {
method: 'POST',
body: request.body
})
.then(response => {
const duration = Date.now() - startTime;
console.log(`Transport request took ${duration}ms`);
return {
statusCode: response.status
};
});
}
Best Practices
1. Set Appropriate Buffer Size
// High-traffic applications
Sentry.init({
transportOptions: {
bufferSize: 100 // Increase for burst traffic
}
});
// Low-memory environments
Sentry.init({
transportOptions: {
bufferSize: 10 // Decrease to save memory
}
});
2. Use Tunnel for Browser Apps
// Avoid CORS and ad-blockers
Sentry.init({
dsn: 'your-dsn',
tunnel: '/api/tunnel'
});
Sentry.init({
transportOptions: {
headers: {
'Authorization': `Bearer ${token}`
}
}
});
4. Monitor Buffer Overflow
client.on('flush', () => {
const buffer = client.getTransport()?.getBuffer();
if (buffer?.isFull()) {
console.warn('Transport buffer is full');
}
});