ST_AsMVTEx generates a binary Mapbox Vector Tile (MVT) from a set of rows, extending ST_AsMVT with two capabilities: element-level filtering to reduce tile size, and a hard cap on the number of vector elements per tile.
Syntax
bytea ST_AsMVTEx(anyelement row);
bytea ST_AsMVTEx(anyelement row, int4 scale_factor);
bytea ST_AsMVTEx(anyelement row, int4 scale_factor, int4 mvt_size_limit);
bytea ST_AsMVTEx(anyelement row, int4 scale_factor, int4 mvt_size_limit, text name);
bytea ST_AsMVTEx(anyelement row, int4 scale_factor, int4 mvt_size_limit, text name, int4 extent);
bytea ST_AsMVTEx(anyelement row, int4 scale_factor, int4 mvt_size_limit, text name, int4 extent, text geom_name);
bytea ST_AsMVTEx(anyelement row, int4 scale_factor, int4 mvt_size_limit, text name, int4 extent, text geom_name, text feature_id_name);Return value
Returns a bytea value: a binary MVT representation of a tile layer. The tile content is determined by the input row set.
Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
row | anyelement | — | Row data with at least one geometry column. |
scale_factor | int4 | 1 | Controls how aggressively vector elements are filtered. Larger values filter more elements, producing a smaller tile. Valid range: 1 to extent - 1. |
mvt_size_limit | int4 | 2147483647 | Maximum number of vector elements the tile can contain. After filtering, any excess elements are randomly discarded. |
name | text | 'default' | Name of the tile layer. |
extent | int4 | 4096 | Tile extent in screen space, as defined by the MVT specification. |
geom_name | text | First geometry column | Name of the geometry column in the row data. |
feature_id_name | text | — | Name of the Feature ID column. The first column matching the name with a valid type (smallint, integer, or bigint) is used as the Feature ID; any subsequent matching column is added as a property instead. The Feature ID is not set for NULL or negative values. JSON properties are not supported. |
Usage notes
ST_AsMVTEx is not suitable for datasets that consist of large planes. Use it with point-dominant or line-dominant datasets for best results.
Setting extent to a very large value degrades system performance. Keep extent at the default (4096) unless your rendering pipeline requires higher resolution.
The scale_factor parameter ranges from 1 to extent - 1. A value of 1 applies minimal filtering; higher values remove more elements. After scale_factor filtering, if the remaining element count still exceeds mvt_size_limit, the function randomly selects and discards the excess.
Examples
Effect of scale_factor on tile size
All examples below use the same dataset created above. Increasing scale_factor reduces tile size by filtering out elements with minimal visual impact.
-- Create a vector data table and insert one plane, one line, and 9,998 points.
CREATE TABLE example_table(id integer, geom Geometry);
INSERT INTO example_table(id, geom) VALUES
(1, ST_MakeEnvelope(150, 75, 170, 80, 4326));
INSERT INTO example_table(id, geom) VALUES
(2, ST_GeomFromText('LINESTRING(-160 -70, 160 -70)', 4326));
INSERT INTO example_table(id, geom)
SELECT i,
ST_SetSRID(ST_MakePoint((random() * 20) + 150, (random() * 10) + 70), 4326)
FROM generate_series(3, 10000) i;
-- scale_factor = 1 (minimal filtering): 54,237 bytes
WITH mvtgeom AS (
SELECT ST_AsMVTGeom(geom, ST_Transform(ST_TileEnvelope(1, 1, 0), 4326))
FROM example_table
WHERE geom && ST_Transform(ST_TileEnvelope(1, 1, 0), 4326)
)
SELECT length(ST_AsMVTEx(mvtgeom.*, 1)) FROM mvtgeom;
-- length
-- -------
-- 54237-- scale_factor = 4 (more aggressive filtering): 39,211 bytes
WITH mvtgeom AS (
SELECT ST_AsMVTGeom(geom, ST_Transform(ST_TileEnvelope(1, 1, 0), 4326))
FROM example_table
WHERE geom && ST_Transform(ST_TileEnvelope(1, 1, 0), 4326)
)
SELECT length(ST_AsMVTEx(mvtgeom.*, 4)) FROM mvtgeom;
-- length
-- -------
-- 39211Combining scale_factor and mvt_size_limit
-- scale_factor = 4, mvt_size_limit = 100: tile capped at 100 elements, 1,117 bytes
WITH mvtgeom AS (
SELECT ST_AsMVTGeom(geom, ST_Transform(ST_TileEnvelope(1, 1, 0), 4326))
FROM example_table
WHERE geom && ST_Transform(ST_TileEnvelope(1, 1, 0), 4326)
)
SELECT length(ST_AsMVTEx(mvtgeom.*, 4, 100)) FROM mvtgeom;
-- length
-- -------
-- 1117Custom extent and layer name
-- scale_factor = 4, mvt_size_limit = 100, extent = 10000, layer name = 'layer_name': 1,220 bytes
WITH mvtgeom AS (
SELECT ST_AsMVTGeom(geom, ST_Transform(ST_TileEnvelope(1, 1, 0), 4326), 10000)
FROM example_table
WHERE geom && ST_Transform(ST_TileEnvelope(1, 1, 0), 4326)
)
SELECT length(ST_AsMVTEx(mvtgeom.*, 4, 100, 'layer_name', 10000)) FROM mvtgeom;
-- length
-- -------
-- 1220Custom geometry and Feature ID columns
-- All parameters specified: scale_factor = 4, mvt_size_limit = 100, extent = 10000,
-- layer name = 'layer_name', geometry column = 'geom_field', Feature ID column = 'id_field': 1,520 bytes
WITH mvtgeom AS (
SELECT ST_AsMVTGeom(geom, ST_Transform(ST_TileEnvelope(1, 1, 0), 4326), 10000) AS geom_field,
id AS id_field
FROM example_table
WHERE geom && ST_Transform(ST_TileEnvelope(1, 1, 0), 4326)
)
SELECT length(ST_AsMVTEx(mvtgeom.*, 4, 100, 'layer_name', 10000, 'geom_field', 'id_field')) FROM mvtgeom;
-- length
-- -------
-- 1520