flush()

Manually flush pending spans to Respan

Overview

flush() forces immediate export of all pending spans to Respan without closing the tracer. The JavaScript SDK automatically drains pending spans on normal Node.js process exit, so short-lived scripts do not need a final flush() only to make their last trace appear. Use flush() when your code needs an explicit export checkpoint while the process is still running.

Signature

async flush(): Promise<void>

Basic Usage

import { RespanTelemetry } from '@respan/tracing';
const respanAi = new RespanTelemetry({
apiKey: process.env.RESPAN_API_KEY,
appName: 'my-app'
});
await respanAi.initialize();
await respanAi.withWorkflow(
{ name: 'my_workflow' },
async () => {
return await processData();
}
);
// Manually checkpoint spans while the tracer stays active
await respanAi.getClient().flush();
console.log('Spans sent to Respan');

Explicit Export Checkpoints

async function main() {
const respanAi = new RespanTelemetry({
apiKey: process.env.RESPAN_API_KEY,
appName: 'batch-job'
});
await respanAi.initialize();
try {
await respanAi.withWorkflow(
{ name: 'batch_processing' },
async () => {
for (let i = 0; i < 100; i++) {
await processBatch(i);
}
return 'complete';
}
);
} finally {
// Checkpoint spans before validating or reading trace data
await respanAi.getClient().flush();
console.log('All traces flushed');
}
}
main().catch(console.error);

Periodic Flushing

await respanAi.withWorkflow(
{ name: 'long_running_job' },
async () => {
for (let i = 0; i < 1000; i++) {
await respanAi.withTask(
{ name: `batch_${i}` },
async () => {
return await processBatch(i);
}
);
// Flush every 100 batches
if (i % 100 === 0) {
await respanAi.getClient().flush();
console.log(`Flushed after batch ${i}`);
}
}
return 'complete';
}
);

Serverless Functions

Serverless runtimes can freeze or reuse the process before Node.js reaches normal process exit. Flush before returning when the trace must be exported within the invocation window.

// AWS Lambda handler
export async function handler(event: any) {
const respanAi = new RespanTelemetry({
apiKey: process.env.RESPAN_API_KEY,
appName: 'lambda-function'
});
await respanAi.initialize();
try {
const result = await respanAi.withWorkflow(
{ name: 'lambda_execution' },
async () => {
return await processEvent(event);
}
);
// Flush before Lambda freezes
await respanAi.getClient().flush();
return {
statusCode: 200,
body: JSON.stringify(result)
};
} catch (error) {
// Flush even on error
await respanAi.getClient().flush();
throw error;
}
}

Express Middleware

import express from 'express';
const app = express();
const respanAi = new RespanTelemetry({
apiKey: process.env.RESPAN_API_KEY,
appName: 'api-server'
});
await respanAi.initialize();
app.post('/api/important', async (req, res) => {
try {
const result = await respanAi.withWorkflow(
{ name: 'critical_operation' },
async () => {
return await processCriticalRequest(req.body);
}
);
// Flush immediately for critical operations
await respanAi.getClient().flush();
res.json({ success: true, result });
} catch (error) {
await respanAi.getClient().flush();
res.status(500).json({ error: error.message });
}
});
// Explicit drain for this signal path
process.on('SIGTERM', async () => {
console.log('Flushing traces before shutdown...');
await respanAi.getClient().flush();
process.exit(0);
});

Testing

import { describe, it, beforeAll, afterAll } from '@jest/globals';
describe('My Service', () => {
let respanAi: RespanTelemetry;
beforeAll(async () => {
respanAi = new RespanTelemetry({
apiKey: process.env.RESPAN_API_KEY,
appName: 'test-suite'
});
await respanAi.initialize();
});
afterAll(async () => {
// Flush all test traces
await respanAi.getClient().flush();
});
it('should process data', async () => {
await respanAi.withWorkflow(
{ name: 'test_workflow' },
async () => {
const result = await processData();
expect(result).toBeDefined();
}
);
});
});

With shutdown()

For complete cleanup, use shutdown() instead of flush(). shutdown() flushes and then closes the tracer.

// Flush only (tracer stays active)
await respanAi.getClient().flush();
// Shutdown (flush + close tracer)
await respanAi.shutdown();

Best Practices

  • Do not add a final flush() to short-lived Node.js scripts only for normal process exit; the SDK drains pending spans automatically
  • Use flush() for explicit checkpoints, tests that read exported traces before exit, critical operations, and serverless invocations that may freeze before process exit
  • Use shutdown() when you want complete cleanup and to close the tracer
  • Flush is automatically called periodically when batching is enabled
  • Awaiting flush() waits for export to complete
  • In long-running processes, prefer shutdown() over flush() when the process is done tracing