Tippecanoe CLI Fundamentals

Tippecanoe converts GeoJSON or NDJSON feature collections into Mapbox Vector Tile (MVT) tilesets packaged as MBTiles or PMTiles — the core translation step in any automated generation pipeline. This page covers the full operational sequence: environment setup, the ingest-simplify-tile-package execution model, the flag groups that govern that model, optimisation trade-offs, and the failure modes specific to CLI invocations.


Pipeline overview

The diagram below shows how Tippecanoe sits in the wider data flow. Raw geometry enters on the left; rendered tiles leave on the right through a tile server or CDN.

Tippecanoe CLI pipeline overview Data flow from GeoJSON source files through input validation, tippecanoe processing, MBTiles or PMTiles packaging, a tile server or CDN, and finally the browser map renderer. .geojson / .geoparquet validate jq / ogrinfo tippecanoe simplify · slice · pack .mbtiles / .pmtiles tile server / CDN browser

Prerequisites

System dependencies

Tippecanoe is a C++17 application. Required packages on Debian/Ubuntu:

bash
sudo apt-get install -y build-essential libsqlite3-dev zlib1g-dev

On macOS with Homebrew:

bash
brew install tippecanoe

To build from source (always produces the most recent version):

bash
git clone https://github.com/felt/tippecanoe.git
cd tippecanoe
make -j$(nproc)
sudo make install
tippecanoe --version

Supported input formats

Format Flag / method Notes
GeoJSON (RFC 7946) positional arg WGS84 (EPSG:4326) required
NDJSON positional arg one feature per line, no FeatureCollection wrapper
CSV with lat/lon --csv explicit column names required
stdin stream - combine with -P for parallel read
GeoParquet (via conversion) pipe from ogr2ogr or pyarrow see GeoParquet Input Processing

Tippecanoe assumes EPSG:4326 on input and encodes tile geometry in EPSG:3857 internally. Any other CRS must be reprojected before ingestion — a projection mismatch produces geometrically valid but geographically wrong tiles with no error message.

Environment variables

Set these before any large run to prevent silent failures:

bash
export LC_ALL=C.UTF-8
export SQLITE_TMPDIR=/mnt/fast-nvme/tippecanoe-tmp   # must have headroom ≥ 3× input file size

SQLITE_TMPDIR controls where SQLite stages intermediate B-tree data during tile packing. Default /tmp is often on a small tmpfs; redirect it to a volume with adequate I/O throughput when processing continental-scale feature collections.

Input validation

Validate GeoJSON schema and coordinate system before invoking Tippecanoe:

bash
# confirm valid FeatureCollection
jq -e '.type == "FeatureCollection" and (.features | length) > 0' input.geojson

# confirm all coordinates are finite (catches NaN/Inf from projection errors)
jq '[.features[].geometry.coordinates | .. | numbers | isnan or isinfinite] | any' input.geojson

# quick layer/schema audit
ogrinfo -al -so input.geojson

For teams managing tabular formats in object storage, GeoParquet Input Processing covers bbox spatial filtering and column pushdown before the NDJSON stream reaches Tippecanoe stdin.


Core concept: the execution model

Tippecanoe follows a four-stage deterministic pipeline that maps directly to its flag taxonomy:

text
ingest → simplify → tile → package
Stage What happens Controlling flags
Ingest Features read into SQLite scratch DB; layer names assigned -l, -L, -P, --csv
Simplify Vertex reduction per zoom level; feature dropping -S, --simplification, -r, --drop-rate, --drop-densest-as-needed
Tile Features sliced to MVT coordinate grid (4096 units/tile) -Z, -z, -B, --full-detail, --low-detail
Package Tiles written to SQLite MBTiles or individual .pbf files -o, -e, --output-to-directory, PMTiles extension

Understanding which stage a flag belongs to tells you exactly when its effect materialises and which other flags it interacts with.


Step-by-step implementation

Step 1 — Assign layers explicitly

Tippecanoe infers layer names from input filenames. In multi-layer builds that ambiguity causes hard-to-debug style mismatches. Use explicit assignment from the start:

bash
# single file, single layer
tippecanoe -o parcels.mbtiles -l parcels parcels.geojson

# multiple files → multiple named layers in one tileset
tippecanoe -o city.mbtiles \
  -L parcels:parcels.geojson \
  -L roads:roads.geojson \
  -L buildings:buildings.geojson

The layer name string maps directly to the source-layer property referenced in MapLibre GL JSON style documents. Rename a layer at the Tippecanoe step rather than patching the style.

Verify: tippecanoe-decode parcels.mbtiles 0 0 0 | jq 'keys' — layer names must match what your style expects.

Step 2 — Configure zoom range and base zoom

Define the zoom window to control output size and rendering fidelity:

bash
tippecanoe -o parcels.mbtiles -l parcels \
  -Z 10 -z 16 \
  -B 12 \
  parcels.geojson
