Skip to Content
Rius

How much of my AI agent traffic can I attribute to end users?

Rius shows the share of your traces that carry an end user on the Users page, for example 400 of 471, and groups the rest in an anonymous row. The line above the list updates with the time window you pick. To raise the share, set the user on every request your agents handle, so that the anonymous row shrinks.

How it works

  • The count. The line above the Users list reads like “400 of 471 traces carry an end user”. It covers the window you choose (15m, 1h, 1d, 7d by default, or 30d) and counts only finished traces. A run appears once every span of it has ended.
  • What counts as an end user. A span names its end user with user.id, enduser.id or enduser.pseudo.id, and Rius takes the first one that is set. A trace with no end user on any span is anonymous.
  • The anonymous row. It always comes first in the list. Opening it shows the trace list filtered to traces with no end user, so you can see which runs lack attribution.
  • Where the user comes from. The SDKs set user.id on every span of a request that runs inside a user scope: rius.user in Python, withUser in TypeScript. There is no environment variable for the user, by design, because a process-wide value would give every request the same user.
  • Coding agents. Sessions from version 0.6.2 or later of the Rius plugin for Claude Code, Codex (beta) and Cursor (beta) carry the email the developer signed in with as user.id. Sessions from earlier plugin versions, and sessions sent with a key stored by use-key, count as anonymous. For OpenHands, pass user_id to Conversation.
  • The list size. The list shows the top 50 users for the sort you choose (traces, failed traces or cost). To reach anyone else, search by exact user ID.

Set it up

  1. Initialise the SDK once at startup, if you have not already.
import rius client = rius.init( api_key="ri_...", service_name="my-agent", )
  1. Wrap the whole handling of each request in a user scope: rius.user in Python, withUser in TypeScript. Open the scope at the outermost point, such as your request handler, so that every span, the root included, carries the user. Code paths that run outside a scope produce anonymous traces.
  2. Pass an opaque identifier, such as an internal account ID, rather than an email address. The Users page and the trace filters work with whatever string you send.
  3. For coding agents, update the Rius plugin to 0.6.2 or later and sign in with /rius:login, or the equivalent for Codex (beta) and Cursor (beta). Use the Sent by column in the trace list to see whose session a trace is.
  4. Verify in one minute. Run one request inside a user scope with a test ID such as test-user-1. Open Users, type test-user-1, click Find, and open the row. Once the trace has finished, the page shows 1 trace, your agent under Agents that served this user, and the trace under Recent traces.
  5. Watch the line above the list over the following days. If the anonymous row stays large, open it, look at which agents and trace names appear, and move the user scope further out in those code paths.

What you get

  • A single figure for how much of your traffic is attributed, per time window, so you can track it as you add user scopes.
  • A list of end users with traces, failed traces and cost, sortable so you can see who drives failures and spend.
  • A page per user with tiles for traces, failed traces, error rate, cost, sessions and time to first token (p50), plus recent and failed traces you can open.
  • A route from a support ticket to a failing span: type the exact user ID, click Find, open the row, then open the trace from the time they wrote in.
  • The same filter elsewhere: the User column in the trace list, the user_id field in the filter builder, and the user_id argument of the MCP tools list_users and user_activity_summary.
  • For the wider picture of watching agents in production, see Monitor AI agents in production.

When something else fits

  • If you only need to know whether your agents work, not who they served, you can leave user scopes out. Traces still appear, grouped as anonymous.
  • If a shared view of cost or failures across all traffic is what you want, the trace list and usage pages answer that without any user attribution.

Still stuck? Get help

Last updated on