How do I switch from Arize Phoenix to Rius for tracing LlamaIndex?
Rius traces LlamaIndex with one install and one call: replace Phoenix’s register() with rius.init() and install the llama-index extra. Your query engines and retrievers stay as they are. Each query arrives as a nested trace with retrieval, embedding and model-call spans, and Rius computes the cost from the token counts.
How it works
Phoenix and Rius both read OpenInference spans, so this migration is a routing change, not a rewrite. The Rius Python SDK ships the same kind of OpenInference instrumentation as optional extras, and the llama-index extra covers LlamaIndex. With a default init(), every installed integration turns on automatically. That means the auto_instrument=True flag on register() and any instrumentor calls you made yourself go away.
You have two paths:
- Replace
register()withrius.init(). This is the path this article follows. You also get the Rius SDK defaults: a raised span attribute limit, privacy controls, session and user scopes, and heartbeats that show which agent processes are alive. - Keep
register()and re-point it at Rius. Pass the full traces URL,protocol="http/protobuf", your Rius API key and aservice.name. This is also how you send to both backends at once. The Phoenix migration guide has the code for both.
A Phoenix project maps to a Rius agent, which is named by service.name. Phoenix’s openinference.project.name is stored but does not group traces, so set a service name on every service. If you used separate Phoenix projects per environment, give each environment its own Rius workspace and API key.
The LlamaIndex integration is Python only. LlamaIndex.TS has no integration, so its query-engine and retriever structure is not captured.
Set it up
-
Install the instrumentation and LlamaIndex. The extra installs the instrumentation, not
llama-indexitself, so the package is named here for a fresh environment. Then removearize-phoenix-otelonce nothing else uses it.pip install "glassflow-rius[llama-index]" llama-index export RIUS_API_KEY="<your API key>" -
Replace the
register()call withrius.init(). The endpoint defaults to EU ingest, so the API key is usually the only setting. Build your indexes and query engines exactly as before.import rius rius.init(service_name="my-agent") with rius.session(conversation_id): response = query_engine.query(question) -
Switch
using_sessionandusing_usertorius.sessionandrius.userin the same change. The OpenInference context managers do not stamp spans you start withrius.start_as_current_spanor@rius.observe, which are usually the root span, so the trace would lose its session and user.rius.sessionandrius.userstamp every span in scope. -
Run one query and open the trace in the console. Check that the pipeline appears as nested spans, that the model-call span shows model, tokens and cost, and that the trace sits under the session and user you expect.
-
If you want an evaluation period, start there instead of with step 1: keep
register()pointed at Phoenix andarize-phoenix-otelinstalled, add Rius as a second exporter as the Phoenix migration guide shows, compare both backends on real traffic, then make the swap above. The migration overview covers the general routing options, and the integrations page lists which libraries are covered.
New organizations start on a free trial of 30 days or 500,000 spans, whichever comes first, with no card.
What you get
A query becomes a nested trace of typed spans on the LlamaIndex integration:
- Retrieval steps appear as RETRIEVER spans. The retriever span’s output shows what the model was given to work with, which is usually where RAG debugging starts.
- Embedding calls appear as EMBEDDING spans.
- Synthesis model calls appear as LLM spans with model, token usage and messages. Rius computes cost on its side from the model and token counts, as a list-price estimate in US dollars. You never send a cost value.
If you also installed the openai extra, an LLM’s chat or completion call, streamed or not, is traced as a second LLM span under the LlamaIndex span. Since glassflow-rius 1.1.1 the call is counted once in tokens and cost, and the LlamaIndex span still shows the call’s total. Calls from MultiModalLLM models, embedding models and retrievers are not nested: their OpenAI span starts a trace of its own.
Retrieved document content and messages are content attributes, so the privacy controls cover them. Document ids and scores stay visible even with content stripped.
What does not carry over from Phoenix: evals, datasets and experiments, annotations and feedback, and prompt management or a playground. Rius is a managed service only, so there is no self-hosting. Custom model prices are not supported, and existing Phoenix traces cannot be imported. Rius starts from the first span you send.
When something else fits
If evals, datasets or annotations are central to your workflow, send traces to both backends and keep Phoenix for those pieces rather than cutting over completely. If your LlamaIndex code is in TypeScript, there is no framework integration, so use the OpenAI integration for provider calls and manual generations for the rest of the pipeline.