diff --git a/CHANGELOG.md b/CHANGELOG.md
index c559b19..fb9d55a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,7 @@
+## 1.16.12
+
+* Stop processing higher zooms when a feature reaches its explicit maxzoom tag
+
 ## 1.16.11
 
 * Remove polygon splitting, since polygon cleaning is now fast enough
diff --git a/tile.cpp b/tile.cpp
index d1ae4c1..e47e281 100644
--- a/tile.cpp
+++ b/tile.cpp
@@ -1451,7 +1451,9 @@ long long write_tile(FILE *geoms, long long *geompos_in, char *metabase, char *s
 			}
 
 			if (first_time && pass == 1) { /* only write out the next zoom once, even if we retry */
-				rewrite(geom, z, nextzoom, maxzoom, bbox, tx, ty, buffer, line_detail, within, geompos, geomfile, fname, t, layer, metastart, feature_minzoom, child_shards, max_zoom_increment, original_seq, tippecanoe_minzoom, tippecanoe_maxzoom, segment, initial_x, initial_y, m, metakeys, metavals, has_id, id, index, extent);
+				if (tippecanoe_maxzoom == -1 || tippecanoe_maxzoom >= nextzoom) {
+					rewrite(geom, z, nextzoom, maxzoom, bbox, tx, ty, buffer, line_detail, within, geompos, geomfile, fname, t, layer, metastart, feature_minzoom, child_shards, max_zoom_increment, original_seq, tippecanoe_minzoom, tippecanoe_maxzoom, segment, initial_x, initial_y, m, metakeys, metavals, has_id, id, index, extent);
+				}
 			}
 
 			if (z < minzoom) {
diff --git a/version.hpp b/version.hpp
index e7c66ce..77f80bc 100644
--- a/version.hpp
+++ b/version.hpp
@@ -1 +1 @@
-#define VERSION "tippecanoe v1.16.11\n"
+#define VERSION "tippecanoe v1.16.12\n"