How do I move my user ids from Langfuse to Rius?
Rius maps the Langfuse user_id to user.id, which you set with rius.user in Python or on your spans from your own OpenTelemetry instrumentation. The ids you already use carry over as they are. Each user then appears on the Users page with their traces, failures and cost. Your past Langfuse traces and their user history stay in Langfuse, and Rius starts from the first span you send it.
How it works
Langfuse stores a user as the user_id on a trace. Rius stores it as the span attribute user.id. The concept is the same, so the mapping is one to one:
| Langfuse | Rius |
|---|---|
user_id | user.id |
propagate_attributes(user_id=...) | with rius.user(user_id): |
Which change you make depends on the path you take in the Langfuse migration guide:
- You use the Langfuse SDK. Swap
propagate_attributes(user_id=...)forrius.user(user_id)as part of the SDK swap. In TypeScript the equivalent iswithUser. - You send OTLP from your own instrumentation. Keep it and set
user.idon every span of the trace, the root span included. Rius reads the attribute directly, so there is nothing to translate.
The id you pass is the id Rius shows, so keep the same values you used in Langfuse if you want to recognise your users on both sides during the evaluation. If a trace has no user.id, Rius counts it as anonymous.
Rius computes cost and time to first token from the spans. You never send a cost value with the user id.
Set it up
-
Create a workspace and API key and initialise the SDK, as the Migrate to Rius overview and the Langfuse guide describe. This is the only shared setup, and it is the same for every migration.
import rius client = rius.init( api_key="ri_...", service_name="my-agent", ) -
Find where your code sets the user today. In Langfuse Python code, that is the
propagate_attributes(user_id=...)call around your request handling. -
Replace it with the Rius user scope. Keep the same id variable:
# Langfuse with propagate_attributes(user_id=user_id): handle(query)# Rius with rius.user(user_id): handle(query) -
In TypeScript, wrap the same block with
withUserinstead ofrius.user. -
If you keep your own OpenTelemetry instrumentation (Path A in the Langfuse guide), add
user.idto every span of the trace, including the root. A value set only on a child span does not cover the whole trace. -
Decide whether the id you send is safe to store. Prefer an opaque id, such as an internal account id, to an email address. If your Langfuse user ids are emails, this is a good moment to switch.
-
Send one request and open the Users page. Check that the user appears with the id you passed, and that the trace shows under that user. While you evaluate, you can send the same traces to both backends and compare the two user lists on the same traffic.
What you get
- A Users page. Each end user your agents served appears with their traces, failures, cost and time to first token. This is the same view Langfuse’s user id gave you, built from
user.id. - Per-user cost. Costs are list-price estimates in US dollars, so you can see which users drive spend.
- No new concepts to learn. The id is the same value, set in a similar scope, with the same rule that every span in the trace carries it.
- Sessions alongside users. If you also move sessions,
rius.sessionreplacespropagate_attributes(session_id=...), and both can describe the same traffic.
Two things have no counterpart:
- A user environment variable. Rius has no setting that applies one user to a whole process, by design. Set the user in code, per request, with
rius.userorwithUser, or on spans from your own instrumentation. Only sessions have a process-wide variable. - Past user history. Existing Langfuse traces stay in Langfuse. Rius does not import them, so a user’s history in Rius begins at the first span you send.
Langfuse scores, evals, datasets and prompt management also have no Rius equivalent, so any per-user score you attach there does not move. If you rely on those, keep them in Langfuse and send your traces to both tools.
When something else fits
If your user ids are tied to scores, annotation queues or eval runs in Langfuse, keep Langfuse for that work and send traces to both tools during the transition. If you need the full history of a user from before the move, read it in Langfuse, because Rius only holds what you send it from now on. The Langfuse migration guide covers the side-by-side setup and the cutover checklist.