---
title: "Trace serverless runtimes"
description: "Keep tracing alive through bundlers and runtimes that freeze."
seo:
  title: "Serverless AI Agent Tracing | Judgment Docs"
  description: "Keep Judgment tracing active through TypeScript bundlers and serverless runtimes that can freeze before spans export."
---

Bundled and serverless tracing requires two things: one server-side SDK instance
must load before traced clients in a TypeScript bundle, and completed roots must
flush before a serverless runtime freezes. Use this page for bundlers such as
Next.js and for serverless runtimes that can stop after responding.

## TypeScript bundlers

Load tracing from the runtime's instrumentation or bootstrap path before you
import traced model clients. Confirm the bundler puts that module in the
server runtime.

A bundled runtime can give each entry point its own copy of `judgeval` or
`@opentelemetry/api`. The copy you initialized is then not the copy your handler
uses, so nothing records. Keep one server-side copy of both packages.

For Next.js:

```typescript title="next.config.ts"
export default {
  serverExternalPackages: ["judgeval", "@opentelemetry/api"],
};
```

Log once at initialization. A second log when a handler loads points to a
second copy.

In TypeScript, auto-instrumentation needs all three of the following: a
preloaded instrumentation file, OpenTelemetry instrumentations registered on
`Tracer` before `Tracer.init()`, and a CommonJS build. See
[Instrument your agent](/documentation/tracing/instrumentation#use-auto-instrumentation) for the setup.

## Serverless runtimes

A serverless runtime can freeze as soon as it sends the response, which may
discard spans still waiting to export. In TypeScript, await
`Tracer.forceFlush()` after the root ends and before the handler returns. In
Python, call `Tracer.force_flush()` at the same point. Initialize the tracer once
per runtime instance and shut it down only when the process stops, not after
each request.

## Verify

First run the
[shared verification checklist](/documentation/tracing/instrumentation#verify-before-you-claim-success).
Then deploy and export a full trace on a cold call, meaning the first request
after the runtime spins up. The init log should appear once, and the completed
trace should arrive before the runtime freezes. Silent export loss is the
failure mode here: the app works while the platform shows nothing.

## Troubleshooting

| Symptom | Check |
| --- | --- |
| Tracing initializes but handlers emit nothing | Confirm the bundle uses one server-side copy of `judgeval` and `@opentelemetry/api`. |
| Warm calls work but cold calls disappear | Load instrumentation from the runtime bootstrap path before traced clients. |
| The application responds but traces are missing | Await a flush after the root ends and before the runtime can freeze. |
| Initialization logs appear per request | Initialize once per runtime instance rather than inside each handler. |

## Related pages

- [Activate the root span](/documentation/tracing/instrumentation#activate-the-root-span)
- [Streaming](/documentation/tracing/streaming) for handlers that
  return a response before generation ends
- [Durable work](/documentation/tracing/durable-work) for serverless
  handlers that enqueue work for a later worker
