MVT: Mapbox Vector Tile — Vector Tile Standard for Web Maps
MVT (Mapbox Vector Tile) is an open specification for a binary vector-tile format, published by Mapbox in 2014 and now, ten years on, the de-facto industry standard for web maps. A single MVT tile is a .pbf file (Protocol Buffers, typically gzip-wrapped) holding several layers of geometries and attributes, with coordinates expressed in a tile-local 0..4096 grid. MVT powers MapLibre GL JS, Mapbox GL JS, OpenLayers, the Mapbox iOS/Android SDKs and dozens of servers (tippecanoe, tegola, t-rex, pg_tileserv, Martin). On osm2cdr.ru MVT is the natural intermediate for cloud-native exports: the user picks a bbox, the backend pulls OSM features from PostGIS, pushes them through tippecanoe and packages the result either as PMTiles (single file, range requests), MBTiles (SQLite container) or a file-system hierarchy of z/x/y.pbf.

History: from raster tiles to vector
By 2013 web cartography lived entirely on raster tile pyramids — 256×256 PNGs over XYZ or TMS, server-side tile generators (Mapnik, TileMill, MapProxy) and heavy offline pyramids running into hundreds of gigabytes. The downsides were obvious: every new style or palette required regenerating the whole pyramid; Retina devices and large monitors made the blur visible; interactivity (hover, click-to-select on an individual object) was technically impossible — a PNG doesn't know where the building ends and the park begins.
In 2014 Mapbox published Vector Tile Specification 1.0 (CC-BY 3.0, at github.com/mapbox/vector-tile-spec) — an open description of a binary format built on Google Protocol Buffers. The idea was simple: instead of a raster image, the tile carries the source geometries (points, lines, polygons) plus their attributes; styling moves entirely to the client (Mapbox GL JS, later MapLibre); the same tileset can render under any style — light, dark, satellite-hybrid, custom — without regenerating the server layer. By 2016 the OpenStreetMap Foundation launched its own vector tiles based on MVT, and the format was firmly established as the industry standard.
Between 2020 and 2024 a rich ecosystem grew around MVT: tippecanoe (Mapbox, open-source, builds MBTiles from GeoJSON); tegola and t-rex (Go and Rust servers); pg_tileserv and Martin (direct MVT served from PostGIS); PMTiles (Protomaps) — a single-file container with HTTP range requests that lets you host tiles directly on S3 or GitHub Pages, no tile-server required.
Inside MVT: protobuf, layers and tile-local coordinates
The spec describes a tile as a protobuf Tile message containing an array of Layer entries. Each layer has a name (e.g. "roads", "buildings", "poi"), an extent (usually 4096 — the size of the virtual coordinate grid), a shared dictionary of attribute keys (keys) and values (values, typed string/float/int/bool), and an array of features — geometry plus references into the keys/values dictionary.
Coordinates are stored tile-local: after reprojection to Web Mercator (EPSG:3857) and scaling to extent, each geometry is expressed as a sequence of 32-bit varint commands (MoveTo, LineTo, ClosePath) with delta encoding — giving compact serialization, especially for long lines and large polygons. The client, knowing the zoom and the tile coordinates (z/x/y), trivially projects points back to lon/lat.
On top of protobuf, gzip compression is usually applied either at the HTTP layer or inside the MBTiles container. A typical OSM tile at zoom 14 is 10–50 KB; a dense city center can run to 200–300 KB; an empty ocean is a few bytes. A single tile can hold tens of layers, and layers can differ per zoom level (e.g. only country boundaries at z=4, but buildings, POI and address points at z=14).
A key property: MVT is a transport format, not a source of truth. An MVT tile is already a clipped and simplified view of the source geometries — tippecanoe and similar tools apply Douglas-Peucker simplification, drop small features at low zooms, and clip to the tile boundary with a small buffer (typically 4–64 px) so that lines straddling two tiles render seamlessly.
Use cases
Web map clients. The flagship use case — basemaps in MapLibre GL JS, Mapbox GL JS, OpenLayers, Leaflet (via Leaflet.VectorGrid). The browser pulls only the visible tiles, renders them on WebGL with an arbitrary style (light/dark/satellite/custom branding), and supports interactivity — a click on a building returns its OSM attributes straight out of the tile.
Vector basemaps in production. Large geo-services (Mapbox Streets, MapTiler Cloud, Stadia Maps, Protomaps, OSM Vector Tiles) distribute OpenStreetMap as MVT tiles on a CDN. One tileset serves millions of clients because styling lives on the client; the server only needs to deliver binary tiles.
Offline mobile apps. Mobile apps (Mapbox SDK, MapLibre Native) cache MVT in a local MBTiles database for offline mode. For a tourist with an Android phone this means a single 200-MB MBTiles file of all of Switzerland holds a full vector basemap with any style — incomparably more compact than a raster pyramid covering the same area.
Custom thematic layers. Analytical dashboards and BI tools (Kepler.gl, deck.gl, Felt) overlay MVT with their own attributes on top of a basemap: choropleth by population, POI icons, hexbin density plots. Attributes travel with the geometry, so filtering and recoloring happen on the client in real time.

