diff --git a/app/views/profiles/preferences/show.html.haml b/app/views/profiles/preferences/show.html.haml
index 4930ef71e7d699e2b7a7a27ba5c9780a5cd14f49..a085840ee84aba8af357de6f04a2856d0190efd4 100644
--- a/app/views/profiles/preferences/show.html.haml
+++ b/app/views/profiles/preferences/show.html.haml
@@ -171,6 +171,6 @@
           = f.gitlab_ui_checkbox_component :enabled_following,
           s_('Preferences|Enable follow users')
   = render_if_exists 'profiles/preferences/code_suggestions_settings', form: f
-
+  = render_if_exists 'profiles/preferences/zoekt_settings', form: f
 
   #js-profile-preferences-app{ data: data_attributes }
diff --git a/db/migrate/20230524142655_add_enabled_zoekt_to_user_preferences.rb b/db/migrate/20230524142655_add_enabled_zoekt_to_user_preferences.rb
new file mode 100644
index 0000000000000000000000000000000000000000..b92f424d5e112b4d13a3156e80b3f22107bde5dd
--- /dev/null
+++ b/db/migrate/20230524142655_add_enabled_zoekt_to_user_preferences.rb
@@ -0,0 +1,9 @@
+# frozen_string_literal: true
+
+class AddEnabledZoektToUserPreferences < Gitlab::Database::Migration[2.1]
+  enable_lock_retries!
+
+  def change
+    add_column :user_preferences, :enabled_zoekt, :boolean, null: false, default: true
+  end
+end
diff --git a/db/schema_migrations/20230524142655 b/db/schema_migrations/20230524142655
new file mode 100644
index 0000000000000000000000000000000000000000..35aa474f5dd9d7ed4d5ccad85e0282b41e34e9fa
--- /dev/null
+++ b/db/schema_migrations/20230524142655
@@ -0,0 +1 @@
+81f0d62ff5c06d5c34984dae613535d7ffbe9f0f3b25d2a694c5607e5e590805
\ No newline at end of file
diff --git a/db/structure.sql b/db/structure.sql
index 4ad846f49af29cac60728f5a084228fc96180163..b3e087759e2d685d8a12624131e99f67e167ee08 100644
--- a/db/structure.sql
+++ b/db/structure.sql
@@ -23690,6 +23690,7 @@ CREATE TABLE user_preferences (
     enabled_following boolean DEFAULT true NOT NULL,
     visibility_pipeline_id_type smallint DEFAULT 0 NOT NULL,
     project_shortcut_buttons boolean DEFAULT true NOT NULL,
+    enabled_zoekt boolean DEFAULT true NOT NULL,
     CONSTRAINT check_89bf269f41 CHECK ((char_length(diffs_deletion_color) <= 7)),
     CONSTRAINT check_d07ccd35f7 CHECK ((char_length(diffs_addition_color) <= 7))
 );
diff --git a/doc/user/profile/index.md b/doc/user/profile/index.md
index 35f6f07f0be4b2de23bb45d9995f972fd5665101..20ca57a540bf0b8bf6f7c644146e84b24e1ce7d4 100644
--- a/doc/user/profile/index.md
+++ b/doc/user/profile/index.md
@@ -324,6 +324,20 @@ You can disable following and being followed by other users.
 NOTE:
 When this feature is being disabled, all current followed/following connections are deleted.
 
+## Advanced code search with zoekt
+
+### Disable searching code with zoekt
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/388519) as a beta feature [with a flag](../feature_flags.md) named `search_code_with_zoekt`. Enabled by default.
+
+You can disable searching with Zoekt and use Elasticsearch instead.
+
+1. On the top bar, in the upper-right corner, select your avatar.
+1. Select **Edit profile**.
+1. Select **Preferences**.
+1. Clear the **Enable advanced code search** checkbox.
+1. Select **Save changes**.
+
 ## View your activity
 
 GitLab tracks [user contribution activity](contributions_calendar.md).
diff --git a/ee/app/controllers/ee/profiles/preferences_controller.rb b/ee/app/controllers/ee/profiles/preferences_controller.rb
index 33a4572b5132a6a252114dd6bd2448f2af84fbe7..c8f25cbdf3c6b5d64806f5d99835da530e5c3c2e 100644
--- a/ee/app/controllers/ee/profiles/preferences_controller.rb
+++ b/ee/app/controllers/ee/profiles/preferences_controller.rb
@@ -12,6 +12,7 @@ def preferences_param_names_ee
     params_ee = []
     params_ee.push(:group_view) if License.feature_available?(:security_dashboard)
     params_ee.push(:code_suggestions) if user.namespace.ai_assist_ui_enabled?
+    params_ee.push(:enabled_zoekt) if user.has_zoekt_indexed_namespace?
 
     params_ee
   end
