Skip to Content

How do I move my historical traces from Arize Phoenix to Rius?

Rius does not import historical traces from Arize Phoenix. You keep that history in Phoenix and send new traces to Rius, which starts from the first span you export. Your OpenInference instrumentation stays, and you change where its exporter sends spans. Running both backends side by side lets you build up history in Rius while Phoenix keeps the old data.

How it works

Phoenix and Rius both read OpenInference spans, so moving to Rius is a routing change. Rius ingests traces as they are exported, and there is no import path for data already stored in Phoenix. The Migrate to Rius overview and the Arize Phoenix migration guide cover the full move. Here is how the Phoenix concepts map once new traces arrive:

  • Project becomes an agent, named by the service.name resource attribute. Phoenix’s openinference.project.name is stored but does not drive grouping. If you use separate projects per environment, give each environment its own workspace and API key.
  • Trace and span kind carry over as they are. AGENT, LLM, TOOL, CHAIN, RETRIEVER, EMBEDDING and RERANKER are read as they are.
  • LLM spans are read as generations, so the span gets model, token and cost analytics.
  • Session and user use the same session.id and user.id attributes.
  • Metadata and tags are stored as span attributes and can be filtered by key. There are no dedicated views for them.
  • Cost is computed by Rius from the model and token counts. You send tokens, never cost.

Several Phoenix features have no counterpart in Rius:

  • Evals, datasets and experiments.
  • Annotations and feedback.
  • Prompt management and the playground.
  • Custom model prices. Rius prices calls at the providers’ public list prices, and a model it does not know stays unpriced (empty, not $0).
  • Self-hosting. Rius is a managed service only.

Set it up

  1. Create a Rius workspace and an API key. A new organization starts on a trial of 30 days or 500,000 spans, whichever comes first, with no card.
  2. Keep Phoenix exactly as it runs today and add Rius as a second span processor on the same provider. Pass replace_default_processor=False, otherwise the provider that register() returns drops its Phoenix exporter and your Phoenix project goes quiet.
import os from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter from opentelemetry.sdk.resources import Resource from opentelemetry.sdk.trace.export import BatchSpanProcessor from phoenix.otel import register # Phoenix, configured as today (PHOENIX_COLLECTOR_ENDPOINT, PHOENIX_API_KEY) tracer_provider = register( project_name="my-agent", batch=True, resource=Resource.create({"service.name": "my-agent"}), auto_instrument=True, ) # Rius, as a second exporter tracer_provider.add_span_processor( BatchSpanProcessor( OTLPSpanExporter( endpoint="https://ingest.eu.console.rius-glassflow.com/v1/traces", headers={"Authorization": f"Bearer {os.environ['RIUS_API_KEY']}"}, ) ), replace_default_processor=False, )
  1. Set service.name on every service. Without it your traces arrive as unknown_service, because Rius does not group by the Phoenix project attribute.
  2. Set session.id and user.id on every span of the trace, the root span included. The OpenInference using_session and using_user helpers only stamp spans that OpenInference creates, so start your root spans from the tracer your provider returns, or set the attributes on the root yourself. Otherwise the trace appears as a single-trace session with no user.
  3. If you want the Rius SDK instead of register(), replace it with rius.init(service_name="my-agent") and switch using_session and using_user to rius.session and rius.user in the same change. The Phoenix migration guide has the full API mapping.
  4. Verify one traced request end to end: the tree looks right, the LLM span shows model and token counts, cost appears, and the trace sits under the expected session and user. Then compare both backends on real traffic for a few days.
  5. When you are satisfied, remove the Phoenix exporter and revoke the Phoenix API key once nothing sends to it. Leave Phoenix, or an export of it, in place for as long as you need the old traces.

What you get

  • New traces in Rius from the first span you send, with the same trace trees you see in Phoenix.
  • Session and user grouping from the attributes you already set.
  • Cost per call computed by Rius, as list-price estimates in US dollars, without you sending a cost value.
  • Alerts and an MCP server so your coding agent can query production traces.
  • A reversible migration. Both backends receive identical spans until you remove the Phoenix exporter, so you can compare before you cut over.
  • A clear split of responsibilities. Phoenix holds your history, and Rius holds everything from the first exported span onward.

When something else fits

  • If you must query old traces alongside new ones in one place, keep Phoenix running for the history, because Rius has no import of historical data.
  • If evals, datasets or annotations are central to your workflow, keep Phoenix for those pieces and run it side by side with Rius rather than cutting over completely.

Still stuck? Get help

Last updated on