> ## 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, such as ad-hoc lookups and exploration from your IDE.

[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>