diff --git a/ee/app/models/ee/user.rb b/ee/app/models/ee/user.rb
index f89eb12c73986dee22c76c675f76456a9e9968ab..ab152e6ccc6d459d1ea35660d304896ce08219ba 100644
--- a/ee/app/models/ee/user.rb
+++ b/ee/app/models/ee/user.rb
@@ -49,6 +49,9 @@ module User
       delegate :code_suggestions_enabled?, :code_suggestions, :code_suggestions=,
         to: :namespace
 
+      delegate :enabled_zoekt?, :enabled_zoekt, :enabled_zoekt=,
+        to: :user_preference
+
       has_many :epics,                    foreign_key: :author_id
       has_many :test_reports,             foreign_key: :author_id, inverse_of: :author, class_name: 'RequirementsManagement::TestReport'
       has_many :assigned_epics,           foreign_key: :assignee_id, class_name: "Epic"
@@ -322,6 +325,19 @@ def owns_group_without_trial?
         .any?
     end
 
+    # Returns true if the user is a Reporter or higher on any namespace
+    # that is associated as a Zoekt::IndexedNamespace
+    def has_zoekt_indexed_namespace?
+      zoekt_indexed_namespaces.any?
+    end
+
+    def zoekt_indexed_namespaces
+      ::Zoekt::IndexedNamespace.where(
+        namespace: ::Namespace
+          .from("(#{namespace_union_for_reporter_developer_maintainer_owned}) #{::Namespace.table_name}")
+      )
+    end
+
     # Returns true if the user is a Reporter or higher on any namespace
     # currently on a paid plan
     def has_paid_namespace?(plans: ::Plan::PAID_HOSTED_PLANS, exclude_trials: false)
diff --git a/ee/app/services/concerns/search/zoekt_searchable.rb b/ee/app/services/concerns/search/zoekt_searchable.rb
index d1c0a90ffe62d9f7dfbf504a9845ad60bbd3218e..bab51ab12abbeec8f79147cbaa36b582c460f58e 100644
--- a/ee/app/services/concerns/search/zoekt_searchable.rb
+++ b/ee/app/services/concerns/search/zoekt_searchable.rb
@@ -4,9 +4,9 @@ module Search
   module ZoektSearchable
     def use_zoekt?
       return false if params[:basic_search]
-      return false if params[:advanced_search]
       return false unless ::Feature.enabled?(:search_code_with_zoekt, current_user)
       return false unless ::License.feature_available?(:zoekt_code_search)
+      return false unless current_user&.enabled_zoekt?
 
       scope == 'blobs' &&
         zoekt_searchable_scope.respond_to?(:use_zoekt?) &&
diff --git a/ee/app/views/profiles/preferences/_zoekt_settings.html.haml b/ee/app/views/profiles/preferences/_zoekt_settings.html.haml
new file mode 100644
index 0000000000000000000000000000000000000000..b1c36152a7c148e694b197153b73556a480c0a69
--- /dev/null
+++ b/ee/app/views/profiles/preferences/_zoekt_settings.html.haml
@@ -0,0 +1,17 @@
+- return unless @user.has_zoekt_indexed_namespace?
+
+.row.js-preferences-form.js-search-settings-section
+  .col-sm-12
+    %hr
+  .col-lg-4.profile-settings-sidebar
+    %h4.gl-mt-0
+      = s_('Preferences|Enable Zoekt code search')
+      = gl_badge_tag _('beta'), variant: :info, size: :sm
+    %p
+      = s_('Preferences|Turns on or off the preference to search with Zoekt instead of Elasticsearch.')
+      = link_to _('Learn more'), help_page_path('user/profile/index', anchor: 'advanced-code-search-with-zoekt'), target: '_blank', rel: 'noopener noreferrer'
+
+  .col-lg-8
+    .form-group
+      = form.gitlab_ui_checkbox_component :enabled_zoekt,
+        s_('Preferences|Enable Zoekt code search')
diff --git a/ee/spec/controllers/ee/profiles/preferences_controller_spec.rb b/ee/spec/controllers/ee/profiles/preferences_controller_spec.rb
index b25b85d185f234c676645d759307b8f24229b165..b9d9a17e98f822009a224e87e17ff6ab4ad4bda9 100644
--- a/ee/spec/controllers/ee/profiles/preferences_controller_spec.rb
+++ b/ee/spec/controllers/ee/profiles/preferences_controller_spec.rb
@@ -10,6 +10,16 @@
   end
 
   describe 'PATCH update' do
+    def go(params: {}, format: :json)
+      params.reverse_merge!(
+        color_scheme_id: '1',
+        dashboard: 'stars',
+        theme_id: '1'
+      )
+
+      patch :update, params: { user: params }, format: format
+    end
+
     context 'when updating security dashboard feature' do
       subject { patch :update, params: { user: { group_view: group_view } }, format: :json }
 
@@ -76,5 +86,37 @@
         end
       end
     end
