Basic Setup
Configure and enable tracing for your Agno agents
This guide walks you through setting up tracing for your Agno agents. Tracing is designed to be simple: install dependencies, enable tracing, and all your agents are automatically instrumented.
Installation
Install the required packages:
uv pip install -U "agno[os]" openai opentelemetry-api opentelemetry-sdk openinference-instrumentation-agnoThe OpenTelemetry packages provide the instrumentation infrastructure and the Agno-specific instrumentation logic. agno[os] covers the database and AgentOS dependencies used in the examples below.
Set OpenAI Key
Set your OPENAI_API_KEY as an environment variable. You can get one from OpenAI.
export OPENAI_API_KEY=sk-***Configure tracing once per process, before running agents, teams, or workflows. If a real global OpenTelemetry TracerProvider already exists, setup_tracing() returns without adding an exporter or instrumenting Agno. A second call does not change the database or processing settings. When another integration owns the provider, configure its exporters and AgnoInstrumentor directly.
Two Ways to Enable Tracing
There are two ways to enable tracing in Agno:
-
setup_tracing()- Use this function for standalone scripts, notebooks, and custom applications. Provides full control over configuration options like batch processing, queue sizes, and export delays. -
AgentOS
tracing=True- Use this parameter when deploying agents through AgentOS. Simpler setup for production deployments with sensible defaults.
Option 1: Using tracing with SDK
For standalone scripts, notebooks, or custom applications use setup_tracing():
from agno.agent import Agent
from agno.db.sqlite import SqliteDb
from agno.models.openai import OpenAIResponses
from agno.tracing import setup_tracing
# Set up your tracing database
db = SqliteDb(db_file="tmp/traces.db")
# Enable tracing (call this ONCE at startup)
setup_tracing(db=db)
# Create and run agents - they're automatically traced!
agent = Agent(
name="Research Agent",
model=OpenAIResponses(id="gpt-5.2"),
instructions="You are a research assistant",
)
response = agent.run("What is quantum computing?")Call setup_tracing() before running your agents so instrumentation is active during execution.
Option 2: Using tracing with AgentOS
When deploying agents with AgentOS, you can enable tracing with a simple parameter:
from agno.agent import Agent
from agno.os import AgentOS
from agno.db.sqlite import SqliteDb
my_agent = Agent(name="Assistant")
db = SqliteDb(db_file="tmp/traces.db")
agent_os = AgentOS(
agents=[my_agent],
tracing=True, # Enable tracing
db=db,
)You can also use setup_tracing() to configure tracing for AgentOS but make sure to pass the db to AgentOS so traces are accessible through the AgentOS API and UI.
from agno.agent import Agent
from agno.db.sqlite import SqliteDb
from agno.os import AgentOS
from agno.tracing import setup_tracing
my_agent = Agent(name="Assistant")
db = SqliteDb(db_file="tmp/traces.db")
setup_tracing(db=db)
agent_os = AgentOS(
agents=[my_agent],
db=db,
)An explicit AgentOS db makes this trace destination available to the API. Without one, tracing=True uses the first available database from registered agents, then teams, then workflows. A database used only by a separate setup_tracing() call must also be registered with AgentOS for API access.
For detailed AgentOS tracing configuration including multi-database setups, see Tracing in AgentOS.
Dedicated Traces Database
Recommended: Use a separate database for storing traces, especially when you have multiple agents or teams with their own databases.
When agents and teams each have their own databases for sessions and memory, traces should go to a dedicated central database. This ensures:
- Unified observability: All traces in one place for cross-agent analysis
- Simpler querying: No need to search multiple databases
- Independent scaling: Traces can grow independently from agent data
- Cleaner separation: Agent data and observability data don't mix
from agno.agent import Agent
from agno.db.sqlite import SqliteDb
from agno.models.openai import OpenAIResponses
from agno.tracing import setup_tracing
from agno.tools.hackernews import HackerNewsTools
# Each agent has its own database for sessions/memory
agent1_db = SqliteDb(db_file="tmp/agent1.db", id="agent1_db")
agent2_db = SqliteDb(db_file="tmp/agent2.db", id="agent2_db")
# Dedicated database for ALL traces (separate from agent databases)
db = SqliteDb(db_file="tmp/traces.db", id="traces_db")
# Use simple processing because this example queries traces immediately
setup_tracing(db=db, batch_processing=False)
# Agent 1: HackerNews specialist with its own database
hackernews_agent = Agent(
name="HackerNews Agent",
model=OpenAIResponses(id="gpt-5.2"),
tools=[HackerNewsTools()],
instructions="You are a hacker news agent. Answer questions concisely.",
markdown=True,
db=agent1_db, # Agent's own database
)
# Agent 2: Research specialist with its own database
research_agent = Agent(
name="Research Agent",
model=OpenAIResponses(id="gpt-5.2"),
tools=[HackerNewsTools()],
instructions="You are a research agent. Answer questions concisely.",
markdown=True,
db=agent2_db, # Agent's own database
)
# Both agents are traced to the same db
hackernews_agent.run("What's trending on HackerNews?")
research_agent.run("Latest AI news on HackerNews")
# Query traces for both agents from one place
traces, count = db.get_traces(limit=20)
print(f"Found {count} traces across all agents")Once configured, traces and spans are automatically stored in your database. The tracing system creates two tables: agno_traces for high-level trace information and agno_spans for individual span details.
Use ClickHouse for high-volume tracing. Traces are an append-heavy, OLAP workload: billions of rows, time-bucketed aggregates, low-cardinality filters. ClickHouse is purpose-built for that shape. Pair it with a row-store for sessions and memory. This example uses SQLite.
uv pip install -U clickhouse-connectRun a ClickHouse service at the host and port below, with the configured user and database permissions, before starting this application.
from agno.agent import Agent
from agno.db.clickhouse import ClickhouseDb
from agno.db.sqlite import SqliteDb
from agno.os import AgentOS
from agno.tracing import setup_tracing
primary_db = SqliteDb(
id="clickhouse-primary",
db_file="tmp/clickhouse_primary.db",
)
my_agent = Agent(db=primary_db)
traces_db = ClickhouseDb(
id="clickhouse-traces",
host="localhost",
port=8123,
username="ai",
password="ai",
database="agno_traces",
)
setup_tracing(db=traces_db, batch_processing=True)
agent_os = AgentOS(
agents=[my_agent],
db=traces_db, # AgentOS reads traces from this db
)
app = agent_os.get_app()
if __name__ == "__main__":
"""Run your AgentOS.
"""
agent_os.serve(app="clickhouse_tracing:app", reload=True)
AgentOS discovers both database IDs. Pass db_id=clickhouse-traces to /traces and /traces/{trace_id} so the API reads from ClickHouse.
ClickhouseDb is traces-only. Sessions, memories, and component configs are intentionally not supported there. See the ClickHouse provider page for the full rationale and schema details.

Each span record includes the trace_id to group related operations, parent_span_id for hierarchy, and the operation name (e.g., Stock_Price_Agent.run, OpenAIChat.invoke, get_current_stock_price).
Processing Modes
Agno supports two trace processing modes:
Batch Processing
Batch processing collects spans in memory and writes them in batches. This is more efficient and recommended for production:
setup_tracing(
db=db,
batch_processing=True,
max_queue_size=2048, # Max spans in memory
max_export_batch_size=512, # Spans per batch write
schedule_delay_millis=5000, # Export every 5 seconds
)Pros:
- Lower database load
- Better performance
- Minimal impact on agent execution
Cons:
- Slight delay before traces appear (default 5 seconds)
- Spans in memory if the application crashes before export
Simple Processing (Default)
Simple processing writes each span immediately:
setup_tracing(
db=db,
batch_processing=False
)Pros:
- Traces appear immediately
- No memory buffering
Cons:
- More database writes
- Slight performance overhead
Use batch processing in production and simple processing for development/debugging when you need immediate trace visibility.