Workflow in OSM2CDR
Our MVT export is part of the cloud-native pipeline and works as an intermediate step for generating PMTiles and MBTiles. The sequence:
Step 1: filter OSM data by bbox. Through local_osm_loader.py we pull the required layers from PostGIS — planet_osm_polygon (buildings, water bodies, land use), planet_osm_line (roads, rivers, rail), planet_osm_point (POI), plus relations for administrative boundaries. Geometries come out as WKB and are immediately converted to a GeoJSON FeatureCollection — the input format for tippecanoe.
Step 2: run tippecanoe. The worker invokes something like tippecanoe -o out.mbtiles -Z 0 -z 14 --no-feature-limit --no-tile-size-limit --read-parallel -L roads:roads.geojson -L buildings:buildings.geojson -L poi:poi.geojson. -Z/-z set the minimum and maximum zoom, -L maps input GeoJSON files to layers inside the MVT (giving separate roads, buildings, poi — so the client can style each independently). tippecanoe automatically applies Douglas-Peucker simplification at lower zooms and drops small features.
Step 3: package into the final format. Tippecanoe writes MBTiles (SQLite with tiles plus metadata). If the user asked for PMTiles, we run pmtiles convert in.mbtiles out.pmtiles — that produces a single-file container which can be dropped on S3 or GitHub Pages and pointed to from MapLibre via a pmtiles://... URL. If raw MVT was requested, we unpack the MBTiles into a z/x/y.pbf.gz directory via mb-util or tippecanoe-decode.
Step 4: validation. We confirm the output MBTiles/PMTiles opens cleanly with tippecanoe-decode, that the metadata JSON carries correct bounds, minzoom, maxzoom and vector_layers, and that random sample tiles parse via mapbox/vector-tile-py. The user receives either .mbtiles, .pmtiles, or a tar archive with a z/x/y.pbf hierarchy — plus a small HTML snippet with MapLibre GL JS that will load the tileset immediately.
For fine-grained control the API exposes min_zoom, max_zoom, layers (subset of layers), simplification (override the default tippecanoe Douglas-Peucker tolerance) and attribution (metadata field). Defaults are chosen for a typical OSM basemap: z=0..14, all main layers, attribution "© OpenStreetMap contributors".
MVT vs PMTiles vs MBTiles
MVT is the format for a single tile (binary .pbf). MBTiles is a container (a SQLite database) holding hundreds of thousands of MVT tiles plus metadata. PMTiles is an alternative container: a single binary file with its own internal index that supports HTTP range requests, letting you host a tileset on a static server (S3, GitHub Pages, CDN) without a tile API.
The relationship is simple: inside both MBTiles and PMTiles containers sit MVT tiles. The difference is how they are stored and how they are served. If you need dynamic delivery through a tile server with auth, rate limiting and custom logic — go MBTiles + tegola/Martin. If you want the simplest possible setup (drop the file on S3 and forget) — PMTiles. If you need raw tiles for a custom CDN hierarchy — extract z/x/y.pbf.gz directly. All three roads lead to the same binary format at the level of an individual tile.
GeoJSON by comparison is a plain-text format for an entire dataset, with no tiling and no compression. For static delivery in the browser it works only for very small datasets (a few thousand features); for OSM scale you need vector tiles.

Conclusion
MVT is a cornerstone of modern web cartography: an open protobuf-based specification perfectly tuned for streaming small binary tiles to the client and for arbitrary client-side styling. If you're building a web map, a mobile app with offline maps, or an analytical dashboard on top of OSM — MVT through MBTiles or PMTiles is almost certainly your format. Try exporting the region you need now on the /formats/mvt/ page: pick a bbox, a zoom range and a list of layers, and receive a ready tileset you can plug straight into MapLibre GL JS.
Related
- PMTiles — single-file container for vector tiles with range requests
- MBTiles — SQLite container for tile pyramids
- GeoJSON — plain-text format for geo data
Sources
- Mapbox Vector Tile Specification 2.1 — github.com/mapbox/vector-tile-spec
- tippecanoe — Mapbox tile builder — github.com/mapbox/tippecanoe
- MapLibre GL JS — open-source vector renderer — maplibre.org
- Protomaps / PMTiles — protomaps.com