Skip to main content
Restate is a durable execution platform that makes AI agents and workflows resilient and resumable. It handles retries, recovery, orchestration, agent-to-agent communication, human-in-the-loop approvals, and task control out of the box. Restate spans and OpenInference spans come from two different processes. The restate-server process exports the execution journal — ingress, invocation start, each attempt, invocation end. Your service process exports the agent’s LLM and tool spans. Wrapping your tracer provider in Restate’s RestateTracerProvider attaches the agent spans to the invocation attempt, so once both processes export to Arize AX you get a single trace covering the durable workflow and the agent that runs inside it.
Both exporters are required. If only the service process exports to Arize AX, RestateTracerProvider still parents the agent spans to a Restate span that never arrives, and the trace lands as orphaned spans with no root. Configure restate-server as well, as shown in Export the Restate journal.

Prerequisites

Launch Arize AX

  1. Sign in to your Arize AX account.
  2. From Space Settings, copy your Space ID and API Key. You will set them as ARIZE_SPACE_ID and ARIZE_API_KEY below.

Install

This example uses the OpenAI Agents SDK. Any framework with an OpenInference instrumentor works the same way.
The tracing extra installs the OpenTelemetry API that RestateTracerProvider needs, and the openai extra installs the Agents SDK plus Restate’s integration for it. Installing restate-sdk on its own gives you an ImportError on restate.ext.tracing.

Configure credentials

Setup tracing

Wrap the tracer provider returned by register in RestateTracerProvider, then hand that to the instrumentor:

Export the Restate journal

restate-server exports its own spans, so point it at Arize AX too. Arize AX authenticates with the authorization and arize-space-id headers, and reads the project from the openinference.project.name resource attribute. Set all three in the server’s environment:
Each underscore in the part after RESTATE_TRACING_HEADERS__ becomes a hyphen in the header name, so RESTATE_TRACING_HEADERS__ARIZE_SPACE_ID sends arize-space-id. Naming it RESTATE_TRACING_HEADERS__SPACE_ID instead sends space-id, which Arize AX rejects with HTTP 403. Setting the project matters because restate-server has no flag for it. Reusing $ARIZE_PROJECT_NAME keeps both halves of the trace in one project; give the server a different value and the journal spans and agent spans land in separate projects. Restate also accepts these headers in a config file under a [tracing-headers] table, but the environment form keeps your API key out of a file on disk.
For EU spaces both exporters have to move, or half the trace goes to the wrong region and you get the orphaned spans described above. Pass endpoint=Endpoint.ARIZE_EUROPE (from arize.otel) to register in instrumentation.py, and start the server with --tracing-endpoint otlp+https://otlp.eu-west-1a.arize.com/v1/traces.

Run Restate

Define the agent as a Restate service. durable_function_tool makes each tool call recoverable, and run_typed records the API call in the journal so a retry replays it instead of repeating it:
Serve the app, start the server, register the service, then send a request. Use a separate terminal for each of the first two commands:

Expected output

The ingress returns the handler’s JSON-encoded reply, so the degree sign arrives escaped:

Verify in Arize AX

  1. Open your Arize AX space and select project restate-tracing-example.
  2. Open the newest trace. It is rooted at the Restate ingress span, with the agent’s spans under the invocation attempt:
RestateTracerProvider flattens the agent spans into siblings under the invocation attempt rather than preserving the agent framework’s own nesting, so the LLM and tool spans sit at the same depth. Restate has said a future release will preserve the original hierarchy.

Check from the skill, CLI, or SDK

Confirm spans are actually reaching your Arize AX project. Use whichever fits your workflow — the skill and CLI work for any framework; the SDK check is shown for each language.
Install the Arize Skills plugin and let your coding agent check for you:
Then prompt your agent:
Use the arize-trace skill to export and analyze recent traces from my project. Confirm spans are arriving, and summarize any errors or latency issues.

What Arize AX captures

  • Restate journal spans for the ingress request, invocation start, every invocation attempt, and invocation end, each carrying restate.invocation.id and restate.invocation.target
  • OpenInference agent, chain, LLM, and tool spans for the agent that runs inside the attempt
  • Retries as additional invocation attempt spans in the same trace, so a recovered run shows every attempt rather than only the one that succeeded

Troubleshooting

  • Spans appear with no root, or the journal spans are missing. restate-server is not exporting. Check its logs for BatchSpanProcessor.Flush.ExportError; a Status(403, ...) means the authorization or arize-space-id header is wrong. The most common cause is naming the variable RESTATE_TRACING_HEADERS__SPACE_ID, which sends space-id rather than arize-space-id.
  • Journal spans and agent spans are in different projects. OTEL_RESOURCE_ATTRIBUTES was not set for the restate-server process, or it names a different project than ARIZE_PROJECT_NAME.
  • ImportError on restate.ext.tracing. Install the extras: pip install "restate-sdk[openai,tracing]".
  • No traces at all. Confirm instrumentation is imported before agents in your service module, and that the service was registered with restate deployments register.

Resources

Restate AI documentation

Restate server tracing

OpenInference OpenAI Agents Instrumentor

OpenTelemetry context propagation