diff --git a/app/assets/javascripts/jobs/components/filtered_search/constants.js b/app/assets/javascripts/jobs/components/filtered_search/constants.js
new file mode 100644
index 0000000000000000000000000000000000000000..0daba8923754db32d322a4638447e304d8f5a63c
--- /dev/null
+++ b/app/assets/javascripts/jobs/components/filtered_search/constants.js
@@ -0,0 +1,13 @@
+export const jobStatusValues = [
+  'CANCELED',
+  'CREATED',
+  'FAILED',
+  'MANUAL',
+  'SUCCESS',
+  'PENDING',
+  'PREPARING',
+  'RUNNING',
+  'SCHEDULED',
+  'SKIPPED',
+  'WAITING_FOR_RESOURCE',
+];
diff --git a/app/assets/javascripts/jobs/components/filtered_search/jobs_filtered_search.vue b/app/assets/javascripts/jobs/components/filtered_search/jobs_filtered_search.vue
index fe7b7428c6ed2f8977baba70b049d42e2e8dd951..e498a735898d57dd75f83731c6dc4849e4dac250 100644
--- a/app/assets/javascripts/jobs/components/filtered_search/jobs_filtered_search.vue
+++ b/app/assets/javascripts/jobs/components/filtered_search/jobs_filtered_search.vue
@@ -11,6 +11,13 @@ export default {
   components: {
     GlFilteredSearch,
   },
+  props: {
+    queryString: {
+      type: Object,
+      required: false,
+      default: null,
+    },
+  },
   computed: {
     tokens() {
       return [
@@ -24,6 +31,20 @@ export default {
         },
       ];
     },
+    filteredSearchValue() {
+      if (this.queryString?.statuses) {
+        return [
+          {
+            type: 'status',
+            value: {
+              data: this.queryString?.statuses,
+              operator: '=',
+            },
+          },
+        ];
+      }
+      return [];
+    },
   },
   methods: {
     onSubmit(filters) {
@@ -37,6 +58,7 @@ export default {
   <gl-filtered-search
     :placeholder="s__('Jobs|Filter jobs')"
     :available-tokens="tokens"
+    :value="filteredSearchValue"
     @submit="onSubmit"
   />
 </template>
diff --git a/app/assets/javascripts/jobs/components/filtered_search/utils.js b/app/assets/javascripts/jobs/components/filtered_search/utils.js
new file mode 100644
index 0000000000000000000000000000000000000000..eef5b73886336b885619155cde8d6dd1deef01ae
--- /dev/null
+++ b/app/assets/javascripts/jobs/components/filtered_search/utils.js
@@ -0,0 +1,23 @@
+import { jobStatusValues } from './constants';
+
+// validates query string used for filtered search
+// on jobs table to ensure GraphQL query is called correctly
+export const validateQueryString = (queryStringObj) => {
+  // currently only one token is supported `statuses`
+  // this code will need to be expanded as more tokens
+  // are introduced
+
+  const filters = Object.keys(queryStringObj);
+
+  if (filters.includes('statuses')) {
+    const found = jobStatusValues.find((status) => status === queryStringObj.statuses);
+
+    if (found) {
+      return queryStringObj;
+    }
+
+    return null;
+  }
+
+  return null;
+};
diff --git a/app/assets/javascripts/jobs/components/table/jobs_table_app.vue b/app/assets/javascripts/jobs/components/table/jobs_table_app.vue
index c2f460cb64740e44280a56780364a1c33351d027..b8ba781ab5fc657432d7024eeed05aedd2a54c1c 100644
--- a/app/assets/javascripts/jobs/components/table/jobs_table_app.vue
+++ b/app/assets/javascripts/jobs/components/table/jobs_table_app.vue
@@ -2,7 +2,9 @@
 import { GlAlert, GlSkeletonLoader, GlIntersectionObserver, GlLoadingIcon } from '@gitlab/ui';
 import { __ } from '~/locale';
 import createFlash from '~/flash';
+import { setUrlParams, updateHistory, queryToObject } from '~/lib/utils/url_utility';
 import JobsFilteredSearch from '../filtered_search/jobs_filtered_search.vue';
+import { validateQueryString } from '../filtered_search/utils';
 import GetJobs from './graphql/queries/get_jobs.query.graphql';
 import JobsTable from './jobs_table.vue';
 import JobsTableEmptyState from './jobs_table_empty_state.vue';
@@ -37,6 +39,7 @@ export default {
       variables() {
         return {
           fullPath: this.fullPath,
+          ...this.validatedQueryString,
         };
       },
       update(data) {
@@ -95,6 +98,11 @@ export default {
     jobsCount() {
       return this.jobs.count;
     },
+    validatedQueryString() {
+      const queryStringObject = queryToObject(window.location.search);
+
+      return validateQueryString(queryStringObject);
+    },
   },
   watch: {
     // this watcher ensures that the count on the all tab
@@ -133,6 +141,10 @@ export default {
         }
 
         if (filter.type === 'status') {
+          updateHistory({
+            url: setUrlParams({ statuses: filter.value.data }, window.location.href, true),
+          });
+
           this.$apollo.queries.jobs.refetch({ statuses: filter.value.data });
         }
       });
@@ -175,6 +187,7 @@ export default {
     <jobs-filtered-search
       v-if="showFilteredSearch"
       :class="$options.filterSearchBoxStyles"
+      :query-string="validatedQueryString"
       @filterJobsBySearch="filterJobsBySearch"
     />
 
diff --git a/spec/frontend/jobs/components/filtered_search/jobs_filtered_search_spec.js b/spec/frontend/jobs/components/filtered_search/jobs_filtered_search_spec.js
index 322cfa3ba1fc627816d615d5218eafb350a0a889..98bdfc3fcbcf6539ff740723c11db736bf7fad68 100644
--- a/spec/frontend/jobs/components/filtered_search/jobs_filtered_search_spec.js
+++ b/spec/frontend/jobs/components/filtered_search/jobs_filtered_search_spec.js
@@ -15,23 +15,27 @@ describe('Jobs filtered search', () => {
 
   const findStatusToken = () => getSearchToken('status');
 
-  const createComponent = () => {
-    wrapper = shallowMount(JobsFilteredSearch);
+  const createComponent = (props) => {
+    wrapper = shallowMount(JobsFilteredSearch, {
+      propsData: {
+        ...props,
+      },
+    });
   };
 
-  beforeEach(() => {
-    createComponent();
-  });
-
   afterEach(() => {
     wrapper.destroy();
   });
 
   it('displays filtered search', () => {
+    createComponent();
+
     expect(findFilteredSearch().exists()).toBe(true);
   });
 
   it('displays status token', () => {
+    createComponent();
+
     expect(findStatusToken()).toMatchObject({
       type: 'status',
       icon: 'status',
@@ -42,8 +46,26 @@ describe('Jobs filtered search', () => {
   });
 
   it('emits filter token to parent component', () => {
+    createComponent();
+
     findFilteredSearch().vm.$emit('submit', mockFailedSearchToken);
 
     expect(wrapper.emitted('filterJobsBySearch')).toEqual([[mockFailedSearchToken]]);
   });
+
+  it('filtered search value is empty array when no query string is passed', () => {
+    createComponent();
+
+    expect(findFilteredSearch().props('value')).toEqual([]);
+  });
+
+  it('filtered search returns correct data shape when passed query string', () => {
+    const value = 'SUCCESS';
+
+    createComponent({ queryString: { statuses: value } });
+
+    expect(findFilteredSearch().props('value')).toEqual([
+      { type: 'status', value: { data: value, operator: '=' } },
+    ]);
+  });
 });
diff --git a/spec/frontend/jobs/components/filtered_search/utils_spec.js b/spec/frontend/jobs/components/filtered_search/utils_spec.js
new file mode 100644
index 0000000000000000000000000000000000000000..8e9cd357a199042307bb2e31005542002b217857
--- /dev/null
+++ b/spec/frontend/jobs/components/filtered_search/utils_spec.js
@@ -0,0 +1,18 @@
+import { validateQueryString } from '~/jobs/components/filtered_search/utils';
+
+describe('Filtered search utils', () => {
+  describe('validateQueryString', () => {
+    it.each`
+      queryStringObject          | expected
+      ${{ statuses: 'SUCCESS' }} | ${{ statuses: 'SUCCESS' }}
+      ${{ wrong: 'SUCCESS' }}    | ${null}
+      ${{ statuses: 'wrong' }}   | ${null}
+      ${{ wrong: 'wrong' }}      | ${null}
+    `(
+      'when provided $queryStringObject, the expected result is $expected',
+      ({ queryStringObject, expected }) => {
+        expect(validateQueryString(queryStringObject)).toEqual(expected);
+      },
+    );
+  });
+});
diff --git a/spec/frontend/jobs/components/table/job_table_app_spec.js b/spec/frontend/jobs/components/table/job_table_app_spec.js
index 374768c3ee4df2df887a7f1377c03c39d0858eb7..8c724a8030bfc3a0f35303aa96ce56f0de7b81e4 100644
--- a/spec/frontend/jobs/components/table/job_table_app_spec.js
+++ b/spec/frontend/jobs/components/table/job_table_app_spec.js
@@ -11,12 +11,14 @@ import VueApollo from 'vue-apollo';
 import { s__ } from '~/locale';
 import createMockApollo from 'helpers/mock_apollo_helper';
 import waitForPromises from 'helpers/wait_for_promises';
+import { TEST_HOST } from 'spec/test_constants';
 import createFlash from '~/flash';
 import getJobsQuery from '~/jobs/components/table/graphql/queries/get_jobs.query.graphql';
 import JobsTable from '~/jobs/components/table/jobs_table.vue';
 import JobsTableApp from '~/jobs/components/table/jobs_table_app.vue';
 import JobsTableTabs from '~/jobs/components/table/jobs_table_tabs.vue';
 import JobsFilteredSearch from '~/jobs/components/filtered_search/jobs_filtered_search.vue';
+import * as urlUtils from '~/lib/utils/url_utility';
 import {
   mockJobsResponsePaginated,
   mockJobsResponseEmpty,
@@ -230,5 +232,17 @@ describe('Job table app', () => {
       expect(createFlash).toHaveBeenCalledWith(expectedWarning);
       expect(wrapper.vm.$apollo.queries.jobs.refetch).toHaveBeenCalledTimes(0);
     });
+
+    it('updates URL query string when filtering jobs by status', async () => {
+      createComponent();
+
+      jest.spyOn(urlUtils, 'updateHistory');
+
+      await findFilteredSearch().vm.$emit('filterJobsBySearch', [mockFailedSearchToken]);
+
+      expect(urlUtils.updateHistory).toHaveBeenCalledWith({
+        url: `${TEST_HOST}/?statuses=FAILED`,
+      });
+    });
   });
 });