Geometry vs Geography
PostGIS geometry uses planar math in a projected coordinate system. geography uses a spheroid model on WGS84 for geodesic distances in meters. Pick the type that matches your SRID and distance accuracy needs.
Search across all documentation pages
PostGIS geometry uses planar math in a projected coordinate system. geography uses a spheroid model on WGS84 for geodesic distances in meters. Pick the type that matches your SRID and distance accuracy needs.
-- Same lon/lat, different types
SELECT
extensions.ST_SetSRID(extensions.ST_MakePoint(-73.9857, 40.7484), 4326) AS geom_4326,
extensions.ST_SetSRID(extensions.ST_MakePoint(-73.9857, 40.7484), 4326)::extensions.geography AS geog;
-- Distance NYC to LA
SELECT extensions.ST_Distance(
extensions.ST_SetSRID(extensions.ST_MakePoint(-73.9857, 40.7484), 4326)::extensions.geography,
extensions.ST_SetSRID(extensions.ST_MakePoint(-118.2437, 34.0522), 4326)::extensions.geography
) AS meters_geog;
SELECT extensions.ST_Distance(
extensions.ST_SetSRID(extensions.ST_MakePoint(-73.9857, 40.7484), 4326),
extensions.ST_SetSRID(extensions.ST_MakePoint(-118.2437, 34.0522), 4326)
) AS degrees_geom_wrong_for_meters;When to reach for this: Choosing column types for new tables, debugging distance bugs, or optimizing indexes for ST_DWithin.
CREATE TABLE delivery_zones (
id serial PRIMARY KEY,
name text,
-- City-scale polygon: local UTM for accurate geometry math
zone_geom extensions.geometry(Polygon, 32618), -- UTM 18N for NYC area
-- Driver location queries: geography for meter radius from GPS
service_geog extensions.geography(Polygon, 4326)
);
-- Store both when needed: geometry for editing in local projection,
-- geography for "within 2 km of driver" queries
CREATE INDEX delivery_zones_geog_gist
ON delivery_zones USING gist (service_geog);
SELECT name
FROM delivery_zones
WHERE extensions.ST_DWithin(
service_geog,
extensions.ST_SetSRID(extensions.ST_MakePoint(-73.99, 40.75), 4326)::extensions.geography,
2000
);What this demonstrates:
geometry for city planning polygonsgeography for GPS radius filters in metersST_DWithin| Aspect | geometry | geography |
|---|---|---|
| Coordinate system | Projected (meters in plane) | WGS84 spheroid |
| Distance units | Map units (meters if projected) | Meters on spheroid |
| Performance | Faster for local areas | Slower, more accurate globally |
| Functions | Full planar suite | Subset; casts often needed |
| SRID | Must be projected for meter math | Typically 4326 |
| SRID | Name | Use |
|---|---|---|
| 4326 | WGS84 lat/lon | GPS, web maps, geography |
| 3857 | Web Mercator | Display only; poor for distance |
| 32618 | UTM 18N | NYC region planar work |
| 0 | Unknown | Avoid in production |
SELECT srid, auth_name, auth_srid, srtext
FROM spatial_ref_sys
WHERE srid IN (4326, 3857, 32618);-- Reproject geometry between SRIDs
SELECT extensions.ST_Transform(
extensions.ST_SetSRID(extensions.ST_MakePoint(-73.9857, 40.7484), 4326),
32618
);
-- Geography from geometry (4326 only for geog cast)
SELECT extensions.ST_SetSRID(extensions.ST_MakePoint(-73.9857, 40.7484), 4326)::extensions.geography;ST_Distance on 4326 geometry returns degrees. Fix: Cast to geography or transform to UTM.ST_GeomFromText('POINT(0 0)') without SRID. Fix: Typmod geometry(Point,4326) rejects wrong SRID when enforced.ST_IsValid.| Alternative | Use When | Don't Use When |
|---|---|---|
| geometry + UTM | City/county fixed region | Global roaming queries |
| geography only | Simple GPS radius apps | Heavy polygon overlay performance pain |
| Haversine in app | One-off distance | Spatial joins and indexes needed |
| Raster tiles | Display-only maps | Vector feature storage |
Stack versions: This page was written for PostgreSQL 18.4 (stable 18, maintenance 17), pgvector 0.8+, PostGIS 3.5+, pgbouncer 1.x, and Patroni 3.x.
Reviewed by Chris St. John·Last updated Jul 18, 2026