Flag Meaning Typical value
-Z / --minimum-zoom Lowest zoom tile generated 0–6 for global layers
-z / --maximum-zoom Highest zoom tile generated 14–16 for parcel/building data
-B / --base-zoom Zoom at which all features are included without dropping 2 below max-zoom

For zoom selection guidance tied to dataset density and storage budgets, see Zoom Level Optimization Strategies.

Verify: wc -c parcels.mbtiles gives a rough size check. A z10–z16 parcel tileset for a mid-size city should land between 50 MB and 400 MB.

Step 3 — Apply geometry simplification

Tippecanoe applies Douglas-Peucker simplification to reduce vertex count at lower zooms. Two flags govern the intensity:

bash
tippecanoe -o roads.mbtiles -l roads \
  -Z 8 -z 14 \
  --simplification=2 \
  --no-simplification-of-shared-nodes \
  roads.geojson
Flag Default Effect
--simplification=N 1 Multiplies default tolerance; 2 = coarser, 0.5 = finer
--no-simplification-of-shared-nodes off Preserves shared polygon edges; prevents seams between adjacent polygons
--simplify-only-low-zooms off Restricts simplification to zooms below base-zoom

The performance trade-off between Visvalingam-Whyatt and Douglas-Peucker algorithms — and when each produces better results for administrative boundaries versus road networks — is covered in Visvalingam vs Douglas-Peucker in Tile Generation.

Verify: tippecanoe-decode roads.mbtiles 10 511 341 | jq '.features[0].geometry.coordinates | length' — compare vertex counts at z10 vs z14 to confirm simplification is active.

Step 4 — Control feature dropping to enforce the 500 KB tile budget

The Mapbox Vector Tile spec imposes no hard size limit, but browser decompression stalls and TTFB penalties become significant above 500 KB per tile. Three mutually exclusive dropping strategies:

bash
# density-aware drop (recommended for most datasets)
tippecanoe -o buildings.mbtiles -l buildings \
  -Z 12 -z 16 \
  --drop-densest-as-needed \
  --extend-zooms-if-still-dropping \
  buildings.geojson
Strategy flag Behaviour Best for
--drop-densest-as-needed Removes features from densest tiles first; preserves spatial distribution Urban point/polygon datasets
--drop-fraction-as-needed Removes a uniform percentage from every tile over budget Uniform-density global layers
--coalesce-densest-as-needed Merges adjacent same-attribute polygons before dropping Administrative boundaries, land cover

Combine --drop-densest-as-needed with --extend-zooms-if-still-dropping to avoid silently truncating high-density areas; Tippecanoe will add zoom levels until every feature fits rather than discarding data.

Verify: after build, scan for oversized tiles:

bash
sqlite3 buildings.mbtiles \
  "SELECT zoom_level, tile_column, tile_row, length(tile_data) AS bytes
   FROM tiles WHERE length(tile_data) > 512000
   ORDER BY bytes DESC LIMIT 10;"

Step 5 — Package as MBTiles or PMTiles

Choose the output container based on the downstream delivery architecture:

bash
# MBTiles — single SQLite file; suitable for martin, tileserver-gl
tippecanoe -o output.mbtiles -l parcels --force parcels.geojson

# PMTiles — cloud-optimised single file; HTTP range requests, no server
tippecanoe -o output.pmtiles -l parcels --force parcels.geojson

# individual .pbf tiles — for CDN directories or custom tile servers
tippecanoe -e ./tiles -l parcels parcels.geojson

The structural differences between the two container formats — SQLite page layout, index structure, read amplification under range requests — are covered in MBTiles Architecture and Limits.

--force skips the interactive overwrite prompt and is mandatory in any scripted or CI/CD context.

Verify: tippecanoe-decode output.mbtiles 14 8213 4950 | jq '.features | length' — confirm feature counts at the target zoom tile.


Optimization knobs

Three tuning dimensions dominate production Tippecanoe runs. Adjust them in order: zoom range first, then simplification, then detail level.

Parameter Flag Lower value Higher value Primary trade-off
Simplification scale --simplification=N Finer geometry, larger tiles Coarser geometry, smaller tiles Tile size vs rendering fidelity
Tile detail grid --full-detail=N More precise coordinates Larger tile payloads Coordinate precision vs payload size
Drop rate --drop-rate=N More features at lower zooms Fewer features at lower zooms Visual density vs tile budget at low zoom

The detail grid defaults to 12 bits (4096 units per tile edge). Reducing --full-detail to 10 (1024 units) cuts geometry size noticeably with minimal visual impact at z10 and below.

For a complete flag inventory with interaction effects between --drop-densest-as-needed, --coalesce-densest-as-needed, and --no-simplification-of-shared-nodes, see Essential Tippecanoe Flags for Production Builds.


Integration with adjacent pipeline stages

Upstream: attribute filtering before tiling

Carrying unused properties into the tile increases payload with no rendering benefit. Strip attributes at the Tippecanoe stage rather than in a pre-processing step:

bash
tippecanoe -o parcels.mbtiles -l parcels \
  -y parcel_id -y owner_name -y land_use_code \
  --drop-densest-as-needed \
  parcels.geojson

