diff --git a/CHANGELOG b/CHANGELOG
index 6e9567e7e204e11015206fcd69e4966f6ad2ff68..e3b1b86fa920822e36863d9d630be303d51e5e1a 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -17,6 +17,7 @@ v 8.12.0 (unreleased)
   - Fix note form hint showing slash commands supported for commits.
   - Make push events have equal vertical spacing.
   - API: Ensure invitees are not returned in Members API.
+  - Preserve applied filters on issues search.
   - Add two-factor recovery endpoint to internal API !5510
   - Pass the "Remember me" value to the U2F authentication form
   - Display stages in valid order in stages dropdown on build page
diff --git a/app/assets/javascripts/issuable.js.es6 b/app/assets/javascripts/issuable.js.es6
index 81d89a48227f77be9fc9a0091f7a12149f384190..73e2664e9c0b08777244448e877318820957c5d1 100644
--- a/app/assets/javascripts/issuable.js.es6
+++ b/app/assets/javascripts/issuable.js.es6
@@ -15,25 +15,32 @@
       return Issuable.labelRow = _.template('<% _.each(labels, function(label){ %> <span class="label-row btn-group" role="group" aria-label="<%- label.title %>" style="color: <%- label.text_color %>;"> <a href="#" class="btn btn-transparent has-tooltip" style="background-color: <%- label.color %>;" title="<%- label.description %>" data-container="body"> <%- label.title %> </a> <button type="button" class="btn btn-transparent label-remove js-label-filter-remove" style="background-color: <%- label.color %>;" data-label="<%- label.title %>"> <i class="fa fa-times"></i> </button> </span> <% }); %>');
     },
     initSearch: function() {
-      this.timer = null;
-      return $('#issuable_search').off('keyup').on('keyup', function() {
-        clearTimeout(this.timer);
-        return this.timer = setTimeout(function() {
-          var $form, $input, $search;
-          $search = $('#issuable_search');
-          $form = $('.js-filter-form');
-          $input = $("input[name='" + ($search.attr('name')) + "']", $form);
-          if ($input.length === 0) {
-            $form.append("<input type='hidden' name='" + ($search.attr('name')) + "' value='" + (_.escape($search.val())) + "'/>");
-          } else {
-            $input.val($search.val());
-          }
-          if ($search.val() !== '') {
-            return Issuable.filterResults($form);
-          }
-        }, 500);
+      // `immediate` param set to false debounces on the `trailing` edge, lets user finish typing
+      const debouncedExecSearch = _.debounce(Issuable.executeSearch, 500, false);
+
+      $('#issuable_search').off('keyup').on('keyup', debouncedExecSearch);
+
+      // ensures existing filters are preserved when manually submitted
+      $('#issue_search_form').on('submit', (e) => {
+        e.preventDefault();
+        debouncedExecSearch(e);
       });
     },
+    executeSearch: function(e) {
+      const $search = $('#issuable_search');
+      const $searchName = $search.attr('name');
+      const $searchValue = $search.val();
+      const $filtersForm = $('.js-filter-form');
+      const $input = $(`input[name='${$searchName}']`, $filtersForm);
+
+      if (!$input.length) {
+        $filtersForm.append(`<input type='hidden' name='${$searchName}' value='${_.escape($searchValue)}'/>`);
+      } else {
+        $input.val($searchValue);
+      }
+
+      Issuable.filterResults($filtersForm);
+    },
     initLabelFilterRemove: function() {
       return $(document).off('click', '.js-label-filter-remove').on('click', '.js-label-filter-remove', function(e) {
         var $button;