Why StarRocks Is Better Than DuckDB for ETL and Data Transformation Pipelines
DuckDB has quietly become one of the most loved tools in the modern data stack, and nowhere more so than in transformation. The dbt-duckdb…
Why StarRocks Is Better Than DuckDB for ETL and Data Transformation Pipelines
DuckDB has quietly become one of the most loved tools in the modern data stack, and nowhere more so than in transformation. The dbt-duckdb adapter, the "Modern Data Stack in a Box," local ELT pipelines that run on a laptop, Airflow DAGs that spin up an in-process engine to crunch a few Parquet files — these patterns are everywhere in 2026, and for good reason. DuckDB gives you a real columnar SQL engine with zero infrastructure: pip install duckdb, point it at your files, and run transformations that would have needed a warehouse a few years ago. For a single developer transforming gigabytes of data, it is genuinely delightful.
So this post is not an argument that DuckDB is bad at transformation. It is an argument about where the transformation workload lives. ETL/ELT is rarely a one-person, one-run, one-machine activity in production. It is a continuously operating system: dozens of interdependent models, multiple pipelines running concurrently, data volumes that grow without asking permission, freshness commitments to downstream consumers, and an expectation that the whole thing keeps running unattended through failures. Measured against that reality, DuckDB’s defining design choice — an in-process, single-node, single-writer engine — stops being a feature and starts being a ceiling.
This post examines why StarRocks, an open-source distributed MPP analytical database, is the better foundation for production data transformation pipelines, drawing on its architecture, the practical limits practitioners hit with DuckDB-based ELT, and what teams who evaluated both actually concluded.

