Serverless and Flushing
Ensure traces are delivered in short-lived runtimes.
Serverless environments (Vercel, AWS Lambda, Cloudflare Workers) require special handling to ensure traces are delivered before the process exits.
The Problem
In serverless runtimes:
- The process may terminate immediately after returning a response.
- Background async tasks (like sending traces) may be killed.
- Buffered events are lost if not explicitly flushed.
The Solution: Explicit Flush
Always call flush() at the end of each request to best-effort deliver buffered events.
TypeScript
With Middleware (Recommended)
The SDK middleware handles flushing automatically:
- Express/Fastify: Calls
trace.flush()on responsefinishevent. - Next.js: Calls
trace.flush()before returning the response.
Without Middleware
export async function handler(req: Request) {
try {
const result = await processRequest(req);
return result;
} finally {
// Critical: Flush before the function exits
await njira.trace.flush();
}
}
AWS Lambda
export const handler = async (event: APIGatewayEvent) => {
try {
const result = await processEvent(event);
return { statusCode: 200, body: JSON.stringify(result) };
} finally {
await njira.trace.flush();
}
};
Python
With Middleware (Recommended)
The FastAPI middleware automatically flushes after the response is produced.
Without Middleware
async def handler(request):
try:
result = await process_request(request)
return result
finally:
await njira.flush()
AWS Lambda
def handler(event, context):
try:
result = process_event(event)
return {"statusCode": 200, "body": json.dumps(result)}
finally:
# Note: sync flush for Lambda
njira.flush_sync()
Configuration
Timeouts
Set a reasonable flush timeout to avoid hanging:
await njira.trace.flush({ timeoutMs: 2000 }); // Max 2 seconds
await njira.flush(timeout_ms=2000)
Buffer Size
Control how often the SDK auto-flushes during long-running processes:
| Variable | Description | Default |
|---|---|---|
NJIRA_BUFFER_SIZE |
Max events before auto-flush | 100 |
NJIRA_FLUSH_INTERVAL_MS |
Auto-flush interval | 5000 |
Best Practices
- Always use
try/finally: Ensures flush runs even if the handler throws. - Set reasonable timeouts: Don't let flush hang your response.
- Prefer middleware: Let the SDK handle flush timing automatically.
- Monitor for lost events: Check Console for gaps in trace data after deploys.
Edge Cases
Vercel Edge Functions
Edge functions have stricter execution limits. Use:
export const config = { runtime: 'edge' };
export default async function handler(req: Request) {
// ... your logic
await njira.trace.flush({ timeoutMs: 1000 });
return new Response("OK");
}
Cloudflare Workers
Use waitUntil to extend the execution context:
export default {
async fetch(request, env, ctx) {
const result = await handleRequest(request);
ctx.waitUntil(njira.trace.flush());
return result;
}
};