Skip to Content

How do I move my user ids from Arize Phoenix to Rius?

Rius reads the same user.id attribute that Arize Phoenix uses, so your user ids move over by sending your spans to Rius, with no renaming or mapping table. If you keep Phoenix’s using_user, check that the root span of each trace also carries the id. If you switch to the Rius SDK, rius.user replaces using_user and stamps every span in its scope. Ids on traces already stored in Phoenix stay there.

How it works

Phoenix and Rius share one convention for users, so the id itself needs no translation.

  • Phoenix: using_user(user_id) from openinference-instrumentation stamps user.id on the spans it creates.
  • Rius: the same user.id attribute feeds the Users page, which lists each end user your agents served with their traces, failures, cost and time to first token.
  • Root span: the trace list shows a trace under the user of its root span, the top-level span, usually your request handler. using_user only stamps spans created by OpenInference: the instrumentors and the tracer from the provider register() returns. A root span started from a plain OpenTelemetry tracer misses it, and the trace shows no user even though the model call inside carries the right id.
  • No user id: a span with no user.id counts as anonymous.
  • Metadata and tags: Phoenix’s using_metadata and using_tags become ordinary span attributes in Rius. You can filter on them by key, but they get no dedicated view, so they do not stand in for a user id.

The SDK path differs in one way. rius.user stamps every span in its scope, the root and the instrumentors’ spans included, so the root span gap does not arise.

Set it up

  1. Re-point your exporter. Keep your OpenInference instrumentors and send spans to Rius, or send to both backends while you compare. The Migrate from Arize Phoenix guide has the exporter code for both setups and the side by side variant. Your using_user calls need no edit on this path.

  2. Put the id on the root span. If your root span comes from a plain OpenTelemetry tracer, set the attributes on it yourself, or start it from the OpenInference tracer:

with tracer.start_as_current_span( "handle-turn", attributes={"session.id": conversation_id, "user.id": user_id}, ): run_agent(message)
  1. Or switch to the Rius SDK. Replace register() with rius.init() and using_user with rius.user. Do the same for using_session and rius.session in the same change, because the OpenInference context managers do not stamp spans you start with rius.start_as_current_span or @rius.observe.
pip uninstall arize-phoenix-otel pip install "glassflow-rius[openai]" export RIUS_API_KEY="<your API key>"
# Before from phoenix.otel import register from openinference.instrumentation import using_user register(project_name="my-agent", auto_instrument=True) with using_user(user_id): run_agent(message)
# After import rius rius.init(service_name="my-agent") with rius.user(user_id): run_agent(message)
  1. Choose what you send as the id. Prefer an opaque id, such as your own database key, to an email address. Rius has no environment variable for users, by design, so set the id in code on each request. In TypeScript the scope is withUser.

  2. Verify. Send one traced request and open the Users page. Your user should appear with that trace. If it shows as anonymous, the root span is missing user.id. The Migrate to Rius page lists the other migration guides if your setup also includes another tool.

What you get

  • Your existing user.id values keep their meaning, so a user is the same user before and after the move.
  • A Users page with each end user’s traces, failures, cost and time to first token. Cost is a list-price estimate in US dollars that Rius computes from model and token counts, and you never send it.
  • Session and user grouping that works together: set session.id and user.id on every span, the root included, and each trace sits under the right session and user.
  • With the Rius SDK, one scope per id that covers the root and instrumentor spans alike.

Two things have no counterpart. Phoenix annotations and feedback are not available in Rius, so labels you attached to a user’s spans do not carry over. And there is no import of historical Phoenix data: Rius starts from the first span you send, so older user history stays in Phoenix.

When something else fits

  • If you rely on annotations, feedback or evals tied to specific users, keep Phoenix for those workflows and run both backends side by side rather than cutting over completely.
  • If you need user history from before the move, keep your Phoenix instance or an export of it, because Rius does not import past traces.

Still stuck? Get help

Last updated on