DuckDB vs ClickHouse: Embedded Analytics vs Distributed OLAP

DuckDB and ClickHouse are both columnar, vectorized OLAP engines, and both are genuinely fast. But they answer different questions. DuckDB asks: what if analytical SQL were a library you embed in your process, the way SQLite embedded transactional SQL? ClickHouse asks: what if a database server could sustain thousands of analytical queries per second over petabytes, with replication and horizontal scale? The overlap between the two is real but narrower than benchmark headlines suggest, and picking the wrong one usually means discovering a structural limit months in - not a performance problem you can tune away.

Architecture: In-Process vs Client-Server

DuckDB is an in-process database. There is no server, no port, no connection pool - you pip install duckdb or link the library, and queries execute inside your application's process, reading from a single database file or directly from Parquet, CSV, and JSON files on local disk or object storage. This design eliminates network round trips and serialization entirely, which is a large part of why DuckDB feels instant for local work. The engine uses vectorized execution over columnar data, spills to disk for larger-than-memory workloads, and ships as a single dependency with no configuration. The DuckDB concurrency model follows from the design: within one process, MVCC and optimistic concurrency allow multiple threads to read and write; across processes, either multiple readers attach read-only or a single process holds write access. Multi-process writers are explicitly not a design goal.

ClickHouse is a client-server system. Tables use the MergeTree engine, which writes immutable sorted parts and merges them in the background; a sparse primary index skips irrelevant granules, and vectorized SIMD execution processes columns in batches. Around that core sits everything a serving database needs: a network protocol handling thousands of concurrent connections, replication via ReplicatedMergeTree and ClickHouse Keeper, sharding with distributed tables, role-based access control, quotas, and TTL-based data lifecycle management. That machinery is overhead when you are one analyst querying one laptop, and it is the entire point when you are serving dashboards to ten thousand users.

The gap between the two models narrowed from ClickHouse's side with chDB, an in-process build of ClickHouse maintained by ClickHouse Inc. that you pip install and run embedded, querying files, DataFrames, and remote sources with full ClickHouse SQL. chDB is a credible answer to DuckDB for Python-centric local analytics, and it makes ClickHouse SQL portable from a notebook to a cluster. But DuckDB's embedded ecosystem is broader - client APIs across Python, R, Java, Node.js, Go, Rust, WASM in the browser - and the embedded use case is DuckDB's center of gravity rather than a satellite project.

Performance: Single Node vs Cluster

On a single node, DuckDB is now a top-tier performer and often the fastest option. On ClickBench, the benchmark ClickHouse itself maintains, DuckDB reached the #1 open-source spot in October 2025 on the strength of optimizations in its 1.4 LTS release. For scan-heavy aggregations over data that fits on one machine - tens to low hundreds of gigabytes, sometimes more with fast NVMe - there is no meaningful performance argument for standing up a ClickHouse server. The in-process design also means DuckDB wins decisively on time-to-first-query: no deployment, no schema migration, just point it at Parquet files.

The picture inverts as soon as any of three constraints appear. First, data volume: DuckDB is bounded by one machine's disk and memory, while ClickHouse shards and scales horizontally into the petabyte range - this is the workload ClickHouse was built for. Second, sustained ingestion: ClickHouse ingests millions of rows per second from Kafka or async inserts while serving reads, with new parts queryable immediately; DuckDB's single-writer model makes it a poor fit for continuous high-volume streams feeding live queries. Third, and most decisive in practice, concurrency.

Concurrency: The Real Dividing Line

A benchmark measures one query at a time. Production serving workloads do not look like that. ClickHouse is built to run hundreds or thousands of concurrent queries against shared tables - it is the engine behind user-facing analytics at Cloudflare, and the storage layer for observability platforms where every dashboard panel is a query. Concurrent inserts and reads proceed without locking, and replication lets you scale read throughput by adding replicas.

DuckDB has no comparable story, by design. One process owns write access to a database file; concurrent access from many application servers means either every server holds its own read-only copy, or you build coordination in application logic, or you move to a catalog-based format like DuckLake where a separate transactional catalog mediates writers. All of these are workarounds for using an embedded library where a server belongs. If your product has N users refreshing dashboards against shared, continuously updated data, DuckDB is the wrong layer to serve them from - even if a single DuckDB query on the same data would be faster.

