Skip to Content

How do I track usage per developer in OpenHands?

Rius tracks OpenHands usage per developer when you pass user_id to each Conversation, so the Users page shows each developer’s conversations under their own row. Rius turns tracing on from three environment variables, with no plugin and no code changes. Conversations without a user_id land in the anonymous row. Token counts and cost are missing for some OpenHands setups, which limits what each developer’s row can show.

How it works

OpenHands needs no plugin. Its SDK already sends OpenTelemetry, and Rius takes in the traces over OTLP. Each conversation becomes one trace with its model calls and tool calls. The conversation id is the Rius session, so a multi-turn conversation groups together.

When you create a Conversation with a user_id, every span in that conversation carries it. Rius then shows the conversation under that user on the Users page. This differs from the Claude Code plugin, where each developer shows by the email they signed in with. In OpenHands, a developer shows by the user_id you pass.

What each conversation records for that developer:

  • Every model call, with its model, input and output tokens, cache reads and writes, cost, prompt and answer.
  • Every tool call, such as terminal or file_editor, with its input and output, including a terminal command and its exit code.
  • The agent name, from the script name or from agent.name metadata.

Cost is a list-price estimate in US dollars, worked out from the model and token counts. You never send a cost value.

Set it up

  1. Create a Rius API key in the console under Settings → API keys, with the Send telemetry scope. Then set the three variables that point OpenHands at Rius. Use the full /v1/traces path, http/protobuf, and %20 after Bearer. Any LMNR_* variable overrides these settings, so unset them. The full walkthrough is in the OpenHands guide.
export OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=https://ingest.eu.console.rius-glassflow.com/v1/traces export OTEL_EXPORTER_OTLP_TRACES_PROTOCOL=http/protobuf export OTEL_EXPORTER_OTLP_TRACES_HEADERS="Authorization=Bearer%20ri_..."
  1. Pass user_id when you create the Conversation. This is the step that gives you usage per developer. Use a value that identifies the developer, and prefer an opaque id to an email.
conversation = Conversation( agent=agent, workspace=".", user_id="dev-0042", observability_metadata={"agent.name": "fib-writer"}, )
  1. Run the agent from its own directory. Rius names the agent after the script, and a full path in the command shows up in the service column. The agent.name metadata above avoids this.

  2. Open the Users page in the console. The developer appears with the conversations sent under that user_id. Each developer’s own SDK script must pass the user_id, because Rius reads it from the spans.

If you want one workspace to hold the whole team’s sessions, give every developer a key for that workspace. The team guide for Claude Code shows the same one-workspace pattern.

What you get

  • A Users row for each developer with their conversations, so you can see who ran what in OpenHands.
  • Failed conversations and cost per developer, where the model calls report tokens. Claude and GPT-4o in SDK scripts come through in full.
  • An optional readable summary of a developer’s work. With root-cause analysis on, an admin can click Summarise this user on a user’s page, over up to the last 7 days.
  • Questions in an MCP client, through the Rius MCP server, such as “What did a given developer run in OpenHands yesterday?”. That question is answered by the user_activity_summary tool.

What OpenHands does not report:

  • No tokens or cost for OpenAI Responses API models such as GPT-4.1 and GPT-5, or for the web app’s streamed calls. Those developers’ rows show conversations but no spend.
  • Failed commands are not error spans. A non-zero exit code sits in the tool output, so error-rate figures do not count it.
  • OpenHands Cloud cannot send to Rius, because Cloud agents take no custom environment variables.
  • Prompts and replies are always sent. Unlike the plugin, OpenHands has no per-folder opt-in for content.

Conversations without a user_id land in the anonymous row.

When something else fits

  • If your developers use Claude Code, the Rius plugin records each one by sign-in email with no code to write. See Track Claude Code usage and cost across a team.
  • If you run the OpenHands web app, set the variables in OH_AGENT_SERVER_ENV as the OpenHands guide shows. Its conversations carry no tokens or cost.
  • To compare all the coding agents Rius traces, start from Coding agents.

Still stuck? Get help

Last updated on