Skip to Content

How do I migrate from Traceloop to Rius?

Rius accepts the OpenTelemetry traces that Traceloop’s OpenLLMetry already sends, so you keep your instrumentation and change only its export settings. You set a new base URL and an auth header, switch off OpenLLMetry metrics in Python, and your workflow, task, agent and tool decorators keep working. Run Traceloop and Rius side by side while you compare, then cut over. The Traceloop migration guide has the full walkthrough, and Migrate to Rius covers the other tools.

How it works

Traceloop’s SDK is OpenLLMetry, which is plain OpenTelemetry and exports OTLP over HTTP to whatever endpoint you give it. Rius takes OTLP over HTTP with a Bearer API key, so the move is a configuration change.

What stays

  • Your OpenLLMetry auto-instrumentation and your @workflow, @task, @agent and @tool decorators, or their TypeScript with... forms.
  • Your conversation ids. OpenLLMetry writes gen_ai.conversation.id, and Rius reads it as the session.

What changes

  • The base URL and the auth header. The Traceloop API key is replaced by a Rius API key.
  • LLM calls appear as generations with model, tokens and cost. Rius computes cost from the spans as a list-price estimate in US dollars, so you send no cost value.
  • Agents and tools appear as agent and tool spans with their names. Workflows and tasks appear as generic steps.
  • app_name or appName becomes the service name, which names the agent your traces are grouped under.
  • Association properties such as user_id and chat_id arrive as span attributes under traceloop.association.properties.*. You can inspect and filter on them, but Rius does not read them as users.

Optional: swap to the Rius SDK

The decorators map one to one onto rius.observe with a span kind, with rius.session(...) replaces conversations, and with rius.user(...) replaces association properties. Remove OpenLLMetry when you add the Rius SDK, because running both in one process produces duplicate LLM spans. Unnamed agent and tool spans also get different names, so update saved searches that match on span names.

Set it up

  1. Create a Rius workspace and an API key in the console at https://console.rius-glassflow.com. A new organization starts on a trial of 30 days or 500,000 spans, whichever comes first, with no card.
  2. Replace the Traceloop settings with the Rius ones and remove TRACELOOP_API_KEY from your deployment:
# Before: Traceloop export TRACELOOP_API_KEY="<your Traceloop API key>" # After: Rius export TRACELOOP_BASE_URL="https://ingest.eu.console.rius-glassflow.com" export TRACELOOP_HEADERS="Authorization=Bearer%20<your Rius API key>" export TRACELOOP_METRICS_ENABLED="false" # Python SDK only
  1. Check three details. In Python, leftover TRACELOOP_BASE_URL and TRACELOOP_HEADERS values override the arguments to Traceloop.init(), so clear old ones. Setting TRACELOOP_METRICS_ENABLED to false stops the Python SDK from sending metrics, which Rius does not ingest and which otherwise fail with a 404 on every export. The base URL must be http or https, because Rius accepts OTLP over HTTP only.
  2. Check whether your Python code uses get_prompt(), guardrails, user feedback, datasets or experiments. With the base URL set to Rius, those Traceloop platform features stop working. If you rely on them, keep OpenLLMetry pointed at Traceloop and add Rius through an OpenTelemetry Collector that exports to both.
  3. Run both backends in parallel. Send OpenLLMetry to a Collector with one exporter for each destination, or re-point a single service while the others keep reporting to Traceloop.
  4. If you want Rius to group traces by user, set user.id yourself, because OpenLLMetry does not. Do it inside your outermost decorated function so it lands on the root span:
from opentelemetry import trace trace.get_current_span().set_attribute("user.id", user_id)
  1. Verify one traced request end to end, compare a few days of real traffic, then remove the Traceloop exporter and revoke the Traceloop API key.

What you get

  • The same trace tree you had, with agent, tool and generation spans, and no re-instrumentation.
  • Model, token counts and cost on every LLM call, computed by Rius.
  • Sessions from your existing conversation ids, and users once you set user.id.
  • Alerts on errors, loops and metric thresholds, plus an MCP server so your coding agent can query production traces.
  • A reversible move. While both backends receive the same spans you can compare trace counts, token totals and cost before you decide.

After cutover, check that traces with a conversation id share a session, that cost appears on generations, and that any saved searches still match your span names.

When something else fits

  • Rius has no monitors, evaluators, guardrails, prompt registry, playgrounds, datasets, experiments, user feedback or gateway. If you depend on any of them, keep Traceloop for those pieces and fan traces out to both.
  • Existing traces stay in Traceloop, because Rius starts from the first span you send. Rius is a managed service only, so it does not replace a self-hosted Traceloop deployment.

Still stuck? Get help

Last updated on