Architectural shapes

ClickHouse single binary per node SQL → MergeTree parts per partition raw rows; aggregate at read Keeper for replication Apache Druid Broker Coord. Historical MiddleM. deep storage (S3/HDFS) rollup at ingest; segments ZooKeeper + metadata DB

Druid is N services (Broker, Coordinator, Historical, MiddleManager, Overlord, Router) plus deep storage and a metadata DB. ClickHouse is one process plus Keeper.

Side by side

ClickHouseDruid
Process model1 binary5+ services
Storage unitParts within partitionsTime-bucketed segments
AggregationLazy, query-time SQLRollup at ingestion (often)
SchemaSQL typesDimensions + metrics + time
SQLFullDruid SQL (subset, planner-translated)
JoinsHash / merge / directBroadcast lookup only
UpdatesMutations + ReplacingMergeTreeRe-ingest segments
Ingest pathHTTP/native INSERTIndexer task (Kafka → segment)
Failure modelPer-node, replicasSegments live in deep storage

Rollup vs raw rows

Druid's defining feature is rollup: at ingestion time, rows with the same dimensions and time-bucket are pre-aggregated into a single row with summed metrics. A 1B-event raw stream might land as 100M rolled-up rows. This is what makes Druid fast on classic dashboard queries — most of the work is already done.

ClickHouse stores raw rows by default. To get the same effect you build a MaterializedView writing into an AggregatingMergeTree with sumState/uniqState. The result is the same — pre-aggregated tiers — but you control when and how aggregation happens, and the raw rows remain queryable.

-- ClickHouse equivalent of Druid rollup
CREATE MATERIALIZED VIEW events_5m TO events_5m_agg AS
SELECT
    toStartOfFiveMinutes(ts) AS window,
    event,
    sumState(toUInt64(1)) AS hits
FROM events
GROUP BY window, event;

Real-time ingestion path

Druid's archetype is "Kafka → MiddleManager (indexing task) → segment → handoff to Historical → query." The path involves the Coordinator scheduling segments onto Historical nodes after a configurable delay (segment_granularity, ~10 minutes). Recent data lives on MiddleManagers (slow) until handoff.

ClickHouse INSERTs land as parts in seconds and are queryable immediately. The Kafka engine (ENGINE = Kafka) plus a materialized view gives you the same "consume topic, aggregate, store" pipeline in pure SQL with no external indexer.

Query latency

For pre-aggregated dashboard queries (group by dimensions, time-bucket, single time range), Druid's segment layout is microsecond-fast. For queries shaped differently — joins, sub-queries, ad-hoc filters on un-rolled dimensions — Druid is uncomfortable; SQL is translated into a more limited native API.

ClickHouse is more uniform. Latency depends on partition pruning, primary-key alignment, and codec choice, not on whether the query "looks like" a Druid topology.

Operations

Druid: 5+ JVM services per cluster, deep storage (S3/HDFS), metadata DB (Postgres/MySQL), ZooKeeper. Tuning means understanding which service does what and how segment handoff works.

ClickHouse: one binary per node, plus Keeper for replication. Tuning means knowing MergeTree settings, codec choice, and partition strategy.

Schema model

Druid splits columns into three categories: timestamp (mandatory), dimensions (group-by columns), and metrics (aggregated values). Schema is set at ingestion and roll-up is irreversible; if you drop a dimension, the rolled-up data merges across that dimension and the original detail is gone.

ClickHouse uses ordinary SQL types. Any column can be filtered, grouped, or aggregated; raw rows remain intact. The flexibility cost: you set storage policy explicitly via ORDER BY, codecs, and materialized views, where Druid's segment design "decides" for you.

-- Druid spec (excerpt, JSON)
{
  "dimensionsSpec": { "dimensions": ["service", "region"] },
  "metricsSpec":    [{"type":"longSum","name":"hits","fieldName":"count"}],
  "granularitySpec": {"queryGranularity":"MINUTE","rollup":true}
}

-- ClickHouse equivalent
ENGINE = AggregatingMergeTree
ORDER BY (service, region, toStartOfMinute(ts))

Tradeoffs

  • + ClickHouse: simpler ops, full SQL, raw rows queryable.
  • + Druid: pre-rolled-up data is microsecond fast for matching queries.
  • + Druid: deep-storage isolation makes individual-node failure cheap.
  • ClickHouse: rollup is opt-in via MVs; you assemble it.
  • Druid: limited joins, no full SQL, multi-service operational model.
  • Druid: ingestion handoff delay means recent rows are slower.

Failure model

Druid's deep storage isolates the durability question: even if every Historical node loses its disk, the segments are still in S3/HDFS and can be re-served by any other node. The Coordinator handles re-balancing automatically. The cost: every query reads from local cache backed by deep storage; cold reads can be slow.

ClickHouse stores parts on local disks of replicas (or S3 with the new disk type). Replication via Keeper provides redundancy within a shard; loss of all replicas of a shard is data loss. With S3-backed storage (24+) the durability story converges with Druid's, at the cost of higher read latency.

For "lose a node, lose nothing, query continues unaffected," Druid's design has a clean answer. For "low-latency reads, simpler ops, manageable durability via replicas," ClickHouse's wins.

FAQ

Which is faster for dashboards?

If your query is a "group by dimensions over time", Druid wins on pre-rolled-up data. ClickHouse with an AggregatingMergeTree MV reaches the same speed but requires you to build the rollup.

Can Druid do joins?

Only "lookup" joins (broadcast small dimension tables). General hash joins are not supported. ClickHouse joins everything, with the caveats covered in the JOINs page.

What about updates?

Druid replaces full segments — all-or-nothing per time bucket. ClickHouse has lightweight DELETE and ReplacingMergeTree for fine-grained updates.

Should I migrate from Druid?

If your query mix has grown beyond classic OLAP cubes (joins, ad-hoc, complex SQL), ClickHouse fits better. If you're pure-cube and happy with Druid's ops cost, stay.

What about Apache Pinot?

Pinot is closer to Druid in spirit — segments, deep storage, multi-service. It has better SQL than Druid but the same "classic OLAP" archetype.