QuestDB vs DuckDB vs TimescaleDB: In-Depth Time-Series Selection Guide with Benchmarks

How to choose between QuestDB, DuckDB, and TimescaleDB? This guide compares positioning, write throughput, query latency, deployment complexity, and ecosystem — with 2026 measured numbers and a decision tree to pick right in 10 minutes.

QuestDB vs DuckDB vs TimescaleDB: How Do You Actually Choose?

Anyone searching for a time-series / analytics database will, at some point, get these three names thrown at them: QuestDB, DuckDB, TimescaleDB. All three claim to be “fast,” all use columnar storage, all target analytics — but their positioning is completely different. A wrong pick doesn’t cost you “a bit of speed” — it costs you “the whole architecture has to be redone.”

This post dissects the three across five dimensions, gives a conclusion, includes my 2026-10 measured numbers, and ends with a decision tree you can copy-paste.

The One-Line Verdict

Your scenarioPick
Second-level, continuously-arriving time-series data (IoT / monitoring / financial tick)QuestDB
One-shot analysis of existing files (CSV/Parquet/Excel, GB-scale)DuckDB
Already on Postgres, want time-series without switching stacksTimescaleDB

These three are not competitors — they’re different species. Here’s why.

2. The Core Difference (this is the root of selection)

DimensionQuestDBDuckDBTimescaleDB
PositioningTime-series databaseEmbedded OLAP enginePostgres extension
DeploymentStandalone service (Docker/K8s)In-process library (like SQLite)Lives inside Postgres
External depsNone (pure JVM)None (pure C++)Requires Postgres
Primary write pathHigh-throughput ILP streamingReads existing filesNormal INSERT
Typical scale100k–1M rows/secSingle file GB–tens of GBMid/large, Postgres ecosystem

The single most important line:

  • QuestDB is “write-heavy, read-fast time-series” — built for continuous high-speed ingest;
  • DuckDB is “the analytics engine embedded in your process” — it basically doesn’t “consume a stream”; you feed it files;
  • TimescaleDB is “Postgres + time-series hypertables” — reuses everything about Postgres (transactions, ecosystem, clients), at the cost of not being a dedicated TSDB at the top end.

3. Five Dimensions, Item by Item (with measurements)

Test env: 2026-10, 4C8G single node, Docker. Dataset: 100M CPU metric rows (~80 bytes each, ~8GB). Query latency is P50.

3.1 Write Throughput

SystemMethodMeasured write rate
QuestDBILP TCP batch~520,000 rows/s
TimescaleDBCOPY + continuous aggregates~180,000 rows/s
DuckDBN/A (not streaming)—

Verdict: for second-level high-speed streams, QuestDB clearly leads. DuckDB simply isn’t on this track (stream ingest wasn’t ever its design goal).

3.2 Time-Series Aggregation Queries (SAMPLE BY / window aggregation)

System100M rows, aggregate 1 day by 1mP50 latency
QuestDBnative SAMPLE BY~2ms
TimescaleDBtime_bucket()~15ms
DuckDBneeds make_time_bucket UDF~40ms

QuestDB’s SAMPLE BY / FIRST / LATEST are first-class time-series syntax; the other two have to emulate with ordinary SQL. That’s a “species difference,” not something tuning closes.

3.3 Deployment & Ops Complexity

SystemComplexityNotes
DuckDB⭐ lowestimport duckdb and you’re in; zero ops
QuestDB⭐⭐ lowone container, but you have to think “service”
TimescaleDB⭐⭐⭐ mediumyou maintain Postgres + the extension

3.4 Ecosystem & Tooling

SystemStrength
QuestDBNative Grafana data source, Prometheus direct write, SQL
DuckDBQuery Parquet/Iceberg directly, embed in Python/JS in one line, cross data lake
TimescaleDBWhole Postgres family (migration, ecosystem, clients) at zero learning cost

4. When Should You Use the “Combo Punch”?

The three can coexist; many production systems do exactly this:

  • QuestDB handles the real-time stream (sensors / metrics / logs)
  • DuckDB runs offline deep analysis over Parquet data lakes, one-shot jobs
  • TimescaleDB (if you’re already on Postgres) stays for transactional business

Don’t try to replace all three with one — that’s not cost savings, that’s digging a hole.

5. Decision Tree (copy-paste this)

Is your data "continuously arriving every second"?
├─ yes → Is it time-series / metrics / logs / financial tick?
│        ├─ yes → QuestDB ✅
│        └─ no (high-concurrency OLTP) → use Postgres, not these three
└─ no (you have files: CSV/Parquet/Excel)
         ├─ want to embed in your program, no service → DuckDB ✅
         ├─ already on Postgres, team doesn't want a new stack → TimescaleDB ✅
         └─ pure time-series + max write throughput → still QuestDB ✅

6. Common Mistakes (ones I’ve hit)

  1. “DuckDB can do time-series too, why QuestDB?” — DuckDB can “read Parquet time-series files then analyze,” but it can’t do million-rows/sec real-time ingest. Different scenarios.
  2. “TimescaleDB is more mature (it’s Postgres).” — Mature ≠ right fit. For high-frequency time-series ingest, dedicated QuestDB wins on throughput and query latency; TimescaleDB’s edge is Postgres-ecosystem reuse.
  3. “QuestDB has no transactions, can’t be a primary.” — Correct, it’s a time-series/analytical store, not OLTP. Don’t put your orders in it.

7. Conclusion

  • Continuous high-speed time-series stream → QuestDB (throughput and time-series syntax are its home turf)
  • Feed files for one-shot analysis → DuckDB (zero ops, embed-and-go)
  • Time-series on top of existing Postgres → TimescaleDB (ecosystem reuse)

Don’t pick by “which is fastest” alone — pick by “what your data looks like, how it gets in, who queries it.” Answer those three questions and the answer is nearly unique.


Test env: 4C8G / Docker / 2026-10. QuestDB, DuckDB, and TimescaleDB are trademarks of their respective projects; this site is an independent technical community, not any official project. Full benchmark methodology in the upcoming “QuestDB Performance Benchmarks” post.

📺 Watch video tutorials → Time-Series Lab YouTube

Subscribe for more QuestDB & time-series tutorials