Overzooming vs Generating Higher Max-Zoom Tiles

Overzoom reuses the deepest generated tile at higher view zooms — it costs nothing to build and stores nothing extra, but it adds no new detail; the same geometry is just scaled up. Generating a higher max-zoom adds real detail at each new level, at the price of roughly 4× more tiles per zoom step. Choose overzoom when the deepest data you have is already dense enough to look sharp scaled; build deeper only where new zooms reveal features that were dropped or simplified away.

When to Use Each

Prefer overzoom when your source data has no meaningful detail beyond the zoom you already generate. A road network built to z14 looks perfectly crisp at z16–z18 scaled up, because roads at street level are not more detailed than they were two zooms shallower. Overzoom is also the right call when storage or build time is the binding constraint and the deepest tiles are already near the 500 KB budget — pushing deeper would multiply cost for little visual gain.

Generate a higher max-zoom when features are being dropped or coalesced at your current deepest zoom and users need to see them. Dense point data (address points, individual trees, parcel corners) genuinely carries more information the further you zoom in; if tippecanoe is shedding features to stay under budget at z14, building z15–z16 gives those features room to appear. The break-even is entirely about whether deeper tiles would contain anything the shallower tile does not. Picking that ceiling for real datasets is worked through in calculating optimal max-zoom for urban datasets.

Specification Detail

Two different “maxzoom” values govern this behavior, and conflating them is the usual source of blank high-zoom maps:

Setting Where it lives What it controls
Tileset maxzoom tippecanoe -z (baked into the archive metadata) The deepest zoom for which tiles are actually generated and stored
Source maxzoom The vector source in the MapLibre style JSON The zoom above which the client stops requesting new tiles and overzooms the deepest one it has

The relevant tippecanoe flags:

Flag Meaning
-z / --maximum-zoom Highest zoom to generate tiles for
-Z / --minimum-zoom Lowest zoom to generate tiles for
-zg Auto-choose maxzoom from feature density
--extend-zooms-if-still-dropping Keep adding deeper zooms until no features are dropped for size

The cost of raising -z is geometric: the slippy-map grid has 4^z tiles at zoom z, so each additional zoom level roughly quadruples the tile count for the covered area. Going from z14 to z16 is not 15% more tiles — it is close to 16× more tiles in fully populated regions.

Overzoom is enabled by the source maxzoom in the style, not by anything in the tiles. When the map view exceeds the source maxzoom, MapLibre takes the deepest available tile and scales its vector geometry to fill the higher zoom, so lines and fills stay crisp (they are re-rasterized from vectors) even though no new features appear.

Production Command

Build to a deliberate max-zoom, then declare a higher source maxzoom in the style so MapLibre overzooms above it:

bash
# Generate tiles only to z14; let clients overzoom to z18 in the browser.
# --extend-zooms-if-still-dropping bumps maxzoom only where features are
# still being dropped for size, so you don't blindly generate deep tiles.
tippecanoe \
  --output=dist/roads.pmtiles \
  --layer=roads \
  --minimum-zoom=5 \
  --maximum-zoom=14 \
  --extend-zooms-if-still-dropping \
  --drop-densest-as-needed \
  --force \
  src/roads.geojson

pmtiles show dist/roads.pmtiles
# Note the reported max_zoom — that is the tileset maxzoom.
javascript
// Source maxzoom is 14 (matches the tileset). MapLibre requests z14 tiles
// for any view from z14 up to z22 and scales them — this is overzoom.
const style = {
  version: 8,
  sources: {
    roads: {
      type: "vector",
      url: "pmtiles://https://cdn.example.com/tiles/v1/roads.pmtiles",
      maxzoom: 14,          // <-- enables overzoom above z14
    },
  },
  layers: [
    { id: "roads", type: "line", source: "roads", "source-layer": "roads" },
  ],
};

Setting the source maxzoom to the tileset’s actual deepest zoom is what makes overzoom work: MapLibre stops asking for tiles that do not exist and scales the z14 tile instead.

Interaction Effects

With drop and coalesce flags. Whether you need a higher max-zoom is largely decided by how aggressively features are being shed at your current deepest zoom. --drop-densest-as-needed and --coalesce-densest-as-needed remove or merge features to hold the 500 KB budget; if they are firing hard at z14, that is the signal that deeper zooms would carry information overzoom cannot reproduce. Tuning that budget is covered in controlling tile size with drop and coalesce flags. Overzoom, by contrast, never recovers a dropped feature — it can only scale what survived into the deepest tile.

With the per-tile size budget. Building deeper spreads the same features across more tiles, which usually lowers per-tile size at high zoom (fewer features land in each tile as the grid subdivides). So generating a higher max-zoom can relieve size pressure that dropping was masking — at the cost of many more tiles overall. Overzoom keeps tile count flat but does nothing for a deepest tile that is already overfull.

With zoom-dependent styling. Interpolated line widths, symbol sizes, and filter thresholds keyed on view zoom continue to work under overzoom because they respond to the view zoom, not the tile zoom. A ["interpolate", ["linear"], ["zoom"], ...] expression keeps widening roads as the user zooms into overzoomed tiles, so the map still feels responsive even though the underlying geometry is fixed. This ties into broader map styling and layer synchronization practice, where styling does the perceptual work that extra tile detail otherwise would.

Performance Impact

The trade is storage and build time against detail. Overzoom is free on both axes: zero extra tiles, zero extra build time, and the deepest tile you already ship does double duty for every higher view zoom. Its cost is purely visual — no feature that was dropped or simplified at the deepest generated zoom can reappear.

Generating a higher max-zoom is expensive in a compounding way. Each additional zoom roughly quadruples tile count for populated areas, so both archive size and build wall-clock climb steeply: extending a city-scale dataset from z14 to z16 can multiply tile count by an order of magnitude and lengthen the tippecanoe run proportionally. Per-tile size at the new deepest zoom is often smaller than at the previous ceiling, because features spread across the finer grid — but you pay for that with far more tiles to store and serve. The right ceiling is the shallowest zoom at which no meaningful detail is still being dropped.

Common Mistakes

Style source maxzoom higher than the tileset maxzoom with no overzoom fallback. If the style declares maxzoom: 16 but the archive only holds tiles to z14, MapLibre requests z15 and z16 tiles that do not exist and renders nothing above z14. Symptom: the map goes blank when you zoom past the real ceiling. Fix: set the source maxzoom to the tileset’s actual deepest zoom so MapLibre overzooms instead of requesting missing tiles.

bash
# Confirm the real ceiling, then match it in the style source
pmtiles show dist/roads.pmtiles | grep -i "max_zoom"
# Set source maxzoom in the style to exactly this value.

Generating z18 everywhere and exploding storage. Building a deep max-zoom across an entire global dataset because a few dense downtowns need it multiplies tiles for oceans and farmland that hold no extra detail. Symptom: an archive many times larger than expected and build times in hours. Fix: cap the base build at a sensible zoom and use --extend-zooms-if-still-dropping so extra depth is added only where features are still being dropped, not uniformly.

Expecting new detail from overzoom. Overzoom scales existing geometry; it cannot invent features that were never encoded. Symptom: you zoom in expecting individual buildings and see only the coarse shapes from the deepest generated tile, enlarged. Fix: if that detail is required, generate a higher max-zoom for the affected area — no source-side setting will conjure it from a shallower tile.


Parent: Zoom Level Optimization Strategies