This guide covers serving vector tiles on-the-fly from GeoParquet files — no preprocessing or tile generation step required.
What is GeoParquet?
GeoParquet is a standardized way to store geospatial data in Apache Parquet files. It is rapidly becoming the default interchange format for large geospatial datasets:
- Overture Maps Foundation distributes its entire dataset (~200 GB) as GeoParquet
- Source Cooperative, CARTO, and Google Open Buildings all publish GeoParquet
- The data science ecosystem (pandas, DuckDB, Polars) reads Parquet natively
| Feature | GeoParquet | Shapefile | GeoJSON |
|---|---|---|---|
| File size | Compressed (zstd/snappy) | Uncompressed | Uncompressed |
| Max features | Billions | ~70M (2 GB limit) | Memory-limited |
| Spatial index | Row group bbox (v1.1) | .shx index | None |
| Schema | Typed columns | .dbf types | JSON types |
| Cloud-native | Yes (range reads) | No | No |
Quick Start
Point tileserver-rs at a GeoParquet file:
[[sources]]
id = "buildings"
type = "geoparquet"
path = "/data/overture-buildings.parquet"
Or use zero-config auto-detection — drop a .parquet file in your data directory:
tileserver-rs /data/
GeoParquet support requires the geoparquet feature flag: cargo build --features geoparquet
Configuration
Basic
[[sources]]
id = "buildings"
type = "geoparquet"
path = "/data/overture-buildings.parquet"
Full Options
[[sources]]
id = "buildings"
type = "geoparquet"
path = "/data/overture-buildings.parquet"
name = "Overture Buildings"
attribution = "© Overture Maps Foundation"
layer_name = "buildings"
geometry_column = "geometry"
minzoom = 0
maxzoom = 14
| Option | Description | Default |
|---|---|---|
layer_name | MVT layer name in tile output | Source id |
geometry_column | Name of the WKB geometry column | Auto-detected from GeoParquet metadata |
minzoom | Minimum zoom level to serve | 0 |
maxzoom | Maximum zoom level to serve | 14 |
How It Works
When a client requests a tile:
- Convert tile coordinates (z/x/y) to a WGS84 bounding box
- Read the Parquet file with row group filtering (skip groups outside the bbox)
- Filter individual features by bbox intersection
- Encode matching features as MVT protobuf
- Return the tile with
Content-Type: application/x-protobuf
Client request: GET /data/buildings/14/8192/5461.pbf
↓
z/x/y → bbox [-74.01, 40.71, -73.99, 40.73]
↓
Parquet reader (row group pruning via bbox metadata)
↓
Feature filtering (bbox intersection)
↓
MVT encoding (protobuf)
↓
Response: 200 OK, application/x-protobuf
GeoParquet 1.1 Bbox Covering
GeoParquet 1.1 files include a bbox struct column with xmin, ymin, xmax, ymax fields per feature. tileserver-rs uses this for fast spatial filtering without deserializing geometry data.
Overture Maps data includes this column — spatial queries on 73M+ features complete in ~140ms.
Files without the bbox column still work but filter by reading all geometry data (slower on large files).
Drag-and-Drop Upload
GeoParquet files can be uploaded via the built-in drag-and-drop interface. Drop a .parquet or .geoparquet file onto the map viewer to instantly visualize it as vector tiles.
The file is uploaded to the server, registered as a GeoParquet source, and tiles are served on-the-fly.
Obtaining GeoParquet Data
Overture Maps
The largest public GeoParquet dataset. Download specific themes:
# Install the Overture CLI
pip install overturemaps
# Download buildings for a bounding box
overturemaps download \
--bbox=-74.1,40.6,-73.8,40.9 \
-f geoparquet \
--type=building \
-o nyc-buildings.parquet
DuckDB
Query and export GeoParquet from any source:
INSTALL spatial; LOAD spatial;
COPY (
SELECT name, geometry
FROM read_parquet('s3://overturemaps-us-west-2/release/2025-03/theme=places/**/*.parquet')
WHERE bbox.xmin >= -74.1 AND bbox.xmax <= -73.8
AND bbox.ymin >= 40.6 AND bbox.ymax <= 40.9
) TO 'nyc-places.parquet' (FORMAT PARQUET);
GDAL/ogr2ogr
Convert any vector format to GeoParquet:
ogr2ogr -f Parquet output.parquet input.geojson
ogr2ogr -f Parquet output.parquet input.shp
MLT Transcoding
GeoParquet sources output MVT tiles. If a client requests .mlt format, the existing MLT transcoding layer converts MVT→MLT on-the-fly — no additional configuration needed.
GET /data/buildings/14/8192/5461.mlt → MVT generated → MLT transcoded → response
Performance
| Dataset Size | First Tile (cold) | Notes |
|---|---|---|
| 1M features | ~50–200ms | With GeoParquet 1.1 bbox column |
| 10M features | ~100–500ms | Row group pruning essential |
| 100M+ features | ~200ms–1s | Depends on spatial distribution |
Tips
- Use GeoParquet 1.1 with bbox covering columns for fastest filtering
- Set
maxzoomto avoid generating tiles at unnecessarily high zoom levels - Use zstd compression for best file size and read performance
- For very large files (10 GB+), consider partitioning by region