Polymarket Data in DuckDB
Polymarket Data in DuckDB
DuckDB is the analysis engine that matches the data's shape: wide timestamp rows in Parquet/CSV, queried by SQL, no server to run. It is the fastest route from a downloaded slice to a pivot.
Figures measured as of 2026-10-02 on the published PolyOrderbooks archive.
Load
Getting rows in
- CREATE TABLE books AS SELECT * FROM read_parquet("polymarket_books_*.parquet"); loads a directory of Parquet in one line.
- CSV path: read_csv_auto("slice.csv") type-infers timestamps, prices, and depths.
- REST-to-file: a tiny worker script fetches a window and writes Parquet; DuckDB then owns analysis.
- For enterprise, S3 delivery drops Parquet/CSV/JSON that COPY FROM s3:// reads directly.
Queries
Queries that stay useful
- Per-contract summaries: SELECT market, count(*) FILTER (WHERE ask_depth = 0) / count(*) AS pct_onesided FROM books GROUP BY market.
- Spread stats: quantile_cont(sell_price - buy_price, 0.5) over windows by market type.
- Settlement cross-check: join final-minute flags to resolution outcomes (the archive carries both).
- Window aggregates: date_bin(1m, ts) chunks 250ms rows into minute bars for coarser studies.
Why
Why DuckDB fits
Columnar scans make multi-hundred-million-row aggregates immediate on a laptop; Books, prices, and metrics come back over the same endpoints at the same 250ms resolution, so a dashboard needs one schema, not three.
There is no ETL server to babysit — point DuckDB at files and query. When the dataset outgrows the laptop, the same SQL runs on ClickHouse or BigQuery.
Worked example
Settlement analytics in SQL
Point DuckDB at the books directory and compute per-contract one-sidedness over the final hour: SELECT market, count(*) FILTER (WHERE ask_depth = 0)/count(*) AS p FROM books GROUP BY 1.
Step back to 1m bars with date_bin('1 minute', ts) when rendering dashboards; 250ms stays in the file, the bars stay in RAM.
Sanity-checks
The numbers to sanity-check
The full 8,349-slice September BTC run at 250ms is tens of millions of rows; a settlement group-by over the final-hour window should answer in a few seconds, not minutes.
Notes
Going further
DuckDB is also the engine for the guide's published studies — the same SQL reproduces the archive flags from raw 250ms files.
Honest fit
Where this tool wins
DuckDB is the SQL engine that matches 250ms granularity without ceremony: columnar scans on Parquet mean the September BTC settlement run, tens of millions of rows, answers in seconds on a laptop.
The honest boundary is sharing, not compute — a single analyst gets laptop scale for free; a team that wants governed access upgrades the store, not the queries.
Notes
First repro
The 8,349-contract September BTC window is the standard stress dataset in this guide — it stays queryable at 250ms under DuckDB without special tricks.
Get started
Your first solid pull
First query is the settlement scan: point read_parquet at a month of BTC frames and run the final-hour one-sided count per contract; on a laptop, DuckDB returns it in seconds, which is the threshold that tells you this stack works.
Complement it with a window sanity query: select min(ts), max(ts), count(*) from the same files; the range should equal the nominal window exactly, and count should equal seconds x 4 for 250ms.
Conclusion
How to take it further
DuckDB is the proof that hundreds of millions of 250ms frames do not need an infrastructure project to query. The settlement scans, one-sided rates, and point-in-time lookups that this guide uses as examples all run in seconds from Parquet files on a laptop.
The tuple that keeps DuckDB honest is three checks: min/max ts equals the nominal window, row count equals seconds times four at 250ms, and a cross-check against the CSV export for one day. Pass those three and the SQL you write today is the SQL you trust next year.
When the team grows, the files move to a shared bucket and the same queries run under Athena or BigQuery with minimal edit — the schema, not the engine, is the contract you maintain.
FAQ
Does DuckDB need a server?
No — it embeds in the process and reads files directly (Parquet, CSV). That makes it the lowest-friction SQL engine for Polymarket slices.
What format should I request?
Parquet for scale, CSV for spreadsheets. The archive serves both on downloads and datasets; enterprise delivery is Parquet/CSV/JSON on S3.
Can DuckDB handle 250ms series?
Yes — columnar storage and parallel scans handle hundred-million-row tables comfortably; date_bin lets you step down to 1m bars when needed.