Blog /
DuckDB vs Postgres for the Question You Have Today
Harsh Vardhan Goswami

On this page
Postgres and DuckDB keep getting compared as if one should win. They are optimized for different questions. The startup failure is running yesterday’s OLTP schema as tomorrow’s warehouse or copying the app database into a new engine because a newsletter said every agent gets an embedded DuckDB.
Leave with a table you can use on the next slow query, and a rule for agents: scratch engines expire; systems of record do not.
Decision table (start here, not with a migration)
| If the work is… | Start with | Why | Common mistake |
|---|---|---|---|
| Concurrent writes, constraints, roles, backups | Postgres | System of record. You already operate it | “Analytical Postgres” as an excuse to skip indexes |
| Point lookups, small indexed filters | Postgres | Indexes exist. Do not scan | DuckDB on a live primary for WHERE id = |
| Wide scans, Parquet/CSV, “join these files” | DuckDB or similar | Columnar engine; files as tables | Loading Snowflake for a one-off CSV join |
| Mixed: live operational data + a heavy report | Postgres replica or extract, then analytical engine | Do not punish OLTP with a dashboard scan | Same instance, “just this once,” forever |
| Text search | Depends on workload | See Postgres vs DuckDB FTS vs external | One engine ideology |
DuckDB’s 2026 trajectory—async I/O for object stores, more connectivity, agent-shaped embedding—is real. It still does not replace your primary’s transaction semantics, point-in-time recovery, or the role system you already taught the company.
Postgres is a process: WAL, roles, extensions you already fear, backups you already test. DuckDB is a library that became a server-shaped citizen. Mixing the metaphors is how people put DuckDB in front of live checkouts or put Postgres on a 200-column scan with no indexes and then blog that “Postgres cannot do analytics.” Postgres can do a lot of analytics. It cannot do “we never looked at the plan.”
Extensions such as embedding DuckDB inside Postgres exist for a reason: keep the record where it is, accelerate the scan where it hurts. That is a hybrid, not a conversion. Conversion is what you do when you are tired of thinking.
Worked path: the dashboard that “needs a warehouse”
Symptom: a daily revenue chart takes 40 seconds and stutters checkouts.
Wrong move: announce a lakehouse, or move the app DB to an analytical engine “so we can be modern.”
Right move, in order:
- Capture the SQL. If you cannot, you do not have a dashboard problem. You have a visibility problem.
EXPLAINon Postgres. Missing index on(created_at)plusSELECT *is still the modal cause.- If the query is a real scan of facts the primary should not serve, replicate or extract that slice. Materialized view or nightly table. Then chart that.
- If the work is joining files (exports, Parquet dumps), DuckDB locally or in a notebook is often the fastest honest path.
- If the scan is recurring and large, then you have a warehouse conversation. Recurrence is what justifies warehouse cost, not the first slow query.
Teams skip 1–3 because 4 and 5 are more interesting at dinner. Production prefers boring.
What agents change (and what they must not)
Agents emit lots of analytical SQL. An embedded engine next to the agent can make retries cheap. That is a sandboxing idea: temp schema, expiration, no path to prod DDL.
It is not an argument for a second source of truth. The agent’s DuckDB that “has yesterday’s orders” will diverge. Someone will ship a number from it. Finance will reconcile against Postgres. You will spend a week on whose clock was right.
Keep:
- Record in Postgres (or whatever OLTP you run).
- Explore in a replica, a snapshot, or a file-backed analytical engine.
- Publish from a reviewed query, not from the agent’s scratch database.
“Every agent gets a database” is useful the way scratch disks are useful. Treat it like a temp schema with an expiration.
Practical moves that are not a religion
- Slow dashboard: plan and indexes before shopping engines.
- One-off join of exports: DuckDB or a Quantum Lab Python/pandas step on a reduced extract. Do not load a cloud warehouse “for a week.”
- Recurring heavy scans: schedule an extract. Recurrence is the tell.
- Agents: read-only role on the explore connection; never DDL on the record.
Product shape
Quantum Lab runs SQL against the connection you select and Python on the frame you already fetched. That split is “engine of record vs engine of exploration” without making you pick a mascot. Kole should query the connection you trust for the question, not invent a second warehouse because the model prefers it.
You can run this whole article with psql and a laptop DuckDB. The product is useful when the SQL, the frame, the chart, and the note need to stay together for the next reviewer.
Take this home: pick for today’s question; expire scratch; never let an agent become the ledger. If that saved you a migration, good. If you want the choose-a-connection loop inside a governed notebook, look at Quantum Lab. The engine holy war can wait.
Put it to work
Bring the next question into your workflow.
Keep the query, result, and explanation together when the analysis becomes team work.
