Guides

Hot-Reload Configuration

Reload tile sources and styles without restarting the server

tileserver-rs supports reloading configuration at runtime without dropping any in-flight requests. Two mechanisms are available: SIGHUP signal and an admin HTTP endpoint.

SIGHUP (Unix)

Send SIGHUP to reload configuration from the original config file:

kill -HUP $(pgrep tileserver-rs)

The server re-reads the config, rebuilds sources/styles/renderer, and atomically swaps the application state. Requests in progress complete against the old state; new requests use the new state.

Admin Endpoint

Enable the admin server by setting admin_bind in your config:

[server]
host = "0.0.0.0"
port = 8080
# admin_bind = "127.0.0.1:9099"

The default value 127.0.0.1:0 disables the admin server. Set a real port to enable it.

POST /__admin/reload

Trigger a reload via HTTP:

curl -X POST http://127.0.0.1:9099/__admin/reload

Response:

{
  "ok": true,
  "reloaded": true,
  "config_hash": "a1b2c3...",
  "loaded_at_unix": 1700000000,
  "loaded_sources": 3,
  "loaded_styles": 2,
  "renderer_enabled": true,
  "version": "2.7.1"
}

Force Reload

By default, reload is skipped if the config file hasn't changed (hash comparison). Use ?flush=true to force a full reload:

curl -X POST http://127.0.0.1:9099/__admin/reload?flush=true

No-Op Response

When the config hash matches the current state:

{
  "ok": true,
  "reloaded": false,
  "config_hash": "a1b2c3...",
  "loaded_at_unix": 1700000000,
  "loaded_sources": 3,
  "loaded_styles": 2,
  "renderer_enabled": true,
  "version": "2.7.1"
}

Runtime Metadata

The /ping endpoint on the main server returns current runtime state:

curl http://localhost:8080/ping
{
  "status": "ok",
  "config_hash": "a1b2c3...",
  "loaded_at_unix": 1700000000,
  "loaded_sources": 3,
  "loaded_styles": 2,
  "renderer_enabled": true,
  "version": "2.7.1"
}

Use this for health checks, monitoring dashboards, or verifying that a reload took effect.

What Gets Reloaded

ReloadedNot Reloaded
Tile sources (PMTiles, MBTiles, PostgreSQL)Server host/port
Map stylesAdmin bind address
Native rendererCORS configuration
Fonts/files directoriesTelemetry settings
PostgreSQL connection pools
In-memory tile cache (dropped with old state)

Host, port, and admin bind require a full restart since they involve bound TCP listeners.

PostgreSQL Sources

Reload fully rebuilds PostgreSQL connection pools and tile caches:

ChangeReload needed?
Data changes (new rows, updated geometries)No — queries run live per request
Function changes (CREATE OR REPLACE FUNCTION)No — functions are called per request
Config changes (connection string, add/remove source)Yes
Schema changes (new table, altered columns)Yes
Connection pool stale (server restart, failover)Use ?flush=true to force new pool

Between reloads, the in-memory tile cache (moka) serves cached tiles until TTL expires. On reload, the cache is dropped entirely since a new SourceManager is created.

How It Works

The server uses ArcSwap for wait-free atomic state replacement. On reload:

  1. Config file is re-read and hashed
  2. If hash matches current state, reload is skipped (unless flush=true)
  3. New sources, styles, and renderer are built from the updated config
  4. The new state is atomically swapped in (~1ns)
  5. Old state is dropped once all in-flight requests complete

If building the new state fails (invalid config, unreachable sources), the old state is preserved and an error is returned.

Copyright © 2026