Skip to content

PostGIS Vector Tile Server in Rails

Future tutorial: PostGIS Vector Tile Server in Rails

A briefing note on a possible follow-up tutorial to the Vera Dispatch Manager. Captured during Module 4 planning when the topic of vector tiles came up — they’re the wrong tool for a regional dispatch app but a genuinely interesting topic in their own right.

The premise

Build a Rails app whose primary purpose is serving vector tiles backed by PostGIS. Different shape of project from the dispatch deck — instead of “map as application UI,” this is “map as data product.”

Why it’s a separate tutorial

The dispatch deck is a consumer of spatial data. Small datasets, role-scoped, served as GeoJSON. The architecture concerns are around how spatial data integrates with a Rails app’s normal request/response cycle.

A vector tile server is a different kind of app. The architecture concerns are completely different:

  • Performance per request matters more than features. A tile request needs to return in tens of milliseconds because a user panning a map fires hundreds of them.
  • Caching is central, not optional. The same z/x/y for the same dataset returns the same bytes; caching layers (HTTP, CDN, Redis) become essential infrastructure rather than nice-to-haves.
  • The dataset is the product. You’re serving spatial data to other applications, not consuming it within one app.
  • The query patterns are different. Almost every query is “give me everything in this bounding box at this resolution” — heavy spatial filtering, server-side simplification, geometry encoding.
  • Scale is real. This is where you actually do think about millions of features, because that’s the use case.

Trying to teach both patterns in one tutorial would muddy both. They share PostGIS as the backbone but otherwise diverge from the first lesson onward.

What the tutorial could cover

The teaching arc would touch:

  • Tile coordinate math. What z/x/y means, the ST_TileEnvelope function for converting tile coordinates to bounding boxes, why the math works.
  • ST_AsMVT and ST_AsMVTGeom — the PostGIS functions that produce binary tile output. Geometry simplification, attribute clipping, encoding details.
  • Multi-layer tiles. A single tile can contain multiple feature layers (boundaries, roads, points-of-interest). How to compose them.
  • Caching architecture. Rails cache, HTTP Cache-Control, ETags, Cloudflare or similar CDN setup, cache key invalidation strategies.
  • Style specifications. MapLibre style JSON, the layer/source/paint model, how styles connect to tile layers.
  • Performance profiling. Real benchmarks, query plans, where the bottlenecks actually live.
  • Static vs on-demand generation. When to pre-generate (tippecanoe for static datasets), when to generate from the database (live data), the trade-offs.

Spinoffs from there

A few directions that flow naturally:

Build your own basemap. Take OpenStreetMap’s data (an osm.pbf file), import it into PostGIS with osm2pgsql, serve as vector tiles, render with MapLibre using a custom style. End result: a self-hosted basemap. Removes dependence on external tile providers.

Spatial data API. Beyond tiles — a JSON API for spatial queries. “Find features within X polygon,” “find nearest N to point Y,” “aggregate counts by region.” Rails as a spatial query backend that other apps consume.

Embedding maps in static sites. Tippecanoe-generated tiles served from S3 or Cloudflare R2, MapLibre rendering in a static page. No backend at all. Different architecture, same concepts.

Real-time spatial events. Marrying the dispatch deck’s pattern (map-as-application) with vector tiles for the heavy backdrop and ActionCable for live updates. Probably the most natural “what comes after the dispatch tutorial?” project.

How it relates to the dispatch deck tutorial

The dispatch deck teaches: map-as-application. A Rails app where maps are an essential UI element and spatial queries support normal CRUD operations.

A vector tile server teaches: map-as-data-product. A Rails app whose primary output is spatial data for other applications to consume.

These are genuinely different architectural patterns. Both are useful; both are real things people build. The dispatch deck creates a great audience for a tile-server tutorial — readers finish having understood Phlex, MapLibre, PostGIS-with-Rails, GeoJSON, and spatial queries. They’re then perfectly positioned to take the next step into “what if maps were the product?”

Worth flagging in the dispatch deck appendix

The dispatch deck tutorial’s “where to go next” section should mention vector tile servers as a recommended direction. Brief treatment — maybe a paragraph naming ST_AsMVT, tippecanoe, and MapLibre style specifications as the relevant technologies, with a pointer to “if you’d like to learn this, here’s a future tutorial shape we have in mind.”

Status

Idea captured, no action. Revisit after the dispatch deck tutorial is published. If reader interest signals demand for the next-step tutorial, this is the candidate to build.