Skip to main content
Agno supports using ClickHouse as a database with the ClickhouseDb class.
ClickhouseDb is traces-only. It implements upsert_trace, create_spans, and the read paths for traces and spans. Sessions, memories, knowledge, evals, and component configs are not stored here. Pair it with a row-store (Postgres, MySQL, MongoDB) for that data.

Why ClickHouse only for traces

ClickHouse is an OLAP columnar engine. It is designed for the workload traces actually produce:
  • Append-heavy ingest. Spans arrive continuously. ClickHouse inserts coalesce into large columnar parts.
  • Time-bucketed aggregates. Trace dashboards group by minute, hour, day. Columnar storage scans only the columns the query touches.
  • Low-cardinality filters. Filtering by status or span_kind over billions of rows is what LowCardinality(String) is built for. Filtering by agent_id / session_id scans one narrow column instead of whole rows.
  • Cheap retention. PARTITION BY toYYYYMM(start_time) lets you drop a month of traces with one ALTER TABLE.
What ClickHouse is not built for: Session and memory storage hit all three of those patterns, which is why Agno uses a row-store for them and reserves ClickHouse for tracing.

Usage

Install the required packages:
clickhouse_for_traces.py
Always enable batch_processing=True with ClickHouse. The default SimpleSpanProcessor issues one insert per span and will hit the server’s parts_to_throw_insert limit under load. ClickHouse strongly prefers a smaller number of larger inserts.

Run ClickHouse

Install Docker Desktop and run ClickHouse on port 8123 (HTTP) and 9000 (native) using:
The command above is the minimum to get running. Traces don’t persist across container restarts. For a persistent local setup with mounted volumes, use the cookbook script cookbook/scripts/run_clickhouse.sh.

ClickHouse Cloud

Params

Developer Resources