PostGISOverlay

ST_Subdivide

What is ST_Subdivide?

ST_Subdivide takes a geometry and recursively splits it into smaller pieces until each piece has no more than a specified number of vertices. It is a set-returning function — one row per piece — and is the standard tool for making huge geometries (big country polygons, giant coastline multilines) index-friendly and fast to query.

SQL
ST_Subdivide(geometry geom, integer max_vertices = 256, float gridSize = -1) → setof geometry

max_vertices defaults to 256 and must be at least 8. The optional gridSize (PostGIS 3.1+) snaps to a fixed precision grid to improve robustness.

When would you use ST_Subdivide?

Use ST_Subdivide when preparing data for fast spatial joins and tiling. Large monster polygons (a country multipolygon, a full continent of coastline) produce oversized GiST index entries that ruin query performance; subdividing them first so each row is small makes ST_Intersects and ST_DWithin dramatically faster. It is also used to produce smaller tiles for vector map rendering, for parallel processing, and for chunked batch overlays.

Code
undefined

FAQs

Why is subdividing faster for spatial joins?

GiST indexes entries are bounding boxes. A huge polygon has a huge bbox that matches most queries, so the index prunes nothing and every candidate must be evaluated by expensive exact-geometry tests. Subdivided pieces have small bboxes, so the index actually helps and queries can run orders of magnitude faster.

What is a good value for max_vertices?

Between 64 and 256 is typical. Too small produces many rows; too large defeats the purpose. Profile on your data — often 128 is a good default.

Does subdivide preserve topology?

The union of all pieces equals the original geometry. Individual pieces are valid polygons/lines sharing edges with their neighbours but no duplicated area. Use ST_Union over an identifier to reassemble the original if needed.

How does ST_Subdivide differ from ST_Split?

ST_Split cuts a geometry with a specific blade you provide. ST_Subdivide automatically splits until each piece is below a vertex threshold, without you specifying cut lines.