Skip to main content

Users & Sessions

This guide covers how to track users and group their interactions into sessions for effective debugging and analytics.


Overview

Langfuse provides powerful user and session tracking to help you:

  • Debug specific users: Find all traces for a particular user
  • Analyze conversations: View complete chat session threads
  • Monitor usage: Understand patterns by user and session
  • Attribute costs: Track spending per user

User Tracking

What is a User?

A User in Langfuse represents an end-user of your application. Each user is identified by a unique user_id that you provide in your code.

Setting User ID

from caip_agents_sdk.observability import observe, propagate_attributes

@observe(name="handle_request")
async def handle_request(user_id: str, message: str):
with propagate_attributes(user_id=user_id):
return await process_message(message)

User Identification Patterns

SourceExampleUse Case
JWT Tokenpayload.get("sub")Production APIs with authentication
API Keyrequest.headers["X-API-Key"]Service-to-service calls
Session Cookierequest.cookies["session_id"]Web applications
Anonymousf"anon_{uuid4()}"Unauthenticated users

Extracting User from JWT (Production Pattern)

import jwt
from fastapi import Header

def extract_user_from_token(authorization: str) -> dict:
"""Extract user from BMW WebEAM JWT token."""
if not authorization or not authorization.startswith("Bearer "):
return {"user_id": "anonymous", "name": None, "email": None}

token = authorization[7:]
payload = jwt.decode(token, options={"verify_signature": False})

return {
"user_id": payload.get("sub") or payload.get("qxid") or "unknown",
"name": payload.get("name"),
"email": payload.get("email")
}

@observe(name="api:chat")
async def chat_endpoint(
message: str,
authorization: str = Header(None)
):
user = extract_user_from_token(authorization)

with propagate_attributes(
user_id=user["user_id"],
metadata={"user_name": user.get("name")}
):
return await agent.run(message)

Users View in Langfuse

The Users view shows aggregated analytics for each user.

User View

User Metrics

MetricDescription
User IDUnique identifier you provided
TracesTotal number of traces from this user
SessionsNumber of distinct sessions
Total TokensSum of all token usage
Total CostAggregated spending
Last ActiveMost recent trace timestamp

User Cost Analytics

Langfuse provides detailed cost breakdowns per user, helping you understand usage patterns and identify high-cost users:

User Cost Analytics

Key insights from User Analytics:

  • Tokens by User: See which users consume the most tokens
  • Cost per User: Track spending attribution across your user base
  • Usage Trends: Identify power users vs occasional users
  • Cost Optimization: Find opportunities to reduce costs for high-usage users

User Analytics Use Cases

Use CaseHow
Debug user issuesFilter traces by User ID
Identify power usersSort by trace count or tokens
Cost attributionView spending per user
Usage patternsAnalyze activity over time
Billing analysisExport user costs for internal chargebacks

Session Tracking

What is a Session?

A Session groups related traces into a logical conversation or interaction. Sessions help you:

  • View complete conversations
  • Track multi-turn interactions
  • Analyze conversation flows
  • Debug conversation failures

Session View

Setting Session ID

from caip_agents_sdk.observability import observe, propagate_attributes

@observe(name="handle_message")
async def handle_message(user_id: str, session_id: str, message: str):
with propagate_attributes(
user_id=user_id,
session_id=session_id # Groups related traces
):
return await process_message(message)

Session ID Patterns

PatternExampleUse Case
Thread IDthread_abc123Chat applications with threads
Conversation IDconv_xyz789Multi-turn conversations
Request IDreq_123456Single request context
Browser Sessionsess_browser_idWeb session tracking

FastAPI Example with Session

from fastapi import FastAPI, Header
from caip_agents_sdk.observability import observe, propagate_attributes

app = FastAPI()

@app.post("/chat")
@observe(name="chat_endpoint")
async def chat(
message: str,
thread_id: str, # Session identifier
authorization: str = Header(None)
):
user = extract_user_from_token(authorization)

with propagate_attributes(
user_id=user["user_id"],
session_id=thread_id, # Use thread_id as session
tags=["chat-api"]
):
return await agent.run(message)

Sessions View in Langfuse

Sessions group related traces into conversation threads.

Session View

Session Overview

FieldDescription
Session IDIdentifier from propagate_attributes(session_id=...)
UserUser ID if set
Trace CountNumber of traces in the session
DurationTime span from first to last trace
Input TokensTotal input tokens across traces
Output TokensTotal output tokens across traces
Total CostAggregated cost across all traces
  1. Sessions List: Click "Sessions" in the left sidebar
  2. Session Detail: Click any session to see all traces
  3. Trace View: Click a trace to see detailed execution

Session Use Cases

Use CaseBenefit
Debug conversationsSee full context of a chat
Identify patternsFind where conversations fail
Conversation replayReview user interactions step-by-step
Cost analysisTrack spending per conversation

User ↔ Session ↔ Trace Relationships

Understanding the hierarchy:

User (user_id)
├── Session 1 (session_id)
│ ├── Trace 1 (request 1)
│ │ ├── Observation: validate_input
│ │ ├── Observation: retrieve_context
│ │ └── Observation: generate_response
│ ├── Trace 2 (request 2)
│ │ └── ...observations...
│ └── Trace 3 (request 3)
│ └── ...observations...

└── Session 2 (different conversation)
├── Trace 4
└── Trace 5

Querying Relationships

QueryFilter
"All traces for user X"Filter by user_id
"All traces in session Y"Filter by session_id
"All sessions for user X"Sessions view + user filter
"Average cost per user"Users view, sort by cost

Best Practices

User Tracking

Always Include User ID

Even for anonymous users, use a consistent anonymous identifier to track sessions:

user_id = user.id if user else f"anon_{session_cookie}"

Session Management

Consistent Session IDs

Use the same session_id across related requests to group them:

  • Chat applications: Use the thread/conversation ID
  • Web apps: Use a browser session cookie
  • APIs: Accept session_id as a parameter

Privacy Considerations

No PII in IDs

Use opaque identifiers, not emails or names:

# ✅ Good
user_id = "usr_abc123"

# ❌ Bad
user_id = "john.doe@bmw.com"

Next Steps