Track Users & Sessions
Tracking users and sessions in your GenAI application provides essential context for understanding user behavior, analyzing conversation flows, and improving personalization. MLflow offers built-in support for associating traces with users and grouping them into sessions.
Why Track Users and Sessions?
User and session tracking enables powerful analytics and improvements for your GenAI application. Understanding how different users interact with your application helps identify usage patterns across your user base, while analyzing multi-turn conversations reveals how well your system maintains context retention across interactions.
This tracking capability allows you to monitor performance metrics across different user segments, identifying areas for targeted improvements. You can also maintain session continuity across multiple interactions within the same conversation, creating better user experiences through improved context awareness.
Standard MLflow metadata fields
User and session tracking is only available in MLflow 3 and above. To upgrade, please run pip install --upgrade mlflow
MLflow provides two standard metadata fields for session and user tracking:
mlflow.trace.user
- Associates traces with specific usersmlflow.trace.session
- Groups traces belonging to multi-turn conversations
When you use these standard metadata fields, MLflow automatically enables filtering and grouping in the UI. Unlike tags, metadata cannot be updated once the trace is logged, making it ideal for immutable identifiers like user and session IDs.
Implementation Examples
- Basic Usage
- Web Application
Here's how to add user and session tracking to your application:
import mlflow
@mlflow.trace
def chat_completion(user_id: str, session_id: str, message: str):
"""Process a chat message with user and session tracking."""
# Add user and session context to the current trace
mlflow.update_current_trace(
metadata={
"mlflow.trace.user": user_id, # Links trace to specific user
"mlflow.trace.session": session_id, # Groups trace with conversation
}
)
# Your chat logic here
response = generate_response(message)
return response
# Example usage
def handle_user_message(request):
return chat_completion(
user_id=request.user_id, # e.g., "user-123"
session_id=request.session_id, # e.g., "session-abc-456"
message=request.message,
)
Key Implementation Notes:
- The
@mlflow.trace
decorator automatically creates a trace for function execution mlflow.update_current_trace()
adds the user ID and session ID to the active trace- Use consistent ID formats across your application for reliable analysis
In production web applications, extract user and session information from request headers:
import mlflow
import os
from fastapi import FastAPI, Request
from pydantic import BaseModel
app = FastAPI()
class ChatRequest(BaseModel):
message: str
@app.post("/chat") # FastAPI decorator should be outermost
@mlflow.trace # Ensure @mlflow.trace is the inner decorator
def handle_chat(request: Request, chat_request: ChatRequest):
# Extract context from headers
session_id = request.headers.get("X-Session-ID")
user_id = request.headers.get("X-User-ID")
# Update trace with user and session context
mlflow.update_current_trace(
metadata={
"mlflow.trace.session": session_id,
"mlflow.trace.user": user_id,
}
)
# Process the chat message
response_text = process_chat_message(chat_request.message, user_id, session_id)
return {"response": response_text}
Example request:
curl -X POST "http://127.0.0.1:8000/chat" \
-H "Content-Type: application/json" \
-H "X-Session-ID: session-def-456" \
-H "X-User-ID: user-jane-doe-12345" \
-d '{"message": "What is my account balance?"}'
Querying and Analysis
- MLflow UI Search
- User Analysis
- Session Analysis
Filter traces in the MLflow UI using these search queries:
# Find all traces for a specific user
metadata.`mlflow.trace.user` = 'user-123'
# Find all traces in a session
metadata.`mlflow.trace.session` = 'session-abc-456'
# Find traces for a user within a specific session
metadata.`mlflow.trace.user` = 'user-123' AND metadata.`mlflow.trace.session` = 'session-abc-456'
The MLflow UI provides powerful filtering and grouping capabilities when you use the standard user and session metadata.
Analyze user behavior patterns programmatically:
import mlflow
def analyze_user_behavior(user_id: str, experiment_id: str):
"""Analyze a specific user's interaction patterns."""
# Search for all traces from a specific user
user_traces = mlflow.search_traces(
experiment_ids=[experiment_id],
filter_string=f"metadata.`mlflow.trace.user` = '{user_id}'",
return_type="list",
)
if len(user_traces) == 0:
return {"error": "No traces found for user"}
# Calculate key metrics
total_interactions = len(user_traces)
unique_sessions = len(
set(
t.info.request_metadata.get("mlflow.trace.session", "") for t in user_traces
)
)
successful_traces = [trace for trace in user_traces if trace.info.state == "OK"]
avg_response_time = (
sum(trace.info.execution_time_ms for trace in successful_traces)
/ len(successful_traces)
if successful_traces
else 0
)
return {
"user_id": user_id,
"total_interactions": total_interactions,
"unique_sessions": unique_sessions,
"avg_response_time_ms": avg_response_time,
}
# Usage
user_stats = analyze_user_behavior("user-123", "1")
print(
f"User has {user_stats['total_interactions']} interactions across {user_stats['unique_sessions']} sessions"
)
Analyze conversation flow within sessions:
def analyze_session_flow(session_id: str, experiment_id: str):
"""Analyze conversation flow within a session."""
# Get all traces from a session, ordered chronologically
session_traces = mlflow.search_traces(
experiment_ids=[experiment_id],
filter_string=f"metadata.`mlflow.trace.session` = '{session_id}'",
order_by=["timestamp_ms ASC"],
return_type="list",
)
if len(session_traces) == 0:
return {"error": "No traces found for session"}
# Build conversation timeline
conversation_turns = []
for i, trace in enumerate(session_traces):
conversation_turns.append(
{
"turn": i + 1,
"timestamp": trace.info.timestamp_ms,
"duration_ms": trace.info.execution_time_ms,
"status": trace.info.status,
}
)
# Session-level metrics
session_duration = max(trace.info.timestamp_ms for trace in session_traces) - min(
trace.info.timestamp_ms for trace in session_traces
)
total_turns = len(conversation_turns)
avg_turn_duration = (
sum(trace.info.execution_time_ms for trace in session_traces) / total_turns
)
return {
"session_id": session_id,
"total_turns": total_turns,
"session_duration_ms": session_duration,
"avg_turn_duration_ms": avg_turn_duration,
"conversation_flow": conversation_turns,
}
# Usage
session_analysis = analyze_session_flow(session_id, exp.experiment_id)
print(
f"Session had {session_analysis['total_turns']} turns over {session_analysis['session_duration_ms']}ms"
)
Best Practices and Integration
Implementation Guidelines
Successful user and session tracking requires consistent ID formats across your application to ensure reliable analysis and filtering. Define clear rules for when sessions start and end, such as after periods of inactivity or when users explicitly end conversations. Consider adding metadata enrichment with additional context like user segments or session types to enhance analysis capabilities. Combining user and session data with request IDs provides complete traceability across your system.
Integration with MLflow Features
User and session tracking enhances other MLflow capabilities significantly. You can use user and session filters in trace search for targeted analysis and debugging. Quality evaluation becomes more powerful when comparing metrics across different user segments to identify improvement opportunities. Environment tracking combines well with user context for comprehensive observability, while production monitoring enables tracking performance patterns by user cohorts in live environments.
Summary
User and session tracking with MLflow provides powerful capabilities for understanding user behavior and optimizing user experiences. This approach delivers enhanced analytics through deep insights into user behavior patterns and session dynamics across your application. It improves debugging by providing user and session context that helps identify and resolve user-specific issues more quickly.
Quality monitoring becomes more targeted when you can track performance across different user segments, enabling focused improvements where they matter most. Conversation analysis through multi-turn conversation tracking helps optimize dialogue systems and user flows for better engagement.
The combination of standard MLflow metadata (mlflow.trace.user
and mlflow.trace.session
) with custom context creates a comprehensive foundation for user-centric observability in GenAI applications.
Next Steps
Track Environments & Context: Add deployment and version context to your traces
Search Traces: Master advanced filtering techniques for user and session analysis
Quality Analysis: Use user and session data to improve application quality
Production Monitoring: Set up comprehensive production observability with user context