Index: src/wp-admin/js/nav-menu.js
===================================================================
--- src/wp-admin/js/nav-menu.js	(revision 36507)
+++ src/wp-admin/js/nav-menu.js	(working copy)
@@ -43,6 +43,7 @@
 
 			this.attachQuickSearchListeners();
 			this.attachThemeLocationsListeners();
+			this.attachMenuSaveSubmitListeners();
 
 			this.attachTabsPanelListeners();
 
@@ -834,6 +835,17 @@
 			});
 		},
 
+		attachMenuSaveSubmitListeners : function() {
+			/*
+			 * When a navigation menu is saved, store a JSON representation of all form data
+			 * in a single input to avoid PHP max_input_vars limitations. See #14134.
+			 */
+			$('#update-nav-menu').submit(function() {
+				var navMenuData = $('#update-nav-menu').serializeArray();
+				$('[name="nav-menu-data"]').val( JSON.stringify( navMenuData ) );
+			});
+		},
+
 		attachThemeLocationsListeners : function() {
 			var loc = $('#nav-menu-theme-locations'), params = {};
 			params.action = 'menu-locations-save';
Index: src/wp-admin/nav-menus.php
===================================================================
--- src/wp-admin/nav-menus.php	(revision 36507)
+++ src/wp-admin/nav-menus.php	(working copy)
@@ -49,6 +49,26 @@
 // Allowed actions: add, update, delete
 $action = isset( $_REQUEST['action'] ) ? $_REQUEST['action'] : 'edit';
 
+/*
+ * If a JSON blob of navigation menu data is found, expand it and fill PHP $_POST
+ * vars to avoid PHP max_input_vars limitations. See #14134.
+ */
+if ( isset( $_POST['nav-menu-data'] ) ) {
+	$data = json_decode( stripslashes( $_POST['nav-menu-data'] ) );
+	if ( ! is_null( $data ) && $data ) {
+		foreach ( $data as $post_input_data ) {
+			// For input names that are arrays (e.g. `menu-item-db-id[3]`), derive the array path keys via regex.
+			if ( preg_match( '#(.*)(?:\[(\d+)\])#', $post_input_data->name, $matches ) ) {
+				if ( empty( $_POST[$matches[1]] ) ) {
+					$_POST[$matches[1]] = array();
+				}
+				$_POST[$matches[1]][(int)$matches[2]] = $post_input_data->value;
+			} else {
+				$_POST[$post_input_data->name] = $post_input_data->value;
+			}
+		}
+	}
+}
 switch ( $action ) {
 	case 'add-menu-item':
 		check_admin_referer( 'add-menu_item', 'menu-settings-column-nonce' );
@@ -731,6 +751,7 @@
 		<div id="menu-management">
 			<form id="update-nav-menu" method="post" enctype="multipart/form-data">
 				<div class="menu-edit <?php if ( $add_new_screen ) echo 'blank-slate'; ?>">
+					<input type="hidden" name="nav-menu-data">
 					<?php
 					wp_nonce_field( 'closedpostboxes', 'closedpostboxesnonce', false );
 					wp_nonce_field( 'meta-box-order', 'meta-box-order-nonce', false );
