ClickHouse Benchmarks

ClickHouse Against PostgreSQL and DuckDB on the Same Host

bench3.sh reruns DuckDB Extensions vs Postgres's six queries on the 1,379,440-row tables in all three engines: PostgreSQL 18.6 1,289 (psql \timing), DuckDB 1.5.5 61,228 (Python client) and ClickHouse 26.9 29,491 (clickhouse client --time, millisecond resolution). The SQL is identical except Q6, a mutation (ALTER TABLE ... UPDATE) in ClickHouse. Other lanes' jobs kept the load average at 3.4 to 8.4 on the four CPUs; this is one of three runs:

Running the three-engine benchmark
RUNS=5 bash scripts/bench3.sh
Output
load: 3.38 4.85 4.79; containers: l2-clickhouse l2-pg
query      pg_ms    duck_ms      ch_ms
Q1       469.88      16.46      50.00
Q2       684.86      48.86     129.00
Q3      2863.88     255.33      63.00
Q4       836.01     124.22     112.00
Q5         0.18       1.68       6.00
Q6         2.54       1.37     227.00

Over the three runs ClickHouse beat PostgreSQL 4.8-9.4x on Q1, 3.7-5.9x on Q2, 38-45x on Q3 and 4.0-7.5x on Q4. DuckDB, in-process with no client round trip, was 2.8-3.3x faster than ClickHouse on Q1 and 1.8-2.9x on Q2, about even on Q4, while ClickHouse's exact distinct count (Q3) beat DuckDB's 2.8-4.2x. ClickHouse lost the point lookup (5 to 14 ms), since order_id ends its key, and the update (0.2 to 0.5 s), since a mutation rewrites column files. A single-user benchmark also hides its strength, many concurrent queries over continuously arriving data. Use PostgreSQL for transactions, DuckDB inside a process or pipeline, and ClickHouse for a growing event table many users query.