How do I move my user ids from LangSmith to Rius?
Rius reads user ids from the user.id attribute on your spans, so you move them by setting that attribute in your code instead of putting a user id in LangSmith run metadata. In Python you set it with rius.user, and in TypeScript with withUser. Once your spans carry it, each end user appears on the Rius Users page with their traces, failures, cost and time to first token.
How it works
LangSmith has no dedicated user field, so a user id usually lives in run metadata, next to thread_id. Rius treats users as a first-class grouping, the same way it treats sessions.
- LangSmith metadata becomes span attributes. The migration guide maps metadata to span attributes set with
span.set_attribute(key, value). A custom key such asuser_idstays an ordinary attribute and is not read as a user. user.idis what makes a user. Rius builds the Users page fromuser.id. Set it withrius.userin Python orwithUserin TypeScript.- Threads work the same way. A LangSmith
thread_idmaps to a Rius session withrius.session(thread_id), which stampssession.id. Set the user and the session around the same call. - No environment variable. There is no user environment variable, by design, because a user belongs to a request and not to a process.
- Spans without a user. A trace with no
user.idcounts as anonymous. - Prefer an opaque id. Send an internal id or a hash, not an email address.
The LangSmith OpenTelemetry export (Path C in the migration guide) does not carry user ids across. A user id in run metadata arrives as a langsmith.metadata.* span attribute, not as user.id, so the Users page does not group by it.
Set it up
- Move the instrumentation to the Rius SDK first, because the user id has to be set in code that runs inside your request. For a LangChain or LangGraph app, install the extra and call
rius.init()as described in Migrate from LangSmith to Rius.
pip install "glassflow-rius[langchain]"- Find where you put the user id today. It is usually a
metadataargument like this one:
# LangSmith
@traceable(name="Chat Pipeline", metadata={"thread_id": thread_id, "user_id": user_id})
def pipeline(question: str) -> str:
...- Remove the
user_identry from the metadata. Keep the rest of the swap as the guide shows:@traceablebecomes@rius.observe, and thethread_idmetadata becomeswith rius.session(thread_id):around the call. - In the same place, set the user with
rius.userin Python, orwithUserin TypeScript, using your own user id. Set it so that every span of the request carries it, root span included.
@rius.observe(name="Chat Pipeline")
def pipeline(question: str) -> str: ...
with rius.user(user_id), rius.session(thread_id):
pipeline(question)- Pass an opaque id, such as your internal user key, rather than an email.
- Send one request, open the Users page and check that the user appears with that trace. Do this while LangSmith still receives the same traffic. The migration overview explains how to run both backends side by side until you cut over.
- If you used Path C to start without code changes, add the user id in code now. Metadata sent that way never becomes
user.id.
What you get
- Each end user your agents served on the Users page, with their traces, failures, cost and time to first token.
- Cost per user, because Rius computes cost on the server from the model and token counts. Costs are list-price estimates in US dollars.
- Sessions and users together. Traces group by
session.idfor a conversation and byuser.idfor a person, so you can follow one person across several threads. - Anonymous traffic kept separate. Traces with no
user.idcount as anonymous instead of being mixed into a real user.
What has no counterpart or does not carry over:
- History. Rius has no importer for LangSmith runs, so past traces and the user ids on them stay in LangSmith. Users appear in Rius from the first span you send with
user.id. - Tags. There is no separate tag concept. Use a span attribute.
- Feedback per user. Rius has no feedback scores or annotation queues, so feedback you tied to a user stays in LangSmith.
When something else fits
- If you cannot change code yet, LangSmith’s OpenTelemetry export gets traces into Rius quickly, but users and sessions do not group until you set
user.idandsession.idin code. - If you rely on LangSmith feedback, datasets or evaluators tied to specific users, keep LangSmith for those workflows and run Rius next to it for tracing, cost and alerts.