ClickHouse vs Elasticsearch for Log Analytics

ClickHouse vs Elasticsearch for log analytics: columnar storage vs inverted indexes, aggregation speed, compression, and when each database is the right choice for logs.

JR3 min read

Elasticsearch and ClickHouse are two of the most common engines teams put behind log and event analytics. Elasticsearch, the heart of the ELK stack, was built for full-text search and became the default for log search and observability. ClickHouse was built from scratch as a columnar OLAP database for fast aggregations over huge datasets. They can both serve log analytics dashboards, but their architectures make very different trade-offs.

Data model and storage#

Elasticsearch is a document store built on Lucene. Every field of every document is indexed — including inverted indexes for text — which makes ad-hoc search over any field fast, but means heavy indexing work on every write and substantial storage overhead on top of the raw data.

ClickHouse stores data by column and builds only the sparse primary index and any secondary indexes you explicitly ask for. Writes are appends of column blocks — extremely cheap — and each column is compressed independently. Because log data is highly repetitive (the same log levels, service names, and status codes over and over), columnar compression ratios on logs are typically dramatic, and storage cost per terabyte of logs ends up far lower than an equivalent Elasticsearch cluster.

Aggregation performance#

Log analytics is mostly aggregations: error counts per minute, p99 latency per endpoint, request volume grouped by status code. This is exactly what ClickHouse's vectorized, columnar execution engine is designed for — it reads only the columns a query touches and processes them in tight loops over compressed data.

Elasticsearch can aggregate, but its engine is row-oriented at execution time and was designed around search, not scans. As a result, heavy aggregations over large time ranges generally run much faster on ClickHouse, and on a fraction of the hardware. This is why companies like Cloudflare and Uber moved large log-analytics workloads to ClickHouse.

This is Elasticsearch's home turf. Lucene's inverted index provides relevance-ranked search, fuzzy matching, wildcard queries, analyzers for different languages, and decades of tuning for the "find the needle in the log haystack" problem. Kibana's log exploration experience is mature and loved by on-call engineers.

ClickHouse has token bloom filter indexes and fast substring matching that cover a lot of "grep the logs" use cases surprisingly well, but it is not a relevance search engine. If interactive full-text search across massive free-text log volumes is the core workflow, Elasticsearch remains the stronger tool.

Operations and cost#

Elasticsearch clusters are notoriously demanding to operate: JVM heap tuning, shard management, index lifecycle policies, and careful capacity planning. The generous indexing that makes search fast makes ingestion expensive, so clusters are often sized by write throughput.

ClickHouse is a single binary with far fewer moving parts, and its cheap appends plus high compression mean significantly smaller clusters for the same log volume. For teams where logs are primarily an analytics input rather than a search corpus, the total cost difference is substantial.

Where each wins#

Choose Elasticsearch when relevance-ranked full-text search is the primary workflow, when you're invested in the ELK/OpenSearch ecosystem (Kibana, Logstash, Beats), or when log exploration for incident response matters more than analytical queries.

Choose ClickHouse when your logs are inputs to dashboards, metrics, and analytical queries; when retention and storage cost matter; and when you need fast aggregations over billions of rows without operating a large cluster.

How GraphJSON Uses ClickHouse#

GraphJSON stores the JSON events you send in ClickHouse. That lets a small team offer interactive dashboards, arbitrary SQL over event payloads, and long retention at low cost without operating the database itself. Events ordinarily become available for exploration as they arrive; GraphJSON’s service behavior page states the current freshness boundary without inventing a seconds-level guarantee.

JR

Written by JR

Founder and builder of GraphJSON.