Configuration Reference

March 13, 2026 · View on GitHub

tilefeed reads a TOML configuration file (default: config.toml). All fields can be overridden with environment variables using the TILES_ prefix and __ as section separator.

Environment Variables

export TILES_DATABASE__HOST=db.example.com
export TILES_DATABASE__PORT=5432
export TILES_DATABASE__USER=myuser
export TILES_DATABASE__PASSWORD=secret
export TILES_DATABASE__DBNAME=geodata

You can also use a .env file in the project directory.

Full Config Example

# Path to Tippecanoe binary (default: "tippecanoe", resolved via PATH)
# tippecanoe_bin = "/usr/local/bin/tippecanoe"

# Path to ogr2ogr binary (default: "ogr2ogr", resolved via PATH)
# ogr2ogr_bin = "/usr/local/bin/ogr2ogr"

[database]
host = "localhost"
port = 5432
user = "postgres"
password = "postgres"
dbname = "geodata"
pool_size = 4

[updates]
debounce_ms = 200
worker_concurrency = 8

[serve]
host = "0.0.0.0"
port = 3000
cors_origins = ["http://localhost:8080"]

[publish]
backend = "none" # none | local | s3 | mapbox | command
publish_on_generate = true
publish_on_update = true

# Source with multiple layers
[[sources]]
name = "basemap"
mbtiles_path = "./basemap.mbtiles"
min_zoom = 0
max_zoom = 14
generation_backend = "tippecanoe" # tippecanoe | gdal | native

[sources.tippecanoe]
drop_densest_as_needed = true
no_tile_size_limit = true

[[sources.layers]]
name = "buildings"
schema = "public"
table = "buildings"
geometry_column = "geom"
id_column = "id"
srid = 4326
properties = ["name", "type", "height"]
filter = "type != 'demolished'"
simplify_tolerance = 0.00001
generate_label_points = true
generate_boundary_lines = true

# Exclude heavy properties at low zooms
[[sources.layers.property_rules]]
below_zoom = 8
exclude = ["description", "metadata"]

[[sources.layers.property_rules]]
below_zoom = 5
exclude = ["type", "height"]

[[sources.layers]]
name = "roads"
table = "roads"
geometry_column = "geom"
id_column = "id"
srid = 4326
properties = ["name", "class"]
simplify_tolerance = 0.00001

Section Reference

[database]

FieldTypeRequiredDescription
hoststringyesPostgreSQL host
portintyesPostgreSQL port
userstringyesDatabase user
passwordstringyesDatabase password
dbnamestringyesDatabase name
pool_sizeintnoConnection pool size

[updates]

FieldTypeDefaultDescription
debounce_msint200Debounce window for batching notifications
worker_concurrencyint8Max concurrent tile regeneration workers

[serve]

FieldTypeDefaultDescription
hoststring"127.0.0.1"HTTP server bind address
portint3000HTTP server port
cors_originsstring[]["*"]Allowed CORS origins. Omit or empty for wildcard.

[publish]

FieldTypeDefaultDescription
backendstring"none"none, local, s3, mapbox, command
destinationstringFile path (local) or S3 URI (s3)
commandstringShell command (command backend)
argsstring[]Extra args for command backend
mapbox_tileset_idstringusername.tileset for Mapbox uploads
mapbox_tokenstringMapbox secret token with uploads:write
publish_on_generatebooltruePublish after full generation
publish_on_updatebooltruePublish after incremental updates

[[sources]]

FieldTypeRequiredDescription
namestringyesSource identifier
mbtiles_pathstringyesOutput MBTiles file path
min_zoomintyesMinimum zoom level
max_zoomintyesMaximum zoom level
generation_backendstringno"tippecanoe" (default), "gdal", or "native"

[[sources.layers]]

FieldTypeRequiredDescription
namestringyesLayer name (must match trigger argument)
schemastringnoDatabase schema (default: "public")
tablestringyesSource table name
geometry_columnstringnoGeometry column (default: "geom")
id_columnstringnoFeature ID column
sridintnoSRID (default: 4326)
propertiesstring[]noProperties to include in tiles
filterstringnoSQL WHERE clause to filter features
simplify_tolerancefloatnoDouglas-Peucker tolerance in degrees (scaled per zoom)
generate_label_pointsboolnoGenerate {name}_labels centroid layer
generate_boundary_linesboolnoGenerate {name}_boundary polyline layer

[[sources.layers.property_rules]]

FieldTypeDescription
below_zoomintZoom threshold
excludestring[]Properties to exclude below this zoom

[webhook]

FieldTypeDefaultDescription
urlsstring[][]Webhook endpoint URLs to receive HTTP POST notifications
secretstringHMAC-SHA256 signing secret. When set, requests include X-Tilefeed-Signature: sha256=... header
cooldown_secsintTrailing-edge throttle window in seconds. Events are accumulated per source and sent as one aggregated notification when the window expires. Also applies to SSE.
timeout_msint5000HTTP request timeout per webhook call
retry_countint2Number of retries with exponential backoff on failure
on_generatebooltrueSend webhook after full generation completes
on_updatebooltrueSend webhook after incremental tile updates

Example:

[webhook]
urls = ["https://example.com/hooks/tilefeed"]
secret = "my-signing-secret"
cooldown_secs = 300  # aggregate events for 5 minutes
on_generate = true
on_update = true

The webhook payload is a JSON object with an event field ("generate_complete" or "update_complete"). The update_complete payload includes max_zoom so frontends can invalidate overzoomed tile views (tiles rendered beyond the source's max zoom level).

[sources.tippecanoe]

See Tippecanoe Settings.

Generation Backends

Tippecanoe (default)

Requires the Tippecanoe binary. Exports PostGIS layers as GeoJSON, pipes through Tippecanoe, and produces optimized MBTiles. Best for production with large datasets.

GDAL

Requires ogr2ogr from GDAL. Exports via OGR and converts to MBTiles. Useful when Tippecanoe isn't available.

Native

No external dependencies. Uses tilefeed's built-in Rust MVT encoder to generate tiles directly from PostGIS queries. Supports geometry simplification and derived layers. Best for development or environments where installing external tools is impractical.

[[sources]]
name = "parks"
mbtiles_path = "./parks.mbtiles"
min_zoom = 0
max_zoom = 8
generation_backend = "native"