Distributed tracing generates a lot of data. A busy microservices system can produce millions of spans per minute. Where you store those spans determines both your observability costs and your query performance.
The default Jaeger backends, Elasticsearch and Cassandra, were chosen because they were widely deployed and well-understood. They are not optimal for trace storage.
Recent benchmarks from teams running Jaeger with ClickHouse as the storage backend show 8.6x compression ratios compared to Elasticsearch, with query performance that matches or exceeds it for the trace lookup and aggregation patterns that matter most for debugging.
Why ClickHouse Works Well for Traces
Traces have a specific data shape. Each trace has a trace ID and is composed of spans. Each span has a parent span, timestamps, service name, operation name, tags, and logs. You mostly query by trace ID, by service and time range, or by error status and time range.
ClickHouse is a columnar database optimized for analytical queries over time-series data. Span data stored in a columnar format compresses dramatically better than it does in a document store like Elasticsearch. The compression is not just storage savings; compressed columnar data reads faster because there is less I/O.
The query patterns for trace analysis map well to what ClickHouse does quickly. Finding all spans for a trace ID is a point lookup. Finding all traces for a service in a time range with error status is an analytical query that ClickHouse executes efficiently.
The jaeger-clickhouse Plugin
The jaeger-clickhouse plugin provides a ClickHouse storage backend for Jaeger without modifying Jaeger itself. The plugin implements the Jaeger storage plugin interface and handles schema management, ingestion, and queries.
The schema uses a primary spans table for raw data and a materialized view that aggregates by service and operation for the service map and dependency graph features. ClickHouse's materialized views update in real time as data is ingested.
Setup is straightforward if you already have ClickHouse running. The plugin configuration points Jaeger at your ClickHouse instance, and the schema is created automatically on first run.
What the Migration Actually Looks Like
If you are running Jaeger today with Elasticsearch, the migration has two phases. First, set up ClickHouse and configure Jaeger to write to both backends simultaneously. This dual-write period ensures you do not lose traces during the transition and gives you time to validate query behavior against ClickHouse before cutting over reads.
Second, after validating that trace queries return correct results from ClickHouse, flip the read path to ClickHouse and stop writes to Elasticsearch.
The main operational consideration is that ClickHouse has different operational characteristics than Elasticsearch. Replication, backup, and monitoring require ClickHouse-specific tooling and knowledge. If your team already runs Elasticsearch confidently, factor in the learning curve.
For new deployments, ClickHouse should be the default choice for Jaeger storage if you want to optimize for cost and performance. The ecosystem support is mature, and the operational tooling has improved significantly.