GeoParquet vs FlatGeobuf for Cold-Archive Retrieval
Choosing between GeoParquet and FlatGeobuf for a cold spatial archive is a decision about access pattern, not file size: GeoParquet’s columnar layout and per-row-group statistics win analytical scans that touch few columns across many features, while FlatGeobuf’s packed Hilbert R-tree and HTTP range streaming win feature-by-bounding-box reads served straight from object storage. Both are cloud-native, both read anywhere GDAL runs, and both beat legacy shapefiles for archival — but they optimize opposite retrieval shapes, and picking the wrong one turns a penny range request into a multi-gigabyte download. This decision guide is for the data engineers and cloud architects who must commit an archive to one format per access tier under the Format Conversion & Pipeline Automation framework, weighing predicate pushdown, index structure, compression, and tooling against how each dataset is actually retrieved.
Framing the Decision
Cold-archive retrieval is dominated by two workloads that pull the format choice in opposite directions. The first is the analytical scan: “sum the burned area across every wildfire polygon in the 2015–2023 archive,” which reads two or three columns from millions of features and never materializes geometry. The second is the point read: “fetch the parcels intersecting this map viewport,” which needs whole features inside a small bounding box and nothing else. A columnar format serves the first for the cost of reading a few column chunks; a spatially indexed feature format serves the second for the cost of an R-tree descent plus a few range requests. The mistake is committing an archive to one format before profiling which workload dominates — or worse, assuming one format can be optimal for both. The tiering logic here mirrors the broader hot/warm/cold tier design for geospatial data: access pattern, not age alone, drives the layout.
Head-to-Head Comparison
The two formats differ on every axis that matters for retrieval economics:
The Same Query Against Both Formats
The clearest way to separate the formats is to trace one realistic archive query through each. The query — “give me every parcel in this district with a land-use code of R3, as of the 2024 generation” — has a spatial predicate, an attribute predicate, and a projection, which is the normal shape of an archival read.
That last sentence is the honest qualification. FlatGeobuf’s disadvantage here is specific to selective attribute queries over wide tables; for a map client that wants whole features in an extent — which is what it was designed for — it transfers less than a columnar reader that has to reassemble rows from twenty-two column chunks, and it does it without an engine.
Per-Dimension Analysis
Physical layout and partial reads
GeoParquet stores each attribute in its own contiguous column chunk, so a query that needs burn_area_ha and fire_year reads exactly those two chunks and skips the geometry entirely. That projection is impossible in FlatGeobuf, where every feature is a self-contained record: reading one attribute means paging in the whole feature, geometry included. For an analytical scan over a wide attribute table, this is the single largest difference in bytes transferred — often an order of magnitude — because cold-storage cost is dominated by what you move, not what you store. FlatGeobuf’s row orientation is the correct trade only when you genuinely want the whole feature.
Index structure and the point-read path
FlatGeobuf embeds a packed Hilbert R-tree in the file header, laid out so a bounding-box query resolves to a small set of byte ranges without a full scan. A client issues one range request for the index, walks it, then issues range requests for the matching feature bytes — three or four round trips to pull the parcels in a viewport, straight from S3 with no server. GeoParquet’s spatial “index” is coarser: per-row-group bounding-box statistics let a reader skip row groups that cannot intersect the query, but within a surviving row group it still scans. If your row groups are spatially clustered — the payoff of spatial partitioning techniques — this pruning is effective for regional filters, but it will never match FlatGeobuf’s per-feature precision for a tight bbox over a dense layer.
Compression and cold-storage footprint
Columnar storage compresses better because a column is a run of like-typed, often low-cardinality values — exactly what dictionary and ZSTD encoders exploit. A GeoParquet archive of categorical vector data routinely lands well under half the size of the equivalent FlatGeobuf, and the ratio widens as you tune the encoder; the level-versus-latency trade-off is laid out in ZSTD level configuration for spatial files. FlatGeobuf compresses its geometry buffer efficiently but cannot reach columnar ratios on attributes, because each feature interleaves fields of different types. For a deep-archive tier billed purely on stored bytes, GeoParquet’s footprint advantage is decisive; for a warm tier billed on retrieval, footprint matters less than range-read efficiency.
Streaming and serverless retrieval
FlatGeobuf was designed to stream: a reader can begin emitting features before the whole file arrives, and the format is a first-class citizen of browser mapping stacks that fetch directly from object storage over HTTP range requests. That makes it the natural archive format when the retrieval client is a map, not a query engine, and there is no compute layer between the bucket and the user. GeoParquet retrieval assumes a reader that understands row groups and statistics — DuckDB, Arrow, GDAL, or a Spark job — so it shines when a serverless SQL engine sits in front of the archive, and is awkward when the consumer is a thin web client. The optimization details for the streaming path are covered under FlatGeobuf optimization techniques, and the columnar migration path under GeoParquet migration workflows.
Tooling and durability
Both formats are open and GDAL-native, so neither is a lock-in risk. GeoParquet inherits the entire Parquet and Arrow ecosystem — DuckDB, pandas, Spark, cloud query services — which is a large advantage for analytical archives and for interoperability with non-spatial data lakes. FlatGeobuf’s ecosystem is narrower and mapping-centric, but its specification is simpler, which some archivists weigh as a durability argument for a format that must remain readable for decades. Both are backed by public specifications; verify writer conformance against the GeoParquet specification and the FlatGeobuf specification before committing an archive.
Recommendation by Scenario
Analytical archive queried by SQL — choose GeoParquet. When the dominant workload is aggregations, filters, and joins across many features touching few columns — climate model outputs, census-scale demographics, sensor time series — the columnar layout and predicate pushdown make GeoParquet the clear winner, and its compression minimizes the deep-archive bill.
Web-map archive served straight from object storage — choose FlatGeobuf. When retrieval means “give me the features in this viewport” and the client is a browser hitting a bucket with no query engine in between, FlatGeobuf’s packed R-tree and range streaming deliver sub-second bbox reads that GeoParquet cannot match on a dense layer.
Mixed archive with both patterns — dual-encode by tier. Keep the authoritative copy as partitioned GeoParquet in the cold, cost-optimized tier for analytics and long-term preservation, and derive a FlatGeobuf copy into a warm, retrieval-optimized tier for the map-serving path. The GeoParquet partition boundary maps cleanly onto the FlatGeobuf tiles, so the derivation is deterministic, and each tier’s storage class is chosen against its real access economics rather than a single compromise.
Uncertain or evolving access pattern — default to GeoParquet. Its broader tooling and superior compression make it the safer default when you cannot yet profile the workload; a FlatGeobuf derivative can always be generated later from the columnar master, whereas reconstructing columnar statistics from FlatGeobuf is a full rewrite.
Before committing either choice at scale, model the retrieval side — request counts, egress, and restore fees — with spatial archive cost modeling, because for cold data the retrieval bill, not the storage bill, usually decides the winner.
Cost of Keeping Both
Most mature archives stop treating this as an either-or and keep a columnar archive of record plus a delivery copy. That is a real cost, and it is smaller than teams expect once the storage classes are chosen deliberately.
The decisive variable is what fraction of the archive is actually served. Where that fraction is small — and for most institutional archives it is under a tenth — duplicating it costs a rounding error against the archive’s storage line and removes both the restore latency and the conversion compute from every read path. Where nearly everything is served, the delivery copy stops being a copy and becomes the primary, which is a different design with different retention implications.
Validating the Choice on Real Data
Before standardizing a format, benchmark both against a representative sample and measure bytes transferred, not just wall-clock time. Encode the same layer each way, then run each format’s characteristic query directly against object storage:
# GeoParquet: analytical scan touching two columns, projection pushdown
duckdb -c "
INSTALL httpfs; LOAD httpfs; INSTALL spatial; LOAD spatial;
SELECT fire_year, sum(burn_area_ha) AS total_ha
FROM read_parquet('s3://spatial-archive/fire/geoparquet/**/*.parquet')
GROUP BY fire_year ORDER BY fire_year;"
# FlatGeobuf: bounding-box feature read, R-tree range requests only
ogr2ogr -f GPKG /vsimem/viewport.gpkg \
/vsis3/spatial-archive/fire/fire_perimeters.fgb \
-spat -122.6 37.7 -122.3 37.9 -progress
Expected shape of the result — the GeoParquet scan returns an aggregate having read only two column chunks, confirming projection pushdown worked:
┌───────────┬───────────┐
│ fire_year │ total_ha │
├───────────┼───────────┤
│ 2015 │ 184203.5 │
│ 2016 │ 201884.1 │
└───────────┴───────────┘
Compare the bytes each retrieval moved — enable request logging on the bucket — and let the transfer volume, weighted by your real query mix, settle the decision.
Troubleshooting Format Selection
| Symptom | Cause | Fix |
|---|---|---|
| GeoParquet bbox reads scan far more than expected | Row groups are not spatially clustered, so statistics prune poorly | Sort by a spatial key and re-write with smaller row groups before archiving |
| FlatGeobuf analytical scan transfers the whole file | Row-oriented layout has no column projection | Move analytics to a GeoParquet copy; keep FlatGeobuf only for bbox reads |
| GeoParquet retrieval needs a running engine users lack | Consumers are thin web clients, not query engines | Derive a FlatGeobuf tier for direct-from-bucket map serving |
| Deep-archive bill higher than modeled | FlatGeobuf attribute compression trails columnar | Store the preservation master as GeoParquet; treat FlatGeobuf as a derived access copy |
Operational Execution Checklist
Frequently Asked Questions
Which format should be the archive of record?
GeoParquet, in nearly every case where the archive supports analysis as well as delivery. It compresses better, supports column projection and attribute pruning, carries its reference system and covering metadata in a structured block, and is read by every engine an analyst is likely to use. FlatGeobuf’s advantages are all on the delivery path, and a delivery copy can be regenerated from the archive of record whereas the reverse loses attributes and structure.
Does either format handle raster or point-cloud data?
Neither. Both are vector feature formats. Raster archives belong in Cloud-Optimised GeoTIFF, which supports the same ranged-read access pattern through internal tiling and overviews, and point clouds in COPC or LAZ. An archive covering all three keeps the access pattern consistent — range-readable, self-describing, no server — and varies the format by data type rather than forcing one format to cover everything.
How do the two compare on long-term readability?
Both are open specifications with multiple independent implementations, which is the property that matters for a multi-decade archive. Parquet has the broader base by a wide margin, being a general data-processing format with a large ecosystem beyond the spatial world, and GeoParquet is a thin, well-documented convention on top of it. FlatGeobuf is a simpler format, which cuts the other way: it is easier to write a reader for from the specification alone.
Can one file serve both purposes?
Only by accepting the weaker option on one axis. A GeoParquet file can be read over ranged requests by a client that understands Parquet footers, and there are browser implementations that do — but they are heavier than a FlatGeobuf reader and the projection benefit disappears if the client wants whole features anyway. If a single format must serve both, choose by whichever workload has the tighter constraint: storage cost and analysis favour GeoParquet, first-paint latency in a browser favours FlatGeobuf.
How does the choice interact with the storage class?
Strongly, and in opposite directions. FlatGeobuf’s advantage is ranged reads, which require a class that serves ranges without a restore — so a delivery copy has to sit in standard or instant-retrieval storage, where per-gigabyte costs are highest. GeoParquet’s advantages survive a restore intact, so the archive of record can live in the deepest, cheapest class the retention policy allows and still prune effectively once restored. That asymmetry is usually what decides the split: the served fraction goes to instant retrieval as FlatGeobuf, the rest goes deep as GeoParquet.
Which format is easier to validate at scale?
GeoParquet, because its footer carries a structured, machine-readable description of the file that can be fetched without reading the data. Validating a FlatGeobuf file means reading its header and, for anything beyond header fields, walking the index or the features. For an archive running continuous integrity checks over millions of objects, that difference in validation cost is significant.
What does a migration between the two formats cost?
Very little in either direction for the data itself, because both are lossless with respect to geometry and attributes — a conversion is a read, a re-encode and a write, with no decisions to make beyond ordering and compression. The cost is in what surrounds it: regenerating indexes, republishing the delivery manifest, invalidating caches, and updating whatever catalogue entries point at the old files. Budget the conversion as a fraction of a day per terabyte of compute and the surrounding work as the larger half.
Is there a third option worth considering?
For vector archives specifically, PMTiles is worth knowing about as a delivery format: it packs pre-rendered or pre-clipped tiles into a single range-readable archive, which suits map display better than either format here but discards the features themselves. It answers a different question — how to serve a basemap — rather than how to preserve and query a feature collection, so it complements a GeoParquet archive of record rather than competing with it.
Related
- Up: Format Conversion & Pipeline Automation — the parent reference for the conversion pipelines that produce both formats.
- Converting Legacy Shapefiles to GeoParquet at Scale — the columnar migration path for the GeoParquet side of this decision.
- Optimizing FlatGeobuf for Web Mapping Archives — tuning the packed R-tree and streaming path for the FlatGeobuf side.
- Tuning ZSTD Compression for GeoParquet Archives — compression tuning that widens GeoParquet’s footprint advantage.
- Spatial Archive Cost Modeling — modeling the retrieval and storage economics that ultimately settle the format choice.
Part of the Spatial Data Archival knowledge base.