What a Production Transformation Pipeline Actually Demands
Before comparing engines, it helps to be precise about what “ETL/ELT pipelines” means once they leave the prototype stage:
- Transform-in-place at scale. The modern pattern is ELT: land raw data, then transform it where it sits using SQL. The engine must transform datasets that range from gigabytes to many terabytes — and the working set for a single join or aggregation can exceed any one machine’s memory.
- Many models, many dependencies. A real dbt project is a DAG of dozens or hundreds of models — staging, intermediate, marts — that build on each other. Builds need to parallelize across independent branches of that DAG.
- Concurrent pipelines and concurrent readers. Multiple pipelines (and multiple teams) run at once, and the tables they produce are queried by BI tools and applications while the next transformation run is writing the next version.
- Incremental, not full-rebuild. Reprocessing the entire history every run is wasteful and eventually impossible. Pipelines need incremental models and partition-level refresh so only changed data is recomputed.
- Freshness as a commitment. Downstream dashboards and data products have SLAs. A transformation pipeline that can’t finish inside its window — or that blocks readers while it runs — breaks those commitments.
- Unattended reliability. Pipelines run on schedules, at night, on weekends. They must survive a crashed step, a transient failure, or a node loss without a human restoring state from files.
- One governed copy of the truth. The transformed tables are shared assets. They need a serving layer, access control, and the ability to be queried directly — not exported and copied around.
DuckDB does the first half of #1 brilliantly. It is the rest of the list where an in-process engine has to be propped up with external machinery.
Where DuckDB Falls Short for Transformation Pipelines
None of the following is a knock on DuckDB’s engineering — the team is explicit that DuckDB is an in-process analytical database, the “SQLite for analytics.” The limits below are the direct, intended consequences of that design, and they show up precisely when transformation moves from a laptop to a production schedule.
The Single-Node Memory Ceiling
DuckDB runs inside one process on one machine. It has a competent out-of-core engine and will spill to disk for large joins and aggregations, but its performance envelope is fundamentally bounded by a single box’s RAM, cores, and local I/O. Practitioner guidance converges on the same shape: DuckDB is excellent up to roughly the low-terabyte range on a beefy node, and beyond that you are fighting spill thresholds, tuning memory_limit, and watching pipelines slow down or fail under memory pressure. When a transformation's intermediate result is larger than the machine, your only lever is a bigger machine — vertical scaling until there is no bigger instance to buy.
StarRocks is a distributed MPP engine: a transformation query is planned by the cost-based optimizer and executed in parallel across all backend nodes, with vectorized, SIMD-optimized operators and automatic spill-to-disk on each node. The working set is partitioned across the cluster, so a join or aggregation that would not fit on one machine simply fans out over many. When you need more transformation throughput, you add nodes — horizontal scaling — rather than hunting for a larger single server.
One Writer: Pipelines Wait in Line
DuckDB uses a single-writer concurrency model. Within a database, one process writes at a time and writes serialize. For a sequential dbt run this is fine, but production transformation is rarely sequential: you want independent branches of the model DAG building in parallel, multiple pipelines from multiple teams running on overlapping schedules, and readers querying yesterday’s marts while today’s run rebuilds them. On DuckDB, those writers contend for a single pen, and heavy concurrent reads and writes on the same file fight for the same cores and I/O.
StarRocks is a multi-user shared service. Many transformations — INSERT INTO, CREATE TABLE AS SELECT, materialized-view refreshes — run concurrently across the cluster, and resource groups let you partition CPU and memory so that, say, the nightly ELT batch cannot starve the ad-hoc analysts or the BI dashboards. Ingestion, transformation, and serving coexist instead of queuing behind one writer.
Incremental Transformation Is Yours to Build
In a DuckDB/dbt pipeline, “incremental” means you write incremental models by hand: you author the merge logic, manage the high-watermark or partition predicates, and make sure the model is idempotent on retries. It works, but the bookkeeping is application code you own and debug.
StarRocks makes incremental transformation a database feature through asynchronous materialized views. An async MV is a pre-computed, physically materialized transformation — multi-table joins and aggregations included — that can refresh on a schedule, on an interval, or automatically when base-table data changes, and crucially can refresh only the partitions that changed rather than rebuilding the whole result. On top of that, StarRocks does transparent query rewrite: queries against the base tables are automatically redirected to a matching materialized view when it can satisfy them, so the transformation accelerates queries without anyone rewriting SQL. Partitioned MVs even work over external Hive, Iceberg, and Paimon tables with partition-level incremental refresh. This is the transformation layer expressed declaratively and maintained by the engine, instead of hand-rolled incremental models maintained by you.
No Orchestration, No Recovery — That’s Your Job Too
DuckDB has no scheduler, no job manager, and no notion of a pipeline that survives a crash. If the process dies mid-transformation, the in-flight work is gone and recovery is your problem — restart the container, figure out what committed, replay from raw files. Every DuckDB ELT architecture therefore leans on an external stack (Airflow, dbt, cron, custom Python) to schedule, sequence, retry, and checkpoint. That surrounding machinery is real infrastructure you write and operate.
StarRocks ships much of this as database functionality. Materialized-view refresh schedules live in the database. Loads are transactional, so a failed INSERT or a crashed load doesn't leave a half-written table — it rolls back. Ingest-and-transform paths (Broker Load and the Pipe load method for large-scale and continuous file loading, Routine Load for Kafka, Stream Load for push, plus Flink/Spark connectors with two-phase commit) handle batching, retries, and exactly-once semantics inside the system. The pipeline's reliability is a property of the database, not an emergent property of a pile of cron jobs.
Fault Tolerance and the Shared Copy of the Truth
A DuckDB database is a file on one node with no replication and no high availability. Lose the node and you lose the working data until you rebuild it. And because DuckDB is a library inside a process — no network endpoint, no authentication, no RBAC — the tables it produces aren’t directly servable to many consumers. The standard pattern is to export DuckDB’s output to wherever it will actually be queried.
StarRocks is a fault-tolerant distributed service: data is replicated, nodes fail without taking the system down, and the transformed tables are immediately queryable by many concurrent users over the MySQL wire protocol with full RBAC and standard SQL. The output of transformation and the serving of transformation are the same system. In shared-data mode, storage lives in object storage and compute scales elastically on top of it, so you can size transformation compute independently and let it shrink when idle.
Why StarRocks Excels at Transformation Pipelines
Consolidating the architectural argument, here is what StarRocks brings that is purpose-built for production ELT:
Distributed, in-database transformation. INSERT INTO ... SELECT and CREATE TABLE AS SELECT execute as MPP jobs across the cluster, with a cost-based optimizer, vectorized execution, and high-performance multi-table joins — so you transform terabyte-scale data in place without flattening it first or exporting it to a bigger machine.
Asynchronous materialized views as a managed transformation layer. Multi-table, aggregating, incrementally refreshed by partition, schedulable, and eligible for transparent query rewrite — declarative transformations the engine keeps fresh, including over external lakehouse tables.
Concurrency with isolation. Many pipelines, many teams, and live readers coexist; resource groups keep the nightly batch from starving interactive workloads. No single-writer queue.
Scale-out instead of scale-up. Add nodes to add transformation throughput; spill-to-disk and partitioned execution handle working sets larger than any one machine’s memory.
Transactional, reliable loading. Pipe, Broker Load, Routine Load, Stream Load, and Flink/Spark connectors provide batching, retries, and exactly-once semantics so failed steps roll back cleanly instead of corrupting tables.
One governed, servable copy. Replicated, highly available, MySQL-protocol-compatible, RBAC-secured — the transformed data is a shared product, queryable directly rather than exported.
Open and standard. Apache 2.0 licensed and MySQL-compatible, so — like DuckDB — it avoids lock-in; unlike DuckDB, it does so as an always-on, multi-user service. And the two coexist well: StarRocks already participates in the same open-source ecosystem (dbt, Iceberg, Airflow) that DuckDB-based pipelines rely on.
What the Evidence Says
The pattern shows up repeatedly when teams evaluate both engines. A large US financial-technology platform, building a system that combines heavy transformation with real-time serving, assessed DuckDB alongside Druid, ClickHouse, and Pinot and found DuckDB’s “single-node architecture was an operational non-starter,” ultimately choosing StarRocks for multi-table join performance at scale, native upserts, and horizontal scaling — and reporting a 98% reduction in data aggregation time afterward. A major telecom operator, consolidating a data warehouse, ran a POC comparing StarRocks with DuckDB and SingleStore for exactly the “compression and performance at scale” requirements that single-node engines struggle to meet. The recurring division of labor, in our own customer conversations, is the one a prospect put plainly: DuckDB “solves a different problem… it’s an in-process database, single file, like SQLite — I should be able to export from StarRocks, put it into DuckDB, and have somebody manage it.” DuckDB as the personal/edge transformation tool; StarRocks as the shared transformation backbone.
When DuckDB Is Still the Right Choice
Honesty makes the comparison credible. DuckDB remains an excellent choice for transformation when:
- The data fits comfortably on one machine. For gigabytes to low terabytes, single-node DuckDB is fast, cheap, and operationally trivial — often faster end-to-end than a distributed system once you account for setup.
- It’s local or embedded ELT. A developer iterating on dbt models locally, a CI job transforming a fixture dataset, or an embedded pipeline inside an application — in-process is exactly right.
- The pipeline is single-user and batch. One owner, one schedule, no concurrent writers, no live serving from the same store.
- Prototyping transformation logic. Many teams (sensibly) prove out model logic in DuckDB before productionizing it on a distributed engine — and
dbt-duckdbmakes that path smooth.
The boundary is crisp: the moment transformation data outgrows a single machine, multiple pipelines and readers need to run at once, freshness becomes an SLA, or the pipeline must run unattended and survive failures, you have left DuckDB’s design envelope. Bolting orchestration, retry logic, incremental bookkeeping, read replicas, and ever-bigger instances onto an in-process library doesn’t change its nature — it means you are assembling a distributed transformation platform out of application code, one incident at a time.
Conclusion
DuckDB is a masterpiece of single-node analytical engineering, and the ELT patterns its community has built — dbt-duckdb, the modern stack in a box, local-first transformation — are genuinely excellent within their envelope. But production data transformation is a distributed, concurrent, always-on discipline: terabyte-scale transforms that exceed one machine's memory, parallel model DAGs and parallel pipelines, incremental refresh, freshness SLAs, unattended reliability, and a single governed copy that many consumers query directly. StarRocks was designed for that profile — distributed MPP execution, asynchronous materialized views, resource isolation, transactional loading, and high availability — and the teams who evaluated both, from a major fintech platform to a large telecom operator, kept arriving at the same fork.
Use DuckDB where it shines: local, embedded, single-node transformation and prototyping. When the pipelines multiply, the data outgrows the box, and the marts have to stay fresh for everyone, build transformation on StarRocks.
메타데이터
- post_id
- f86b5a53b6cc
- slug
- why-starrocks-is-better-than-duckdb-for-etl-and-data-transformation-pipelines-f86b5a53b6cc
- url
- https://medium.com/@indomitability/why-starrocks-is-better-than-duckdb-for-etl-and-data-transformation-pipelines-f86b5a53b6cc
- canonical_url
- https://medium.com/@indomitability/why-starrocks-is-better-than-duckdb-for-etl-and-data-transformation-pipelines-f86b5a53b6cc
- author_url
- https://medium.com/@indomitability
- status
- ok
- fetched_at
- 2026-06-15 22:55:51