Plan a Self-Hosted Web Mapping Stack
Plan a web map with MapLibre, PMTiles or PostGIS and Martin. Understand static versus dynamic tiles, hosting responsibilities, search and routing.
By GisForWeb · Updated
Choose the tile delivery model from your update requirements. For data published as periodic snapshots, a tile archive such as PMTiles can keep delivery simple. For frequently changing records or tiles generated from database queries, evaluate PostGIS with a tile server such as Martin. Both can feed a browser renderer such as MapLibre GL JS.
Self-hosting gives you responsibility for the components you operate. It does not automatically replace address search, directions, traffic or a commercial provider’s place database. Decide which capabilities your application actually needs before assembling the stack.
Draw the boundaries first
A useful architecture separates four jobs: preparing data, storing or publishing it, delivering it to a client, and rendering it. A fifth layer is your own application logic, including authentication and editing.
For a public thematic map, that could mean a source dataset, a generated tile archive, object storage and a browser map. For an operational application, it might mean an import process, a spatial database, an API and a tile server. Keep this list explicit so that a missing service does not surface late in development.
Option one: static tile archives
PMTiles packages a tiled dataset in one archive. Clients can read selected portions using HTTP range requests. That makes it useful for publishing snapshots through compatible storage and delivery infrastructure. The format is read-only: changing a dataset means rebuilding or replacing the archive, rather than updating a record in place.
A starting architecture is source data → tile generation → PMTiles archive → storage/CDN → browser map. Evaluate Tippecanoe or Planetiler against the source format and processing job; they are different tools, not interchangeable steps in every pipeline.
Use versioned archive names when publishing a new snapshot. This lets you test a new file before switching the map and makes rollback easier. Verify range requests and cross-origin access from your actual website. Include the style, glyphs, sprites and attribution in your deployment checklist, since a tile file alone is not a complete styled map.
Option two: database-backed tiles
PostGIS adds spatial storage, indexing and queries to PostgreSQL. It can serve as the system of record when your application needs to change and query features. Martin can expose tile sources from PostGIS tables or functions as well as tile archives, and its documentation explains source configuration and supporting map resources.
A starting architecture is application/import process → PostGIS → Martin → browser map. Your application API remains responsible for authorizing edits and other business operations. Plan connection limits, query cost, backups and how cached tiles become fresh after a change.
Keep a representative slow query in your evaluation dataset. Dense urban features, complicated polygons and broad zoom levels can behave differently from a sparse demonstration layer. Review database access and exposed sources before allowing public requests.
Combine static and dynamic layers when useful
You do not need one delivery method for every layer. A stable basemap can use a snapshot, while an operational overlay comes from the database. The main question is what must update, and how quickly the change must reach a visitor.
Write an explicit freshness target for each layer. A boundary map might be refreshed monthly; a live asset layer may need a much shorter interval. Then test the whole path from data change to visible update, including caches.
Add search and routing deliberately
Address lookup and route calculation are separate capabilities. Tools in the geocoding directory and routing directory can help you evaluate those pieces. Test coverage and output quality using locations and travel modes relevant to your users.
OpenStreetMap’s public infrastructure is not an unlimited hosting backend for applications. Its tile usage policy specifies conditions for the public tile service. The public Nominatim endpoint has its own usage policy, including an absolute maximum of one request per second and restrictions on autocomplete. Hosting software yourself and calling a project’s public endpoint are different operational choices.
Estimate the cost of the whole system
Budget for data preparation, storage, delivery traffic, request volume, database capacity, monitoring and maintenance time. A low software license cost says little about total operating cost. A hosted service may be sensible for a capability your team cannot support reliably.
Before choosing an architecture, publish a small representative dataset and measure a realistic session: initial map load, several pans, zoom changes and a search. Record the requests and transferred bytes, then evaluate them against the hosting provider’s current pricing. We have not benchmarked these architectures or estimated a universal break-even point.
A practical launch checklist
- Confirm attribution and permissions for every dataset and map asset.
- Test the map from the production origin, including range requests and cross-origin access.
- Verify that private data cannot be reached through public tile or data endpoints.
- Exercise backups, a failed import and rollback to the previous dataset.
- Monitor tile errors and response times, then test a slow mobile connection.
- Assign an owner to data freshness and software updates.
For the browser layer, use the JavaScript mapping library guide. Browse the self-hosted tools collection when you are ready to compare individual components.