+
+    context 'on zoekt indexed namespaces', feature_category: :global_search do
+      context 'when user is not a member of any zoekt indexed namespaces' do
+        before do
+          allow(::Zoekt::IndexedNamespace).to receive(:where).and_return([])
+        end
+
+        it 'does not update enabled_zoekt preference of user' do
+          prefs = { enabled_zoekt: false }
+
+          go params: prefs
+          user.reload
+
+          expect(user.enabled_zoekt).to eq(true)
+        end
+      end
+
+      context 'when user is a member of a zoekt indexed namespace' do
+        before do
+          allow(::Zoekt::IndexedNamespace).to receive(:where).and_return([::Zoekt::IndexedNamespace.new])
+        end
+
+        it 'updates enabled_zoekt preference of user' do
+          prefs = { enabled_zoekt: false }
+
+          go params: prefs
+          user.reload
+
+          expect(user.enabled_zoekt).to eq(false)
+        end
+      end
+    end
   end
 end
diff --git a/ee/spec/models/ee/user_spec.rb b/ee/spec/models/ee/user_spec.rb
index 1eac0cc0664e600df64a6b0079e797f52ee72da9..29c5ce001aa115abed94314337de3406f74bff81 100644
--- a/ee/spec/models/ee/user_spec.rb
+++ b/ee/spec/models/ee/user_spec.rb
@@ -1438,6 +1438,36 @@
     end
   end
 
+  context 'zoekt namespaces', feature_category: :global_search do
+    let_it_be(:indexed_parent_namespace) { create(:group) }
+    let_it_be(:unindexed_namespace) { create(:namespace) }
+    let_it_be(:shard) { Zoekt::Shard.create!(index_base_url: 'http://example.com:1234/', search_base_url: 'http://example.com:4567/') }
+    let_it_be(:zoekt_indexed_namespace) { Zoekt::IndexedNamespace.create!(shard: shard, namespace: indexed_parent_namespace) }
+
+    let(:user) { create(:user, namespace: create(:user_namespace)) }
+
+    describe '#zoekt_indexed_namespaces' do
+      it 'returns zoekt indexed namespaces for user' do
+        indexed_parent_namespace.add_maintainer(user)
+        expect(user.zoekt_indexed_namespaces).to match_array([zoekt_indexed_namespace])
+      end
+
+      it 'returns empty array if there are user is not have access of reporter or above' do
+        expect(user.zoekt_indexed_namespaces).to match_array([])
+      end
+    end
+
+    describe '#has_zoekt_indexed_namespace?' do
+      it 'returns true if there are zoekt_indexed_namespaces' do
+        allow(user).to receive(:zoekt_indexed_namespaces).and_return([zoekt_indexed_namespace])
+        expect(user).to be_has_zoekt_indexed_namespace
+
+        allow(user).to receive(:zoekt_indexed_namespaces).and_return([])
+        expect(user).not_to be_has_zoekt_indexed_namespace
+      end
+    end
+  end
+
   context 'paid namespaces', :saas do
     using RSpec::Parameterized::TableSyntax
 
diff --git a/ee/spec/services/search/project_service_spec.rb b/ee/spec/services/search/project_service_spec.rb
index 5be3b14d938c7eec1e906965c7584169fd8b7750..65f8230db77d25de8aea4ca776c1f851e6aec88c 100644
--- a/ee/spec/services/search/project_service_spec.rb
+++ b/ee/spec/services/search/project_service_spec.rb
@@ -78,12 +78,14 @@
     end
 
     let(:use_zoekt) { true }
+    let(:user_preference_enabled_zoekt) { true }
     let(:scope) { 'blobs' }
     let(:basic_search) { nil }
     let(:advanced_search) { nil }
 
     before do
       allow(project).to receive(:use_zoekt?).and_return(use_zoekt)
+      allow(user).to receive(:enabled_zoekt?).and_return(user_preference_enabled_zoekt)
     end
 
     it 'searches with Zoekt' do
@@ -119,11 +121,11 @@
       end
     end
 
-    context 'when advanced search is requested' do
-      let(:advanced_search) { true }
+    context 'when user set enabled_zoekt preference to false' do
+      let(:user_preference_enabled_zoekt) { false }
 
       it 'does not search with Zoekt' do
-        expect(service.use_zoekt?).to eq(false)
+        expect(service).not_to be_use_zoekt
         expect(service.execute).not_to be_kind_of(::Gitlab::Zoekt::SearchResults)
       end
     end
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index deaf1e2fa2dec9169b6e9e312c5cd4b62c7c8469..15a19fc212d0f7ac1955bd4c8d0397524000a28b 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -34308,6 +34308,9 @@ msgstr ""
 msgid "Preferences|Enable Gitpod integration"
 msgstr ""
 
+msgid "Preferences|Enable Zoekt code search"
+msgstr ""
+
 msgid "Preferences|Enable follow users"
 msgstr ""
 
@@ -34383,6 +34386,9 @@ msgstr ""
 msgid "Preferences|Turns on or off the ability to follow or be followed by other users."
 msgstr ""
 
+msgid "Preferences|Turns on or off the preference to search with Zoekt instead of Elasticsearch."
+msgstr ""
+
 msgid "Preferences|Use relative times"
 msgstr ""