Skip to Content
Rius

How do I switch from Langfuse to Rius for tracing the OpenAI API?

Rius traces OpenAI calls through its openai integration, so you replace the Langfuse setup with one install and one init call. Once init runs, every OpenAI client call in your process becomes a traced model call with its model, token counts and cost. Your call sites stay as they are. You can send traces to both tools while you compare, then remove Langfuse.

How it works

Rius and Langfuse are both OpenTelemetry-based, so the move is mostly a routing change. How much you change depends on how you trace OpenAI today.

  • You use the Langfuse SDK (@observe, start_as_current_observation). Swap it for the Rius SDK. The two have the same shape: a decorator, context managers for spans and generations, and session and user scopes. The OpenAI integration instruments the client library for the whole process, so you may not need to port your manual generation blocks at all.
  • You send OTLP to Langfuse (OpenInference, OpenLLMetry or a plain OpenTelemetry SDK). Keep your instrumentation and re-point the exporter at Rius. Rius reads the OpenTelemetry GenAI conventions and the OpenInference and OpenLLMetry attributes.

The mapping from the Langfuse SDK to the Rius SDK:

  • Langfuse(public_key=..., secret_key=...) becomes rius.init(api_key="ri_...", service_name="my-agent"). One RIUS_API_KEY replaces the Langfuse key pair.
  • @observe() becomes @rius.observe.
  • start_as_current_observation(as_type="span", name=...) becomes rius.start_as_current_span(name).
  • propagate_attributes(session_id=...) becomes with rius.session(session_id):, and user_id becomes with rius.user(user_id):.

A Langfuse project maps to an agent in Rius, named by service.name. Give each environment its own workspace and API key.

Set it up

  1. Install the Rius SDK with the OpenAI extra. The extra installs the instrumentation, not openai itself, so a project that already calls OpenAI keeps its own version. In TypeScript, install npm install @arizeai/openinference-instrumentation-openai next to @glassflow-ai/rius.

    pip install "glassflow-rius[openai]" openai
  2. Replace the Langfuse client setup with rius.init, and call it before you create the OpenAI client. Use the client exactly as before. Installation details are on the integrations page and the OpenAI integration page.

    import rius from openai import OpenAI rius.init(api_key="ri_...", service_name="my-agent") client = OpenAI() # use the client exactly as before
  3. Swap the Langfuse decorators and scopes for the Rius ones from the mapping above. Delete a manual generation block around an OpenAI call only after you have seen that call in Rius as a model call. Where you keep one, rius.start_as_current_generation(model=..., provider=...) takes the place of start_as_current_observation(as_type="generation", ...).

  4. Turn on usage for streamed calls. OpenAI sends no token usage on a stream unless you ask for it, and no tokens means no cost.

    stream = client.chat.completions.create( model="gpt-4o-mini", messages=messages, stream=True, stream_options={"include_usage": True}, )
  5. If you export OTLP instead of using the Langfuse SDK, change the exporter variables and leave the instrumentation alone:

    export OTEL_EXPORTER_OTLP_ENDPOINT="https://ingest.eu.console.rius-glassflow.com" export OTEL_EXPORTER_OTLP_PROTOCOL="http/protobuf" export OTEL_EXPORTER_OTLP_HEADERS="authorization=Bearer <your API key>"
  6. Run both backends side by side for a few days. With a Collector, add Rius as a second exporter. Rius takes OTLP over HTTP, so use the otlphttp exporter. Compare trace counts, token totals and cost, then remove Langfuse and revoke its keys. The Langfuse migration guide has the full cutover checklist.

What you get

Run one call, then open the trace in the console. You see:

  • A span for each chat completion with the model, token usage and the input and output messages.
  • The resolved model name, for example gpt-4o-mini-2024-07-18.
  • A cost for the call. Rius computes it from the model and tokens, so you never send a cost value. Costs are list-price estimates in US dollars.
  • Time to first token on streamed calls in Python, with no manual code. In TypeScript, streamed chat completions carry no time to first token.
  • An ERROR span for a call OpenAI rejects, such as a 404, a 429 or a timeout, with error.type naming the error class.
  • Your OpenAI calls nested inside the run when you wrap the calling function with @rius.observe, instead of standalone traces.

Sessions and users carry over. Each user’s cost, failures and traces appear on the Users page. Prompt and response content follows your privacy controls, so capture_content=False applies to instrumented calls as it does to manual ones.

When something else fits

  • Rius has no scores, annotation queues, evals, datasets or prompt management. If you rely on them, keep Langfuse for those workflows and send traces to both tools.
  • Rius is a managed service only, so it does not fit if you need to self-host.
  • Existing traces stay in Langfuse, and Rius starts from the first span you send. The Migrate to Rius guide covers the other tools and paths.

Still stuck? Get help

Last updated on