Technology comparison
ClickHouse vs DuckDB
One workload, two architectures: a shared columnar server versus an in-process analytical engine, each with different locality, concurrency, and operational trade-offs.
Technical context and trade-offs
The same daily revenue aggregation can be answered by two very different architectures: ClickHouse runs as a networked columnar OLAP server that many clients query concurrently, while DuckDB is an embedded engine that runs inside your application process and reads local or object-storage data directly. The real decision is about deployment topology, data locality, and concurrency, not a blanket claim about which engine is faster.
Architecture and topology
ClickHouse: Runs as a client/server system with a persistent daemon that clients reach over the network, so compute is decoupled from the calling application.
DuckDB: Runs in-process as an embedded library with no separate server to deploy, so compute happens wherever your application executes.
Concurrency
ClickHouse: Designed for many concurrent readers and parallel query execution across a shared dataset.
DuckDB: Optimized for a single-process workload; concurrent access to the same database file from multiple processes is restricted and should be validated for your version and usage pattern.
Data locality
ClickHouse: Data lives in server-managed storage, which can be local disks or object storage depending on configuration and engine.
DuckDB: Queries read local files, in-memory data, or remote object storage directly, so data can stay next to the application without a load step.
Scaling model
ClickHouse: Can scale vertically and horizontally, including distributed and replicated cluster configurations.
DuckDB: Scales primarily with the resources of the host process; very large workloads depend on machine capacity and efficient file formats.
Operational cost drivers
ClickHouse: Ongoing cost is driven by server provisioning, storage, replication, and operational or managed-service overhead.
DuckDB: Cost is largely the compute and storage already used by the host application, with little dedicated database infrastructure.
Ingestion
ClickHouse: Supports high-volume batched ingestion and streaming integrations, with tables designed for append-heavy analytical loads.
DuckDB: Ingests from files and DataFrames efficiently; it is well suited to batch and file-based pipelines rather than as a multi-client ingestion service.
Quick verdict
Use ClickHouse if multiple services or users need concurrent access to a large, always-on dataset behind a network endpoint; use DuckDB if one process should analyze files or a local database with minimal infrastructure and no server to operate.
Scores by criterion
Scores reflect wins in matching criteria; ties count as half a point.
Technical feature matrix
| Criterion | ClickHouse | DuckDB | Edge |
|---|---|---|---|
| Performance for a bounded daily revenue aggregation | ClickHouse is a columnar OLAP engine built for scanning large fact tables and aggregating by date and dimension, and it parallelizes queries across cores and, in cluster setups, across nodes. Actual latency depends on table schema, partitioning, primary key and skip indexes, data compression, and available hardware, so results are workload-specific rather than universal. | DuckDB is also a columnar, vectorized analytical engine and executes GROUP BY aggregations over a date range efficiently, especially when data is in columnar formats such as Parquet or its own database file. Performance depends on file layout, row-group and zone-map pruning, available memory, and whether data is local or remote, so it should be evaluated against your specific dataset. | Comparable |
| Performance under concurrency and multi-user access | ClickHouse is architected for many simultaneous readers and parallel query execution against a shared dataset, and clustered deployments add distributed query processing. Concurrency still consumes server resources, so capacity planning and query limits matter for predictable behavior. | DuckDB is oriented toward a single-process analytical workload; patterns that open the same database file from multiple processes for concurrent writes are constrained, and the recommended approach is usually one writer with readers via the application. This is a design characteristic, not a defect, but it shapes multi-user architectures. | ClickHouse |
| Cost / pricing and licensing | ClickHouse is open source under Apache 2.0 for the core, and commercial managed offerings are available with their own pricing that changes over time. Total cost is driven by server or cluster provisioning, storage, replication, and operational effort, so it should be estimated from current vendor documentation for your region and plan. | DuckDB is open source under the MIT license with no server component, so licensing cost is typically zero and infrastructure cost reduces to the compute and storage your application already uses. At very large scale, the cost of the host machine and the engineering effort around file management become the relevant drivers. | DuckDB |
| Deployment / integration and operational effort | Deployment means running a server, configuring storage and users, and handling upgrades, backups, monitoring, and security, or delegating that to a managed service. Integration is broad because clients connect over standard network protocols and many language drivers and BI tools exist. | Deployment is a library dependency inside your application, with no daemon, ports, or cluster to operate, which simplifies local development, CI, and embedded analytics. Integration centers on language bindings and file or object-storage readers rather than a shared network service. | DuckDB |
| Ingestion and data freshness | ClickHouse supports high-throughput batch and streaming ingestion into MergeTree-family tables and is suited to continuously updated analytical datasets with scheduled or streaming loads. Freshness depends on how often you load and how you model tables, not on an automatic guarantee. | DuckDB reads and ingests files and DataFrames efficiently and can query remote object storage directly, which suits batch and file-based pipelines. Serving continuously updated data to many independent clients is not its primary model. | ClickHouse |
| Scaling and high availability | ClickHouse offers replication and distributed tables, allowing horizontal scaling and cluster-level fault tolerance when properly configured and operated. Those capabilities add operational complexity and should be validated against your topology and version. | DuckDB scales with the resources of the process that hosts it; it does not provide a built-in distributed cluster or replication service. Very large or highly available shared workloads generally require a different architecture. | ClickHouse |
| Ecosystem, SQL compatibility, and security model | ClickHouse exposes a SQL dialect with analytical extensions and a broad connector ecosystem, and it includes user management, access control, and encryption options whose specifics depend on version and edition. Security is a server concern that must be configured and maintained. | DuckDB supports a large subset of standard SQL with analytical features and integrates with common data formats and language ecosystems. As an embedded engine, access control largely inherits the host application's filesystem and process permissions rather than a network authentication layer. | Comparable |
Code examples
Calculate daily order revenue for a bounded date range: compare ClickHouse's distributed columnar query service with DuckDB's embedded analytical execution and parameter-binding model.
ClickHouse
import { createClient } from "@clickhouse/client";
type DailyRevenue = { day: string; revenue_cents: string };
const clickhouseUrl = process.env.CLICKHOUSE_URL;
if (!clickhouseUrl) throw new Error("CLICKHOUSE_URL is required");
const client = createClient({ url: clickhouseUrl });
export async function getDailyRevenue(start: Date, end: Date): Promise<DailyRevenue[]> {
if (start >= end) throw new RangeError("start must be earlier than end");
const result = await client.query({
query: "SELECT toDate(created_at) AS day, toString(sum(total_cents)) AS revenue_cents FROM orders WHERE created_at >= parseDateTimeBestEffort({start:String}) AND created_at < parseDateTimeBestEffort({end:String}) GROUP BY day ORDER BY day",
query_params: { start: start.toISOString(), end: end.toISOString() },
format: "JSONEachRow",
});
return result.json<DailyRevenue[]>();
}When to choose each option
Choose this option if… ClickHouse
Pick ClickHouse when the analytical workload is shared, long-running, and growing, and when concurrent users, replication, or a network API justify operating a server or paying for a managed service.
Choose this option if… DuckDB
Pick DuckDB when analytics are embedded in one application or notebook, data sits in files or object storage, and you want no server to manage and minimal infrastructure overhead.
Project fit calculator
Set your priority weights. Scores are based on the comparison evidence available on this page.
Based on your selected weights, we recommend: DuckDB
Option A
ClickHouse
- Databases
Option B
DuckDB
- Databases
This diagram shows broad areas of use, not a complete deployment architecture.
Frequently asked questions
How should I plan a migration from ClickHouse to DuckDB?
Inventory the ClickHouse features, data formats, and integrations you rely on, then verify their equivalents in DuckDB. Run a pilot with compatibility and performance tests, keep a rollback plan, and take a verified backup before switching production traffic.
Which option has lower total cost of ownership?
DuckDB typically has the lower infrastructure and licensing overhead because it is MIT-licensed and embedded, so cost is largely the compute and storage your application already uses. ClickHouse is Apache 2.0 at its core but adds server or cluster provisioning, storage, replication, and operational or managed-service costs. For large shared workloads, ClickHouse's efficiency and scaling options may offset that overhead, so estimate total cost from current vendor documentation and your own operational constraints.
How can I fairly benchmark ClickHouse against DuckDB?
The available criteria report: ClickHouse: ClickHouse is a columnar OLAP engine built for scanning large fact tables and aggregating by date and dimension, and it parallelizes queries across cores and, in cluster setups, across nodes. Actual latency depends on table schema, partitioning, primary key and skip indexes, data compression, and available hardware, so results are workload-specific rather than universal. DuckDB: DuckDB is also a columnar, vectorized analytical engine and executes GROUP BY aggregations over a date range efficiently, especially when data is in columnar formats such as Parquet or its own database file. Performance depends on file layout, row-group and zone-map pruning, available memory, and whether data is local or remote, so it should be evaluated against your specific dataset. Production results still depend on configuration and workload, so test both with representative data and measure latency and throughput before deciding.
Which tool should I use for a daily revenue aggregation over a bounded order-date range?
Both engines can compute this aggregation correctly and efficiently, so the deciding factors are how the data is stored and who queries it. Choose ClickHouse if many users or services need concurrent access to a shared, growing dataset behind a network endpoint. Choose DuckDB if a single application or notebook should aggregate files or a local database with minimal infrastructure. Benchmark on your own schema and hardware rather than assuming a universal winner.
Explore related stacks
Discover alternative tool pairings that share one technology with this comparison.
Related comparisons
- MySQL vs DuckDBCompare MySQL and DuckDB architectural trade-offs, data modeling, query patterns, and indexing, and review side-by-side TypeScript to choose the right stack.
- PostgreSQL vs DuckDBCompare PostgreSQL and DuckDB architectural trade-offs, data modeling, query patterns, and indexing, and review side-by-side TypeScript to choose the right stack.
- SQLite vs DuckDBCompare SQLite and DuckDB architectural trade-offs, data modeling, query patterns, and indexing, and review side-by-side TypeScript to choose the right stack.
- Astra DB vs PineconeCompare Astra DB and Pinecone architectural trade-offs, context windows, model APIs, and integration, and review side-by-side TypeScript to choose the right stack.
- Astra DB vs QdrantCompare Astra DB and Qdrant architectural trade-offs, context windows, model APIs, and integration, and review side-by-side TypeScript to choose the right stack.
- Apache Cassandra vs ScyllaDBCompare Apache Cassandra and ScyllaDB architectural trade-offs, data modeling, query patterns, and indexing, and review side-by-side TypeScript to choose the right stack.
- Chroma vs QdrantCompare Chroma and Qdrant architectural trade-offs, context windows, model APIs, and integration, and review side-by-side TypeScript to choose the right stack.
- Chroma vs WeaviateCompare Chroma and Weaviate architectural trade-offs, context windows, model APIs, and integration, and review side-by-side TypeScript to choose the right stack.