Chris Collins

Tools · infra

DuckDB analytics lab

Real DuckDB in your browser with a console, results grid, plan trees for EXPLAIN ANALYZE, quick charts and CSV/Parquet export — sample datasets, your own CSV/Parquet/JSON files read locally, and twelve guided labs: window functions, QUALIFY, PIVOT, ASOF joins, ROLLUP/CUBE, nested types, regex, Parquet metadata and columnar storage.

Added · updated 28 October 2026

Works with

  • Log parser Dataopens a log parsed in the log parser as a JSONL file, ready to query with SQL
How to use it

This is DuckDB itself — version 1.4, compiled to WebAssembly as duckdb-wasm — running in a Web Worker in this page. It is the analytical cousin of SQLite: in-process, no server, but columnar and vectorised, built for scanning and aggregating millions of rows rather than fetching one. The dialect is PostgreSQL-flavoured with a lot of conveniences on top, and the Labs tab walks through the ones worth knowing.

For one-off runs next to other languages, the code sandbox has DuckDB too; for cleaning and reshaping a table step by step without writing SQL, use the table wrangler. For how a row store lays out the same data on disk, see SQLite internals.

How to use it

Console. Type SQL and press Ctrl/⌘+Enter to run everything (or the selection); Ctrl/⌘+Shift+Enter runs the statement at the cursor. Each statement gets its own block:

  • a results grid (click a column header to sort; the type is shown under each name), the row count and the time taken;

  • Chart draws a bar or line chart from two columns of the result — it guesses a label or date column for x and a number for y, and you can change both;

  • Copy CSV, Copy Markdown, Download CSV, and Download Parquet, which runs the query again into a Parquet file (so it has every row, not only the 20,000 fetched into the page);

  • for EXPLAIN and EXPLAIN ANALYZE, the plan drawn as a tree: each operator with its row count (estimated, or actual after ANALYZE), its own time as a bar, the details DuckDB reports (filters pushed into scans, join conditions, aggregates) and a line on what the operator does. Text shows DuckDB’s own box drawing. The Explain and Explain analyze buttons work on the statement at the cursor.

The panel beside the editor lists the tables and their columns (click a column to insert it, or ▶ FROM to look at a table) and the files DuckDB can see.

Labs. Twelve short guided labs, each a few runnable steps with a note on what to look at: a first tour of DuckDB’s friendly SQL (FROM first, SUMMARIZE, * EXCLUDE, COLUMNS(), GROUP BY ALL), window functions, QUALIFY, PIVOT and UNPIVOT, ASOF joins, ROLLUP / CUBE / GROUPING SETS, lists, structs and maps with lambdas, regular expressions and string functions, Parquet and its metadata (parquet_metadata, parquet_schema, row-group skipping), reading plans, columnar versus row thinking (how each column is compressed, with pragma_storage_info), and querying your own files. Run runs one step under it; Open in console copies it to the editor.

Data. Four sample datasets, generated in SQL from range() and hash() when DuckDB starts, so they cost nothing to download and are the same every time:

  • Shop — customers (300), products (40) and orders (about 6,500 over 2024, busier at weekends and in December);

  • Taxi trips — trips (5,000 in March 2024) and zones: pickup and drop-off times, distance, fare, tip, payment. The shape follows the NYC TLC trip records; the data is made up;

  • Weather — hourly readings for three stations over March 2024, with daily cycles and a few gaps;

  • Markets — bid/ask quotes and trades for three symbols, for ASOF joins.

Reload puts a dataset back; Show the SQL shows how it is generated (the helper macros u() and pick() are created in the database).

Your files. Drop CSV, TSV, Parquet or JSON (also gzipped) files on the Data tab or the console, or use Add files…. Each is registered with DuckDB under its file name and read straight from your disk as queries need it, so FROM 'sales.csv' and FROM read_parquet('big.parquet') work and even large files open quickly. Make a table copies one into a table; Metadata shows a Parquet file’s footer. Files you write with COPY … TO 'name' live in DuckDB’s in-memory file system and can be downloaded from the same list.

History keeps what you ran in this browser, searchable; click one to put it back in the editor.

Share link (at the top of the page) copies a link with the console’s SQL and the lab you are on.

The engine

duckdb-wasm 1.32.0 (DuckDB 1.4.3, MIT licence) is loaded from jsDelivr at a pinned version when the page opens: about 7 MB compressed (33 MB unpacked), cached by the browser after the first visit. It starts in a couple of seconds on a laptop.

The page loads the EH build (WebAssembly exception handling), which is single-threaded. DuckDB’s multi-threaded build needs SharedArrayBuffer, which browsers only allow on pages served with cross-origin isolation headers (COOP/COEP) — and GitHub Pages, where this site lives, cannot send them. Everything works single-threaded; it is just not parallel, so the timings are slower than a native DuckDB on the same machine, and the operators that would run in parallel (hash aggregates, sorts, joins) run on one core.

Limits worth knowing:

  • The database is in memory and is lost when you leave the page. Export anything you want to keep as CSV or Parquet.

  • In-memory tables are not compressed, so the columnar lab attaches a second in-memory database with (COMPRESS) to show what DuckDB does with a file-backed table.

  • Interval values cannot be decoded by the Arrow library in the page, so interval columns are shown as text.

  • Extensions that are not built in (spatial, httpfs, ICU time zones …) are fetched on demand from extensions.duckdb.org when a query needs one. Reading files over HTTP from other sites only works when those sites allow cross-origin requests.

Privacy

Your SQL, the datasets and your files stay in this browser: files are read from your disk by the page and are never uploaded. The network is used to fetch duckdb-wasm from cdn.jsdelivr.net, and DuckDB itself fetches an extension from extensions.duckdb.org if a query needs one that is not built in. The console text, the lab you are on and the history are kept in this browser’s local storage.

Runs entirely in your browser — network requests go only to the services named on this page.