-y whitelists properties to retain; all others are dropped. For complex filtering logic — retaining different attributes per zoom level or per geometry type — see Attribute Filtering Rules and specifically Dropping Unused Attributes to Reduce Tile Size.

Downstream: MBTiles to tile server

An MBTiles file is an SQLite container that tile servers such as martin or tileserver-gl serve over HTTP. The handoff is a single path reference:

bash
martin --config config.yaml   # config references output.mbtiles path

PMTiles files skip the server entirely — a JavaScript client fetches byte ranges directly from R2 or S3 storage. For style-side wiring of vector tile sources to MapLibre GL layer definitions, the source-layer value must exactly match the -l name used at tile generation time.

Python subprocess wrapper

For teams embedding Tippecanoe in a Python orchestration layer:

python
import subprocess
import sys
from pathlib import Path

def run_tippecanoe(
    input_path: str,
    output_path: str,
    layer: str,
    min_zoom: int = 10,
    max_zoom: int = 16,
) -> None:
    cmd = [
        "tippecanoe",
        f"--output={output_path}",
        f"--layer={layer}",
        f"--minimum-zoom={min_zoom}",
        f"--maximum-zoom={max_zoom}",
        "--drop-densest-as-needed",
        "--extend-zooms-if-still-dropping",
        "--no-simplification-of-shared-nodes",
        "--force",
        input_path,
    ]
    result = subprocess.run(cmd, capture_output=True, text=True)
    if result.returncode != 0:
        print(f"tippecanoe failed:\n{result.stderr}", file=sys.stderr)
        sys.exit(1)
    if not Path(output_path).exists():
        print("Output file not created — check disk space and SQLITE_TMPDIR", file=sys.stderr)
        sys.exit(1)

Capture stderr explicitly: Tippecanoe writes Dropping features at zoom X warnings there, not to stdout. These warnings are the earliest signal of a tile-budget problem.


Troubleshooting

1. Error: No room left / build aborts mid-run

Diagnosis:

bash
df -h $SQLITE_TMPDIR   # check available space
du -sh input.geojson   # rule of thumb: temp space ≥ 3× input

Fix: Redirect SQLITE_TMPDIR to a volume with headroom, or split the input spatially:

bash
ogr2ogr -spat -80 25 -70 35 southeast.geojson input.geojson

2. Tiles render correctly at z14 but features vanish at z10

Cause: --drop-densest-as-needed is dropping features at lower zooms; --base-zoom is too high. Diagnosis:

bash
tippecanoe-decode output.mbtiles 10 256 256 | jq '.features | length'
tippecanoe-decode output.mbtiles 14 4096 4096 | jq '.features | length'

Fix: Lower --base-zoom or add --extend-zooms-if-still-dropping so Tippecanoe retains features rather than discarding them.

3. Adjacent polygon seams visible in MapLibre GL JS

Cause: Shared-node simplification is misaligning polygon edges. Fix: Add --no-simplification-of-shared-nodes. If seams persist, also set --buffer=8 (default 4) to widen the tile overlap buffer:

bash
tippecanoe -o zoning.mbtiles -l zoning \
  --no-simplification-of-shared-nodes \
  --buffer=8 \
  zoning.geojson

4. tippecanoe: GeoJSON does not begin with a FeatureCollection on piped NDJSON

Cause: Piping a full GeoJSON FeatureCollection to stdin instead of a feature-per-line NDJSON stream. Fix:

bash
# correct: unwrap features to NDJSON
jq -c '.features[]' input.geojson | tippecanoe -o output.mbtiles -l layer -

5. Oversized tiles at max zoom despite --drop-densest-as-needed

Cause: --no-tile-size-limit left in a debug invocation, or feature geometries have thousands of vertices that survive simplification. Diagnosis:

bash
sqlite3 output.mbtiles \
  "SELECT zoom_level, count(*) AS n_tiles, max(length(tile_data)) AS max_bytes
   FROM tiles GROUP BY zoom_level ORDER BY zoom_level;"

Fix: Increase --simplification for the offending zoom range, or pre-simplify with ogr2ogr -simplify 0.0001 simplified.geojson input.geojson.


Further Reading

Essential Tippecanoe Flags for Production Builds — a focused reference for the six flags that form a reliable production baseline (--drop-densest-as-needed, --extend-zooms-if-still-dropping, --maximum-zoom, --coalesce-densest-as-needed, --no-simplification-of-shared-nodes, --force), covering interaction effects and CI/CD validation steps.

Controlling Tile Size with Drop and Coalesce Flags — how --drop-densest-as-needed, --coalesce-smallest-as-needed, -r/--drop-rate, and --extend-zooms-if-still-dropping decide which features are shed to keep every tile under 500 KB.


Up to parent

Automated Generation Pipelines with Tippecanoe — the parent section covering the full Tippecanoe-based pipeline from input pre-processing through tile delivery.


Next reading Controlling Tile Size with Drop and Coalesce Flags Next reading Essential Tippecanoe Flags for Production Builds