Replacing an Impala cluster with DuckDB pods for a legacy analytics application - looking for architecture feedback
Looking for feedback from people who've worked with analytical databases (Impala, DuckDB, ClickHouse, Trino, etc.).
We have a legacy reporting application where users generate presentations. Opening a presentation triggers 50-100 SQL queries. The application is in maintenance mode with only one major paying customer, so our goal is to simplify the architecture, remove Cloudera licensing for Impala, and significantly reduce infrastructure costs.
Current Architecture
Presentation
|
20 Dataset Worker Pods
|
Impala Cluster
(10 different EC2 r5.4xlarge with 128GB ram each)
The dataset worker pods simply receive tasks from the application and submit SQL to Impala.
The Impala cluster consists of 10 x r5.4xlarge EC2 instances (16 vCPUs, 128 GB RAM each) managed through Cloudera.
Workload
The workload isn't typical OLAP.
Each presentation fires 50-100 queries.
Roughly:
- ~80% are tiny queries
- schema lookups
- small dimension table filters
- simple joins
- These usually return in 5-10 ms on Impala.
- Around 5-10% are heavier joins that take around 10 seconds.
- A presentation typically loads in 1-3 minutes depending upon type and filters
The total warehouse size is only around 300-350 GB.
Only 3-4 large tables account for roughly 200 GB. The remaining ~200 tables are tiny (KBs to MBs).
We want to Migrate away from Impala and not go for big commitment like dedicated EMR or something, we are ok with little delay but we dont want huge maintenance so we started with migrating to Athena from Impala.
Why Athena didn't work
Our first migration idea was Athena.
Large queries were acceptable, but the application performance became much worse because of the large number of tiny queries.
Queries that took 5-10 ms on Impala often became 200-800 ms on Athena.
Since every presentation executes 50-100 queries, that startup overhead adds up quickly.
Unfortunately, changing the application isn't really an option. The query generation is deeply embedded in legacy code, so batching or combining queries would require a major rewrite. Also many queries are sequential that adds up the time.
DuckDB Prototype
Instead of introducing another distributed SQL engine, I built a proof of concept using DuckDB.
Current architecture:
Presentation
|
20 Dataset Worker Pods
|
HTTP
|
---------------------------------
| DuckDB Pod 1 |
| DuckDB Pod 2 |
| DuckDB Pod 3 |
| DuckDB Pod 4 |
| DuckDB Pod 5 |
---------------------------------
Each DuckDB pod:
- has its own DuckDB
.dbfile - has its own dedicated EBS volume
- serves requests over HTTP
- operates completely independently (no distributed execution)
The dataset worker pods simply load balance requests across the DuckDB pods.
The workload is almost entirely read-only.
For the few workflows that create temporary tables, I'm considering running a separate DuckDB write service with its own EBS volume since those temp tables only exist for the lifetime of a request.
Results
So far the prototype performs better than Athena for presentation loading, but still not as fast as Impala.
That isn't too surprising since the existing Impala deployment is heavily provisioned (10 × 128 GB RAM nodes) for only ~300-350 GB of data.
For this application, we're willing to accept somewhat slower presentation loads if it significantly reduces operational complexity, infrastructure cost, and removes the Cloudera dependency.
One thing I'm also thinking about
Right now every DuckDB pod has its own copy of the .db file on its own EBS volume.
Would you keep this design, or would you use something like a high-throughput EFS shared across all DuckDB pods?
I ruled out reading directly from S3 because this workload is dominated by lots of tiny, latency-sensitive queries rather than long analytical scans, and the additional object storage latency seemed noticeable during testing.
Questions
- Has anyone replaced Impala with DuckDB for a similar workload?
- Am I overlooking any major architectural issues with multiple independent DuckDB replicas?
- Would you keep one
.dbfile per pod on dedicated EBS, or use shared storage like EFS? - Would you choose a different engine entirely (ClickHouse, Trino, StarRocks, etc.) for this workload?
- Any concurrency or operational issues you've run into serving DuckDB over HTTP in production?
I'm less interested in benchmark numbers and more interested in hearing from people who've operated similar systems in production