DuckDB & analytic SQL

A spatial database with no server: querying GeoParquet, joining millions of rows, and where it beats a GeoDataFrame.

The usual four steps to query a large file, against querying it where it already is. no server, no load step, no index to builddownloadstart a serverload itindex itquerySELECT … FROM 'https://…/parcels.parquet' WHERE ST_Intersects(…)one stepIt reads the row groups the predicate needs and leaves the rest of the file where it is

DuckDB is a spatial database with no server and no load step. It reads GeoParquet, GeoPackage, shapefiles and CSV in place — including over HTTP — and runs analytic SQL over them at a speed that makes a GeoDataFrame look like the wrong tool for anything joined.

What it gives up is the other half of what a database is for: no concurrent writers, no shared instance, no index it maintains between sessions. That trade is exactly right for analysis over files and exactly wrong for an application several people write to, which is the line between this topic and PostGIS.

Below: the concepts cover the spatial extension, how it reads remote files and where its CRS handling differs from GeoPandas; the how-to guides query, join and convert; and the fixes cover the reads and transforms that behave differently from what you expected.

Learning paths run through this topic too — see the end of this page.

🧭 Start with the concepts

The ideas the how-to guides below assume you already have.

⚙️ Then do the task

Step-by-step walkthroughs with code you can copy and adapt.

Show every how-to guide in this topic

🔧 When it breaks

The errors this topic produces, with the cause explained rather than just the command.

Related topics

Subjects that keep coming up alongside this one, most overlap first.

Keep browsing

DuckDB & analytic SQL sits in Tools. Every topic on the site is listed on the topics index.