Cost and the Managed Options

Self-hosted, both are free: DuckDB is MIT-licensed, ClickHouse is Apache 2.0. DuckDB's marginal cost is effectively zero - it runs on hardware you already have, including a CI runner or a Lambda function. Self-hosted ClickHouse costs whatever the cluster costs, plus real operational time for upgrades, schema design, and replication management.

The managed offerings diverge in model. MotherDuck, the commercial serverless service built on DuckDB, bills per-second for compute instances ranging from about $0.60 per hour (Pulse) to $24 per hour (Giga), with storage at $0.04/GB/month and a free tier; each query or user session runs on its own instance, which fits DuckDB's per-user isolation model and interactive, bursty usage. ClickHouse Cloud bills for provisioned compute at roughly $0.22 to $0.39 per compute unit per hour on the Scale tier, with storage around $25/TB/month - a model where an always-on cluster serves unlimited queries at flat marginal cost. For a data team running occasional interactive analysis, MotherDuck's pay-per-use is likely cheaper. For a high-QPS serving workload running 24/7, provisioned ClickHouse compute amortizes far better, and MotherDuck's per-instance model is not designed for that shape at all.

Ecosystem and Integration

DuckDB has become the default engine of the "small data" and composable-pipeline world: it reads and writes Parquet, Iceberg, and Delta, attaches to PostgreSQL and MySQL, runs inside dbt via dbt-duckdb, executes in the browser via WASM, and is the execution engine under a growing set of data tools. Its extension system (httpfs, spatial, full-text search, vector similarity) installs at runtime with one statement.

ClickHouse's ecosystem is server-shaped: first-class Kafka ingestion, native connectors for Grafana and BI tools over HTTP and MySQL/PostgreSQL wire compatibility, table functions for S3, Iceberg, and hundreds of formats, and a mature operational tooling story (backups, monitoring via system tables). ClickHouse can also query Parquet on object storage directly, so the "query files in place" overlap runs in both directions - but ClickHouse asks you to run a server to do it, where DuckDB asks nothing.

When to Choose Which

Dimension DuckDB ClickHouse
Deployment model In-process library, zero setup Client-server cluster (or Cloud)
Sweet-spot data size GBs to low hundreds of GBs per node Hundreds of GBs to petabytes
Concurrency Multi-thread in one process; single writer per file Thousands of concurrent queries, lock-free reads with writes
Streaming ingestion Batch-oriented; no continuous-serving story Kafka engine, async inserts, immediately queryable
Horizontal scale / HA None (single node by design) Sharding, replication, distributed queries
Embedded option Native (the whole product) chDB
Managed service MotherDuck (per-second, per-user instances) ClickHouse Cloud (provisioned compute)
License MIT Apache 2.0

Choose DuckDB when the workload is local or single-tenant: exploratory analysis, data science notebooks, ETL steps in a pipeline, querying Parquet lakes from a laptop or a serverless function, embedding analytics inside an application where each instance owns its data. In that territory DuckDB is faster to start, faster to run, and radically simpler - deploying ClickHouse there is overengineering.

Choose ClickHouse when the database is shared infrastructure: user-facing dashboards, multi-tenant SaaS analytics, observability and event pipelines with continuous ingestion, or any dataset that outgrows one machine. Concurrency, replication, and streaming ingestion are structural properties you cannot bolt onto an embedded library.

The honest bottom line: these tools are complements more often than competitors. A common and effective pattern is DuckDB (or chDB) for local development and pipeline transforms, with ClickHouse as the serving layer the results land in. The mistake to avoid is extrapolating from a single-node benchmark to a serving workload, in either direction.

Subscribe to the NeverBlink Newsletter

Get early access to new NeverBlink features, insightful blogs & exclusive events , webinars, and workshops.

We use cookies to provide an optimized user experience and understand our traffic. To learn more, read our use of cookies; otherwise, please choose 'Accept Cookies' to continue using our website.