Skip to content

GeoSilo

Compact geometry storage for DuckDB.

30,821
extension loads Β· last 90 days
On this page

Technical Overview

Geometry without paying the WKB tax

What this extension is for

  • β€’ Smaller on disk: On the TIGER/Line 2025 US Census dataset, GEOSILO + ZSTD is ~21% smaller than DuckDB's GEOMETRY column (and ~70% smaller as raw blobs vs WKB). The win comes from delta-encoded int16 deltas compressing exceptionally well under ZSTD.
  • β€’ Native ST_* fast paths: ST_GeometryType, ST_IsEmpty, ST_NPoints, ST_X / ST_Y, ST_XMin / ST_XMax / ST_YMin / ST_YMax, ST_Area, ST_Length, ST_Perimeter all have GEOSILO-native implementations. They read the silo header or walk the integer delta stream directly β€” no GEOS round-trip.
  • β€’ Transparent fallback: Any ST_* function without a native GEOSILO overload β€” ST_Buffer, ST_Union, ST_AsText, etc. β€” still works. The implicit GEOSILO β†’ GEOMETRY cast runs geosilo_decode on demand.
  • β€’ Arrow IPC interchange: GeoSilo registers an Arrow extension type named queryfarm.geosilo. Producers tag a binary column with that metadata; the DuckDB consumer auto-decodes silo blobs to GEOMETRY on read and re-encodes on write. CRS rides through the metadata so scale stays consistent end-to-end.

How the encoding works

  • β€’ Coordinates as scaled integers: Each (x, y) pair is multiplied by an integer scale and stored as integers. For EPSG:4326 (degrees), the default scale is 1e7 β€” about 1 cm precision. For projected CRSes like UTM or EPSG:3857 (meters), the default is 100, also 1 cm.
  • β€’ Delta encoding within rings: The first vertex of each ring is stored as a 4-byte int32. Every subsequent vertex is a 2-byte int16 delta from the previous one. Roughly 90% of deltas fit in 2 bytes; the remainder fall back to a 6-byte escape sequence.
  • β€’ Tight headers, no closing vertex: Points use a 1-byte compact header. Polygon rings omit the closing duplicate vertex (it's reconstructed on decode). The header carries geometry_type, vertex_type, and scale, all readable by geosilo_metadata without touching the body.
  • β€’ Bounding-box and area on integers: Native ST_XMin/XMax/YMin/YMax walk the int16 delta stream and accumulate; native ST_Area runs the shoelace formula on int64 coordinates rebuilt from the same stream. Both avoid the GEOS dependency surface for these calls.

Honest scope

  • β€’ Native overloads are limited: The native fast path covers introspection, bounding-box accessors, and area / length / perimeter. Operations like ST_Buffer, ST_Union, ST_Intersection, ST_AsText, and most of the wider ST_* surface still auto-decode to GEOMETRY and use spatial's GEOS-backed implementation.
  • β€’ Lossy at the chosen scale: Coordinates round to the integer scale you pick. The defaults give ~1 cm precision for the common CRSes; finer-grained data needs an explicit geosilo_encode(geom, scale). Round-tripping through GeoSilo and back is not bit-exact with the original float64 WKB.
  • β€’ ZSTD does the heavy lifting: Without ZSTD, raw GEOSILO blobs are actually larger than DuckDB's columnar GEOMETRY storage. USING COMPRESSION zstd is what makes the storage win real β€” use it.
  • β€’ Spatial extension required: GeoSilo overlays spatial's ST_* namespace. Load spatial first, then geosilo, in every connection that needs the GEOSILO type.

Common Use Cases

Deep Dive

Technical Details

Install

INSTALL geosilo FROM community;
LOAD geosilo;

Quick Start

A GEOSILO column with ZSTD β€” create, load from a GEOMETRY source, query with ST_*

-- A GEOSILO column with ZSTD β€” the recommended setup
CREATE TABLE parcels (
  id    INTEGER,
  name  VARCHAR,
  geom  GEOSILO('EPSG:4326') USING COMPRESSION zstd
);

-- Insert from any GEOMETRY source β€” implicit cast auto-encodes
INSERT INTO parcels SELECT id, name, geom FROM raw_parcels;

-- ST_* runs directly on the GEOSILO column; native overloads skip the decode
SELECT id, ST_Area(geom), ST_X(ST_Centroid(geom)) FROM parcels;

Reference

Extension Contents

Quick reference to all available functions and settings organized by category.

Name Description
Encoding
geosilo_decode() Decode a GEOSILO blob back into a standard GEOMETRY.
geosilo_encode() Encode a GEOMETRY into the compact GEOSILO format and return a BLOB.
geosilo_metadata() Read a GEOSILO blob's header without decoding the geometry.
Introspection (native)
ST_GeometryType() Native GEOSILO overload β€” returns the geometry type (e.g.
ST_IsEmpty() Native GEOSILO overload β€” TRUE if the encoded geometry has no vertices.
ST_NPoints() Native GEOSILO overload β€” total vertex count, read from the silo header.
ST_X() Native GEOSILO overload β€” X coordinate of a single-point geometry, decoded from the silo header without materializing a GEOMETRY.
ST_XMax() Native GEOSILO overload β€” maximum X across the geometry.
ST_XMin() Native GEOSILO overload β€” minimum X across the geometry, computed by walking the integer delta stream.
ST_Y() Native GEOSILO overload β€” Y coordinate of a single-point geometry, decoded from the silo header without materializing a GEOMETRY.
ST_YMax() Native GEOSILO overload β€” maximum Y across the geometry.
ST_YMin() Native GEOSILO overload β€” minimum Y across the geometry.
Measurement (native)
ST_Area() Native GEOSILO overload β€” polygon area computed via the shoelace formula directly on int64 coordinates rebuilt from the delta stream.
ST_Length() Native GEOSILO overload β€” total length of linear geometries, computed on the integer delta stream without rehydrating a GEOMETRY.
ST_Perimeter() Native GEOSILO overload β€” perimeter of polygonal geometries, computed on the integer delta stream without rehydrating a GEOMETRY.
Types
GEOSILO Logical type registered by this extension.

API Reference

Function Documentation

Data model

Registered Types

Logical types this extension adds to DuckDB. Functions in the reference may accept or return these names directly.

  • GEOSILO

    Logical type registered by this extension.

Practical Examples

Cookbook

Real-world recipes and patterns for common use cases.

Platform Support

Compatibility

Extension availability may vary by platform and DuckDB version. Check below to ensure this extension supports your environment before installation.

Quick Facts

Release status Stable
Software License MIT
Pricing Free
Written In C++
Source Available Yes
View on GitHub
Usage
30,821
loads Β· last 90 days

Platforms

  • Linux x86_64 aarch64
  • Linux (musl) Not available
  • macOS Intel Apple Silicon
  • Windows x86_64
  • WASM eh mvp threads
Compiled binary sizes
Platform Architecture Size
Linux x86_64 3.26 MB
Linux aarch64 2.89 MB
macOS Intel 2.64 MB
macOS Apple Silicon 2.30 MB
Windows x86_64 7.40 MB
WASM eh 53.8 KB
WASM mvp 46.6 KB
WASM threads 54.0 KB

Compressed download size from the Haybarn extension repository.

DuckDB & Haybarn

Release calendar