DEV Community

Cover image for "Find What's Nearby" Doesn't Need a Separate GIS Stack
Chizee
Chizee

Posted on Originally published at omenabyte.com

"Find What's Nearby" Doesn't Need a Separate GIS Stack

Store finders, delivery radius checks, geofencing — any "what's near this point" feature looks like it needs specialized spatial infrastructure. Done naively (raw coordinate math checked against every row), it genuinely does fall over past a few thousand points. Done with PostGIS, it's an index like any other.

PostGIS isn't a lightweight workaround, either — it's the de facto industry standard most dedicated GIS tooling gets benchmarked against.

The setup

CREATE EXTENSION IF NOT EXISTS postgis;

CREATE TABLE coffee_shops (
  id        bigserial PRIMARY KEY,
  name      text,
  location  geography(Point, 4326)
);

CREATE INDEX idx_coffee_shops_location
  ON coffee_shops USING GIST (location);
Enter fullscreen mode Exit fullscreen mode

A GiST index draws simple bounding boxes around your geometries first, so Postgres can instantly discard millions of points that obviously aren't close, before running the precise (and expensive) distance math on the small set that remain.

The query

SELECT name FROM coffee_shops
WHERE ST_DWithin(
  location,
  ST_SetSRID(ST_MakePoint(-122.42, 37.77), 4326)::geography,
  1000  -- meters
);
Enter fullscreen mode Exit fullscreen mode

The trap that's actually worth knowing about

I went looking for the "obvious" PostGIS gotcha (mismatched SRIDs throwing hard errors) and, tested directly against a live PostGIS instance, that specific fear turned out to be overstated — casting straight to geography without an explicit SRID mostly just works, since geography only ever supports SRID 4326 anyway.

The trap that's real and far more dangerous: PostGIS does not validate that your coordinates are actually in range. Feed it projected/UTM meters where it expected longitude/latitude degrees, and it silently coerces the values into valid range with nothing but a quiet NOTICE — no error, no loud failure, just garbage coordinates that look plausible until someone notices the map is wrong. If you're piping coordinates in from another system, double-check the units before they ever hit this table.

Why this beats a separate GIS engine

  • It's the standard, not a substitute — documentation and tooling assume PostGIS by default.
  • Spatial joins work against ordinary relational tables in the same query.
  • Decades of production hardening, not a new or experimental extension.

Where dedicated GIS tooling still wins

Heavy cartographic rendering or raster analysis — satellite imagery, terrain modeling — which is a genuinely different workload from querying point and polygon data. For "what's near this address," you likely already have everything you need.


This is one of eight infrastructure swaps in Just Use Postgres, a 24-page field manual on replacing MongoDB, Redis, Elasticsearch, Pinecone, and more with the database you're probably already running. Every recipe in it — including this one — was run against a live Postgres instance before it went in the book.

👉 Get the field manual — launch price $14 instead of standing up a tile server for a distance query: https://payhip.com/omenabyte
🐳 Or take the $24 bundle with the full docker-compose up starter repo — all 8 modules as tested, runnable migrations + seed data: https://4693433176360.gumroad.com/

Read this on omenabyte.com → https://omenabyte.com/blog/replace-gis-tools-with-postgis

Top comments (0)