> ## Documentation Index
> Fetch the complete documentation index at: https://braintrust.dev/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Temporal

> Trace Temporal workflow and activity executions in Braintrust to debug and monitor distributed applications

If you are a coding agent, prefer the Braintrust [`bt` CLI](/docs/reference/cli/quickstart) for repeatable, scriptable work: running evals, instrumenting code, querying logs, syncing data, managing functions, and configuring coding agents. Use the MCP server for reasoning over Braintrust data in conversation, and for capabilities the CLI doesn't cover, such as monitor views, alerts, and authoring evaluators, preprocessors, and facets.

[Temporal](https://temporal.io/) is a durable execution platform for building reliable distributed applications. Braintrust traces Temporal workflow and activity executions, linking activities to their parent workflows and propagating trace context across workers.

<View title="TypeScript" icon="https://img.logo.dev/typescriptlang.org?token=pk_BdcHD9e5SCW3j1rnJkNyMQ">
  <h2 id="setup-typescript">
    Setup
  </h2>

  Install the Braintrust Temporal integration alongside the Temporal SDK packages.

  <CodeGroup>
    ```bash pnpm theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
    pnpm add @braintrust/temporal braintrust @temporalio/client @temporalio/worker @temporalio/workflow @temporalio/activity @temporalio/common
    ```

    ```bash npm theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
    npm install @braintrust/temporal braintrust @temporalio/client @temporalio/worker @temporalio/workflow @temporalio/activity @temporalio/common
    ```
  </CodeGroup>

  <Note>
    Temporal integration requires TypeScript SDK v2.1.0+.
  </Note>

  <h2 id="manual-instrumentation-typescript">
    Manual instrumentation
  </h2>

  To trace Temporal workflows and activities, attach `BraintrustTemporalPlugin` to both your Temporal Client and Worker. Create a single plugin instance and pass it to each via the `plugins` option so spans propagate across process boundaries.

  <CodeGroup>
    ```typescript TypeScript theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
    import { Client, Connection } from "@temporalio/client";
    import { Worker } from "@temporalio/worker";
    import * as braintrust from "braintrust";
    import { BraintrustTemporalPlugin } from "@braintrust/temporal";

    // Initialize Braintrust
    braintrust.initLogger({ projectName: "my-project" });

    // Create a single plugin instance
    const plugin = new BraintrustTemporalPlugin();

    // Use the plugin with your Client
    const client = new Client({
      connection: await Connection.connect(),
      plugins: [plugin],
    });

    // Use the same plugin with your Worker
    const worker = await Worker.create({
      taskQueue: "my-task-queue",
      workflowsPath: require.resolve("./workflows"),
      activities,
      plugins: [plugin],
    });
    ```
  </CodeGroup>

  <h2 id="what-traced-typescript">
    What Braintrust traces
  </h2>

  Braintrust captures:

  * Workflow execution spans (`temporal.workflow.<workflow_type>`), with workflow type, ID, and run ID in metadata, and errors on failure.
  * Activity execution spans (`temporal.activity.<activity_type>`), with activity type and ID, parent workflow ID and run ID in metadata, the activity result as output, and errors on failure.
  * Trace context propagated across workers via Temporal headers, including to activities, local activities, and child workflows.
  * Parent-child relationships between client calls, workflows, and activities.

  <h2 id="tracing-resources-typescript">
    Tracing resources
  </h2>

  * [Braintrust Temporal integration for TypeScript](https://github.com/braintrustdata/braintrust-sdk-javascript/tree/main/integrations/temporal-js)
  * [Temporal TypeScript SDK](https://github.com/temporalio/sdk-typescript)
  * [Temporal documentation](https://docs.temporal.io/)
</View>

<View title="Python" icon="https://img.logo.dev/python.org?token=pk_BdcHD9e5SCW3j1rnJkNyMQ">
  <h2 id="setup-python">
    Setup
  </h2>

  Install Braintrust with the Temporal extra.

  ```bash theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
  pip install "braintrust[temporal]"
  ```

  <h2 id="auto-instrumentation-python">
    Auto-instrumentation
  </h2>

  To trace Temporal workflows and activities without configuring anything manually, call `braintrust.auto_instrument()` (Python SDK v0.19.0 or later). It adds `BraintrustPlugin` to any Temporal client or worker you create.

  ```python theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
  import braintrust

  braintrust.auto_instrument()
  ```

  <h2 id="manual-instrumentation-python">
    Manual instrumentation
  </h2>

  To wire tracing in yourself, import `BraintrustPlugin` from `braintrust.integrations.temporal`, instantiate it, and pass it to both your Temporal client and worker via `plugins=[plugin]`. The plugin intercepts workflow and activity executions to create spans with full context, including workflow IDs, activity types, and execution metadata.

  ```python theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
  from braintrust.integrations.temporal import BraintrustPlugin
  from temporalio.client import Client
  from temporalio.worker import Worker

  # Create a single plugin instance
  plugin = BraintrustPlugin()

  # Use the plugin with your Client
  client = await Client.connect(
      "localhost:7233",
      plugins=[plugin],
  )

  # Use the same plugin with your Worker
  worker = Worker(
      client,
      task_queue="my-task-queue",
      workflows=[MyWorkflow],
      activities=[my_activity],
      plugins=[plugin],
  )

  await worker.run()
  ```

  <Note>
    The `braintrust.contrib.temporal` module is deprecated in Python SDK v0.19.0. Imports from `braintrust.contrib.temporal` still work but emit a `DeprecationWarning`. Update imports to `braintrust.integrations.temporal`.
  </Note>

  <h2 id="what-traced-python">
    What Braintrust traces
  </h2>

  Braintrust captures:

  * Workflow execution spans (`temporal.workflow.<workflow_type>`), with workflow type, ID, and run ID in metadata, and errors on failure.
  * Activity execution spans (`temporal.activity.<activity_type>`), with activity type and ID, parent workflow ID and run ID in metadata, and errors on failure.
  * Local activities and child workflows, linked to their parent workflow.
  * Trace context propagated across workers via Temporal headers, with replay-safe span creation (no duplicate spans during workflow replay).
  * Parent-child relationships between client calls, workflows, and activities.

  <h2 id="tracing-resources-python">
    Tracing resources
  </h2>

  * [Building a deep research agent with Temporal](/docs/cookbook/recipes/TemporalDeepResearch)
  * [Temporal Python SDK](https://github.com/temporalio/sdk-python)
  * [Temporal documentation](https://docs.temporal.io/)
</View>

<View title="Go" icon="https://img.logo.dev/go.dev?token=pk_BdcHD9e5SCW3j1rnJkNyMQ">
  <h2 id="setup-go">
    Setup
  </h2>

  Install the Braintrust Go SDK, the Temporal SDK, and Temporal's OpenTelemetry contrib package.

  ```bash theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
  go get github.com/braintrustdata/braintrust-sdk-go
  go get go.temporal.io/sdk
  go get go.temporal.io/sdk/contrib/opentelemetry
  ```

  <h2 id="opentelemetry-go">
    OpenTelemetry
  </h2>

  To trace Temporal workflows and activities through your OpenTelemetry pipeline, attach Temporal's OpenTelemetry interceptor to your client and register a Braintrust `TracerProvider`. This routes Temporal's OpenTelemetry spans through the Braintrust SDK for unified observability.

  <CodeGroup>
    ```go Go theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
    package main

    import (
    	"context"
    	"log"

    	"go.opentelemetry.io/otel"
    	"go.opentelemetry.io/otel/propagation"
    	"go.opentelemetry.io/otel/sdk/trace"
    	"go.temporal.io/sdk/activity"
    	"go.temporal.io/sdk/client"
    	"go.temporal.io/sdk/contrib/opentelemetry"
    	"go.temporal.io/sdk/interceptor"
    	"go.temporal.io/sdk/worker"
    	"go.temporal.io/sdk/workflow"

    	"github.com/braintrustdata/braintrust-sdk-go"
    )

    // MyWorkflow is a minimal workflow that executes an activity
    func MyWorkflow(ctx workflow.Context, input string) (string, error) {
    	var result string
    	err := workflow.ExecuteActivity(ctx, MyActivity, input).Get(ctx, &result)
    	return result, err
    }

    // MyActivity is a minimal activity
    func MyActivity(ctx context.Context, input string) (string, error) {
    	logger := activity.GetLogger(ctx)
    	logger.Info("Processing input", "input", input)
    	return "processed: " + input, nil
    }

    func main() {
    	ctx := context.Background()

    	// Set up OpenTelemetry TracerProvider
    	tp := trace.NewTracerProvider()
    	defer tp.Shutdown(ctx)
    	otel.SetTracerProvider(tp)

    	// Configure propagators for distributed tracing
    	otel.SetTextMapPropagator(propagation.NewCompositeTextMapPropagator(
    		propagation.TraceContext{},
    		propagation.Baggage{},
    	))

    	// Initialize Braintrust
    	_, err := braintrust.New(tp,
    		braintrust.WithProject("My Project"),
    	)
    	if err != nil {
    		log.Fatal(err)
    	}

    	// Create OpenTelemetry interceptor for Temporal
    	tracer := otel.Tracer("temporal-example")
    	tracingInterceptor, err := opentelemetry.NewTracingInterceptor(
    		opentelemetry.TracerOptions{Tracer: tracer},
    	)
    	if err != nil {
    		log.Fatal(err)
    	}

    	// Create Temporal client with tracing
    	c, err := client.Dial(client.Options{
    		Interceptors: []interceptor.ClientInterceptor{tracingInterceptor},
    	})
    	if err != nil {
    		log.Fatal(err)
    	}
    	defer c.Close()

    	// Create worker with the same client
    	w := worker.New(c, "my-task-queue", worker.Options{})
    	w.RegisterWorkflow(MyWorkflow)
    	w.RegisterActivity(MyActivity)

    	if err := w.Run(worker.InterruptCh()); err != nil {
    		log.Fatal(err)
    	}
    }
    ```
  </CodeGroup>

  <h2 id="what-traced-go">
    What Braintrust traces
  </h2>

  Braintrust captures:

  * Workflow and activity execution spans emitted by Temporal's OpenTelemetry interceptor.
  * Trace context propagated across workers and processes via OpenTelemetry propagators.
  * Parent-child relationships between workflows and activities.

  <h2 id="tracing-resources-go">
    Tracing resources
  </h2>

  * [OpenTelemetry integration](/docs/integrations/sdk-integrations/opentelemetry)
  * [Temporal Go SDK](https://github.com/temporalio/sdk-go)
  * [Temporal documentation](https://docs.temporal.io/)
</View>
