diff --git a/app/assets/javascripts/shortcuts.js b/app/assets/javascripts/shortcuts.js
index a4a7f3fa9441f777e8f9d4667b3c57498e8682c1..49d980212d6b8972026c67cd5b483a16dbca3c45 100644
--- a/app/assets/javascripts/shortcuts.js
+++ b/app/assets/javascripts/shortcuts.js
@@ -62,7 +62,7 @@ import findAndFollowLink from './shortcuts_dashboard_navigation';
       if (Cookies.get(performanceBarCookieName) === 'true') {
         Cookies.remove(performanceBarCookieName, { path: '/' });
       } else {
-        Cookies.set(performanceBarCookieName, true, { path: '/' });
+        Cookies.set(performanceBarCookieName, 'true', { path: '/' });
       }
       gl.utils.refreshCurrentPage();
     };
diff --git a/app/controllers/admin/application_settings_controller.rb b/app/controllers/admin/application_settings_controller.rb
index f978ce478c7a5712a434a66cc5dfaa98c5876f96..1cc060e4de85c66cf2b57981fda5511b91b45738 100644
--- a/app/controllers/admin/application_settings_controller.rb
+++ b/app/controllers/admin/application_settings_controller.rb
@@ -126,6 +126,8 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController
       :metrics_port,
       :metrics_sample_interval,
       :metrics_timeout,
+      :performance_bar_allowed_group_id,
+      :performance_bar_enabled,
       :recaptcha_enabled,
       :recaptcha_private_key,
       :recaptcha_site_key,
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
index b4c0cd0487f83132adbf3db7ec78bf67c75167a7..db7edbd619bf299b52ab686d7d0a74be5a30ef3e 100644
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -9,7 +9,7 @@ class ApplicationController < ActionController::Base
   include SentryHelper
   include WorkhorseHelper
   include EnforcesTwoFactorAuthentication
-  include Peek::Rblineprof::CustomControllerHelpers
+  include WithPerformanceBar
 
   before_action :authenticate_user_from_private_token!
   before_action :authenticate_user_from_rss_token!
@@ -68,21 +68,6 @@ class ApplicationController < ActionController::Base
     end
   end
 
-  def peek_enabled?
-    return false unless Gitlab::PerformanceBar.enabled?
-    return false unless current_user
-
-    if RequestStore.active?
-      if RequestStore.store.key?(:peek_enabled)
-        RequestStore.store[:peek_enabled]
-      else
-        RequestStore.store[:peek_enabled] = cookies[:perf_bar_enabled].present?
-      end
-    else
-      cookies[:perf_bar_enabled].present?
-    end
-  end
-
   protected
 
   # This filter handles both private tokens and personal access tokens
diff --git a/app/controllers/concerns/with_performance_bar.rb b/app/controllers/concerns/with_performance_bar.rb
new file mode 100644
index 0000000000000000000000000000000000000000..ed253042701d181377845850fec1d3168e484362
--- /dev/null
+++ b/app/controllers/concerns/with_performance_bar.rb
@@ -0,0 +1,17 @@
+module WithPerformanceBar
+  extend ActiveSupport::Concern
+
+  included do
+    include Peek::Rblineprof::CustomControllerHelpers
+  end
+
+  def peek_enabled?
+    return false unless Gitlab::PerformanceBar.enabled?(current_user)
+
+    if RequestStore.active?
+      RequestStore.fetch(:peek_enabled) { cookies[:perf_bar_enabled].present? }
+    else
+      cookies[:perf_bar_enabled].present?
+    end
+  end
+end
diff --git a/app/models/application_setting.rb b/app/models/application_setting.rb
index b0d7f7ef5f525d41ad74a733c0a2106d7afce922..14516091495d16ce8d417f350ab0160e9af72e0c 100644
--- a/app/models/application_setting.rb
+++ b/app/models/application_setting.rb
@@ -234,6 +234,7 @@ class ApplicationSetting < ActiveRecord::Base
       koding_url: nil,
       max_artifacts_size: Settings.artifacts['max_size'],
       max_attachment_size: Settings.gitlab['max_attachment_size'],
+      performance_bar_allowed_group_id: nil,
       plantuml_enabled: false,
       plantuml_url: nil,
       recaptcha_enabled: false,
@@ -336,6 +337,48 @@ class ApplicationSetting < ActiveRecord::Base
     super(levels.map { |level| Gitlab::VisibilityLevel.level_value(level) })
   end
 
+  def performance_bar_allowed_group_id=(group_full_path)
+    group_full_path = nil if group_full_path.blank?
+
+    if group_full_path.nil?
+      if group_full_path != performance_bar_allowed_group_id
+        super(group_full_path)
+        Gitlab::PerformanceBar.expire_allowed_user_ids_cache
+      end
+      return
+    end
+
+    group = Group.find_by_full_path(group_full_path)
+
+    if group
+      if group.id != performance_bar_allowed_group_id
+        super(group.id)
+        Gitlab::PerformanceBar.expire_allowed_user_ids_cache
+      end
+    else
+      super(nil)
+      Gitlab::PerformanceBar.expire_allowed_user_ids_cache
+    end
+  end
+
+  def performance_bar_allowed_group
+    Group.find_by_id(performance_bar_allowed_group_id)
+  end
+
+  # Return true if the Performance Bar is enabled for a given group
+  def performance_bar_enabled
+    performance_bar_allowed_group_id.present?
+  end
+
+  # - If `enable` is true, we early return since the actual attribute that holds
+  #   the enabling/disabling is `performance_bar_allowed_group_id`
+  # - If `enable` is false, we set `performance_bar_allowed_group_id` to `nil`
+  def performance_bar_enabled=(enable)
+    return if enable
+
+    self.performance_bar_allowed_group_id = nil
+  end
+
   # Choose one of the available repository storage options. Currently all have
   # equal weighting.
   def pick_repository_storage
diff --git a/app/views/admin/application_settings/_form.html.haml b/app/views/admin/application_settings/_form.html.haml
index 5f5eeb8b9a9c3cada53d9199c8f03fb0ff588c81..7f1e13c7989a66aa2511006b4f564d48e42f621c 100644
--- a/app/views/admin/application_settings/_form.html.haml
+++ b/app/views/admin/application_settings/_form.html.haml
@@ -332,6 +332,22 @@
                 %strong.cred WARNING:
                 Environment variable `prometheus_multiproc_dir` does not exist or is not pointing to a valid directory.
 
+  %fieldset
+    %legend Profiling - Performance Bar
+    %p
+      Enable the Performance Bar for a given group.
+      = link_to icon('question-circle'), help_page_path('administration/monitoring/performance/performance_bar')
+    .form-group
+      .col-sm-offset-2.col-sm-10
+        .checkbox
+          = f.label :performance_bar_enabled do
+            = f.check_box :performance_bar_enabled
+            Enable the Performance Bar
+    .form-group
+      = f.label :performance_bar_allowed_group_id, 'Allowed group', class: 'control-label col-sm-2'
+      .col-sm-10
+        = f.text_field :performance_bar_allowed_group_id, class: 'form-control', placeholder: 'my-org/my-group', value: @application_setting.performance_bar_allowed_group&.full_path
+
   %fieldset
     %legend Background Jobs
     %p
diff --git a/changelogs/unreleased/33929-allow-to-enable-perf-bar-for-a-group.yml b/changelogs/unreleased/33929-allow-to-enable-perf-bar-for-a-group.yml
new file mode 100644
index 0000000000000000000000000000000000000000..810cc8489b5d1cd55eb51bb291f82574f181be74
--- /dev/null
+++ b/changelogs/unreleased/33929-allow-to-enable-perf-bar-for-a-group.yml
@@ -0,0 +1,4 @@
+---
+title: Allow to enable the performance bar per user or Feature group
+merge_request: 12362
+author:
diff --git a/db/migrate/20170706151212_add_performance_bar_allowed_group_id_to_application_settings.rb b/db/migrate/20170706151212_add_performance_bar_allowed_group_id_to_application_settings.rb
new file mode 100644
index 0000000000000000000000000000000000000000..fe9970ddc71e7101a59ade324972a44e9a9aaafa
--- /dev/null
+++ b/db/migrate/20170706151212_add_performance_bar_allowed_group_id_to_application_settings.rb
@@ -0,0 +1,9 @@
+class AddPerformanceBarAllowedGroupIdToApplicationSettings < ActiveRecord::Migration
+  include Gitlab::Database::MigrationHelpers
+
+  DOWNTIME = false
+
+  def change
+    add_column :application_settings, :performance_bar_allowed_group_id, :integer
+  end
+end
diff --git a/db/schema.rb b/db/schema.rb
index 386f304113570790755dbef14f9b25c6d56b063a..023783c2b3bd6ad95f39b01882b8eef9bf57030f 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -126,6 +126,7 @@ ActiveRecord::Schema.define(version: 20170724184243) do
     t.boolean "prometheus_metrics_enabled", default: false, null: false
     t.boolean "help_page_hide_commercial_content", default: false
     t.string "help_page_support_url"
+    t.integer "performance_bar_allowed_group_id"
   end
 
   create_table "audit_events", force: :cascade do |t|
diff --git a/doc/README.md b/doc/README.md
index ebf1a0415d208af8b58f4a8cbcb27b05e2019fdc..9b81c409570c135fe43ccc4c5a417797d165f4f1 100644
--- a/doc/README.md
+++ b/doc/README.md
@@ -167,6 +167,7 @@ have access to GitLab administration tools and settings.
 - [Operations](administration/operations.md): Keeping GitLab up and running.
 - [Polling](administration/polling.md): Configure how often the GitLab UI polls for updates.
 - [Request Profiling](administration/monitoring/performance/request_profiling.md): Get a detailed profile on slow requests.
+- [Performance Bar](administration/monitoring/performance/performance_bar.md): Get performance information for the current page.
 
 ### Customization
 
diff --git a/doc/administration/monitoring/performance/img/performance_bar.png b/doc/administration/monitoring/performance/img/performance_bar.png
new file mode 100644
index 0000000000000000000000000000000000000000..d38293d2ed6c81db52b459496b9a10ea64686f8c
Binary files /dev/null and b/doc/administration/monitoring/performance/img/performance_bar.png differ
diff --git a/doc/administration/monitoring/performance/img/performance_bar_configuration_settings.png b/doc/administration/monitoring/performance/img/performance_bar_configuration_settings.png
new file mode 100644
index 0000000000000000000000000000000000000000..2d64ef8c5fc41a6853b57dae29085ba6798cb6bc
Binary files /dev/null and b/doc/administration/monitoring/performance/img/performance_bar_configuration_settings.png differ
diff --git a/doc/administration/monitoring/performance/img/performance_bar_line_profiling.png b/doc/administration/monitoring/performance/img/performance_bar_line_profiling.png
new file mode 100644
index 0000000000000000000000000000000000000000..7868e2c46d1bff6c4fc8fc02b40317956fe91364
Binary files /dev/null and b/doc/administration/monitoring/performance/img/performance_bar_line_profiling.png differ
diff --git a/doc/administration/monitoring/performance/img/performance_bar_sql_queries.png b/doc/administration/monitoring/performance/img/performance_bar_sql_queries.png
new file mode 100644
index 0000000000000000000000000000000000000000..372ae021f6b2212c4bc96833fe7bda6f8caacc64
Binary files /dev/null and b/doc/administration/monitoring/performance/img/performance_bar_sql_queries.png differ
diff --git a/doc/administration/monitoring/performance/performance_bar.md b/doc/administration/monitoring/performance/performance_bar.md
new file mode 100644
index 0000000000000000000000000000000000000000..ee680c7b258db7244debcf6e06ff4a54767b1e39
--- /dev/null
+++ b/doc/administration/monitoring/performance/performance_bar.md
@@ -0,0 +1,35 @@
+# Performance Bar
+
+A Performance Bar can be displayed, to dig into the performance of a page. When
+activated, it looks as follows:
+
+![Performance Bar](img/performance_bar.png)
+
+It allows you to:
+
+- see the current host serving the page
+- see the timing of the page (backend, frontend)
+- the number of DB queries, the time it took, and the detail of these queries
+![SQL profiling using the Performance Bar](img/performance_bar_sql_queries.png)
+- the number of calls to Redis, and the time it took
+- the number of background jobs created by Sidekiq, and the time it took
+- the number of Ruby GC calls, and the time it took
+- profile the code used to generate the page, line by line
+![Line profiling using the Performance Bar](img/performance_bar_line_profiling.png)
+
+## Enable the Performance Bar via the Admin panel
+
+GitLab Performance Bar is disabled by default. To enable it for a given group,
+navigate to the Admin area in **Settings > Profiling - Performance Bar**
+(`/admin/application_settings`).
+
+The only required setting you need to set is the full path of the group that
+will be allowed to display the Performance Bar.
+Make sure _Enable the Performance Bar_ is checked and hit
+**Save** to save the changes.
+
+---
+
+![GitLab Performance Bar Admin Settings](img/performance_bar_configuration_settings.png)
+
+---
diff --git a/doc/api/README.md b/doc/api/README.md
index b7f6ee69193535cb2c9be29b5b5f4c57d844c14b..95e7a457848b01ba22d0654bc6dc9e8e97ff2560 100644
--- a/doc/api/README.md
+++ b/doc/api/README.md
@@ -17,6 +17,7 @@ following locations:
 - [Deploy Keys](deploy_keys.md)
 - [Environments](environments.md)
 - [Events](events.md)
+- [Feature flags](features.md)
 - [Gitignores templates](templates/gitignores.md)
 - [GitLab CI Config templates](templates/gitlab_ci_ymls.md)
 - [Groups](groups.md)
diff --git a/doc/api/features.md b/doc/api/features.md
index 558869255cccdb98dc21c78f4385fcca2dbf75bd..6861dbf00a2e0723215a82547bc09eb4d6244645 100644
--- a/doc/api/features.md
+++ b/doc/api/features.md
@@ -1,4 +1,4 @@
-# Features API
+# Features flags API
 
 All methods require administrator authorization.
 
@@ -61,7 +61,8 @@ POST /features/:name
 | `feature_group` | string | no | A Feature group name |
 | `user` | string | no | A GitLab username |
 
-Note that `feature_group` and `user` are mutually exclusive.
+Note that you can enable or disable a feature for both a `feature_group` and a
+`user` with a single API call.
 
 ```bash
 curl --data "value=30" --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v4/features/new_library
diff --git a/doc/development/feature_flags.md b/doc/development/feature_flags.md
index 5c6316b9ac69c0c18e5228e23bd5158b7d778426..59e8a087e02ca965319a393d93e94487799dd954 100644
--- a/doc/development/feature_flags.md
+++ b/doc/development/feature_flags.md
@@ -3,5 +3,19 @@
 Starting from GitLab 9.3 we support feature flags via
 [Flipper](https://github.com/jnunemaker/flipper/). You should use the `Feature`
 class (defined in `lib/feature.rb`) in your code to get, set and list feature
-flags. During runtime you can set the values for the gates via the
-[admin API](../api/features.md).
+flags.
+
+During runtime you can set the values for the gates via the
+[features API](../api/features.md) (accessible to admins only).
+
+## Feature groups
+
+Starting from GitLab 9.4 we support feature groups via
+[Flipper groups](https://github.com/jnunemaker/flipper/blob/v0.10.2/docs/Gates.md#2-group).
+
+Feature groups must be defined statically in `lib/feature.rb` (in the
+`.register_feature_groups` method), but their implementation can obviously be
+dynamic (querying the DB etc.).
+
+Once defined in `lib/feature.rb`, you will be able to activate a
+feature for a given feature group via the [`feature_group` param of the features API](../api/features.md#set-or-create-a-feature)
diff --git a/lib/api/features.rb b/lib/api/features.rb
index 217459164638068adbf9d6bf166c1793edcffd0e..9385c6ca174243cc9a9d8b649df6dc450b7b8fd0 100644
--- a/lib/api/features.rb
+++ b/lib/api/features.rb
@@ -14,14 +14,12 @@ module API
         end
       end
 
-      def gate_target(params)
-        if params[:feature_group]
-          Feature.group(params[:feature_group])
-        elsif params[:user]
-          User.find_by_username(params[:user])
-        else
-          gate_value(params)
-        end
+      def gate_targets(params)
+        targets = []
+        targets << Feature.group(params[:feature_group]) if params[:feature_group]
+        targets << User.find_by_username(params[:user]) if params[:user]
+
+        targets
       end
     end
 
@@ -42,18 +40,25 @@ module API
         requires :value, type: String, desc: '`true` or `false` to enable/disable, an integer for percentage of time'
         optional :feature_group, type: String, desc: 'A Feature group name'
         optional :user, type: String, desc: 'A GitLab username'
-        mutually_exclusive :feature_group, :user
       end
       post ':name' do
         feature = Feature.get(params[:name])
-        target = gate_target(params)
+        targets = gate_targets(params)
         value = gate_value(params)
 
         case value
         when true
-          feature.enable(target)
+          if targets.present?
+            targets.each { |target| feature.enable(target) }
+          else
+            feature.enable
+          end
         when false
-          feature.disable(target)
+          if targets.present?
+            targets.each { |target| feature.disable(target) }
+          else
+            feature.disable
+          end
         else
           feature.enable_percentage_of_time(value)
         end
diff --git a/lib/gitlab/performance_bar.rb b/lib/gitlab/performance_bar.rb
index a4c8a77129e5ce450921fe225f46970eeaf155e4..2da2ce45ebc08630cd67989a18d4de6bc9545031 100644
--- a/lib/gitlab/performance_bar.rb
+++ b/lib/gitlab/performance_bar.rb
@@ -1,7 +1,33 @@
 module Gitlab
   module PerformanceBar
-    def self.enabled?
-      Rails.env.development? || Feature.enabled?('gitlab_performance_bar')
+    include Gitlab::CurrentSettings
+
+    ALLOWED_USER_IDS_KEY = 'performance_bar_allowed_user_ids'.freeze
+
+    def self.enabled?(user = nil)
+      return false unless user && allowed_group_id
+
+      allowed_user_ids.include?(user.id)
+    end
+
+    def self.allowed_group_id
+      current_application_settings.performance_bar_allowed_group_id
+    end
+
+    def self.allowed_user_ids
+      Rails.cache.fetch(ALLOWED_USER_IDS_KEY) do
+        group = Group.find_by_id(allowed_group_id)
+
+        if group
+          GroupMembersFinder.new(group).execute.pluck(:user_id)
+        else
+          []
+        end
+      end
+    end
+
+    def self.expire_allowed_user_ids_cache
+      Rails.cache.delete(ALLOWED_USER_IDS_KEY)
     end
   end
 end
diff --git a/spec/features/user_can_display_performance_bar_spec.rb b/spec/features/user_can_display_performance_bar_spec.rb
index 24fff1a3052c770cd7fb24cfada096c044973d4b..9452fe6d92a839aa733e3babd2b03ec0c62e8e8b 100644
--- a/spec/features/user_can_display_performance_bar_spec.rb
+++ b/spec/features/user_can_display_performance_bar_spec.rb
@@ -33,22 +33,24 @@ describe 'User can display performance bar', :js do
     end
   end
 
+  let(:group) { create(:group) }
+
   context 'when user is logged-out' do
     before do
       visit root_path
     end
 
-    context 'when the gitlab_performance_bar feature is disabled' do
+    context 'when the performance_bar feature is disabled' do
       before do
-        Feature.disable('gitlab_performance_bar')
+        stub_application_setting(performance_bar_allowed_group_id: nil)
       end
 
       it_behaves_like 'performance bar is disabled'
     end
 
-    context 'when the gitlab_performance_bar feature is enabled' do
+    context 'when the performance_bar feature is enabled' do
       before do
-        Feature.enable('gitlab_performance_bar')
+        stub_application_setting(performance_bar_allowed_group_id: group.id)
       end
 
       it_behaves_like 'performance bar is disabled'
@@ -57,22 +59,25 @@ describe 'User can display performance bar', :js do
 
   context 'when user is logged-in' do
     before do
-      gitlab_sign_in(create(:user))
+      user = create(:user)
+
+      gitlab_sign_in(user)
+      group.add_guest(user)
 
       visit root_path
     end
 
-    context 'when the gitlab_performance_bar feature is disabled' do
+    context 'when the performance_bar feature is disabled' do
       before do
-        Feature.disable('gitlab_performance_bar')
+        stub_application_setting(performance_bar_allowed_group_id: nil)
       end
 
       it_behaves_like 'performance bar is disabled'
     end
 
-    context 'when the gitlab_performance_bar feature is enabled' do
+    context 'when the performance_bar feature is enabled' do
       before do
-        Feature.enable('gitlab_performance_bar')
+        stub_application_setting(performance_bar_allowed_group_id: group.id)
       end
 
       it_behaves_like 'performance bar is enabled'
diff --git a/spec/lib/gitlab/performance_bar_spec.rb b/spec/lib/gitlab/performance_bar_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..8a586bdbf630658c6cdad3915a6943f6003a29e7
--- /dev/null
+++ b/spec/lib/gitlab/performance_bar_spec.rb
@@ -0,0 +1,92 @@
+require 'spec_helper'
+
+describe Gitlab::PerformanceBar do
+  shared_examples 'allowed user IDs are cached' do
+    before do
+      # Warm the Redis cache
+      described_class.enabled?(user)
+    end
+
+    it 'caches the allowed user IDs in cache', :caching do
+      expect do
+        expect(described_class.enabled?(user)).to be_truthy
+      end.not_to exceed_query_limit(0)
+    end
+  end
+
+  describe '.enabled?' do
+    let(:user) { create(:user) }
+
+    before do
+      stub_application_setting(performance_bar_allowed_group_id: -1)
+    end
+
+    it 'returns false when given user is nil' do
+      expect(described_class.enabled?(nil)).to be_falsy
+    end
+
+    it 'returns false when allowed_group_id is nil' do
+      expect(described_class).to receive(:allowed_group_id).and_return(nil)
+
+      expect(described_class.enabled?(user)).to be_falsy
+    end
+
+    context 'when allowed group ID does not exist' do
+      it 'returns false' do
+        expect(described_class.enabled?(user)).to be_falsy
+      end
+    end
+
+    context 'when allowed group exists' do
+      let!(:my_group) { create(:group, path: 'my-group') }
+
+      before do
+        stub_application_setting(performance_bar_allowed_group_id: my_group.id)
+      end
+
+      context 'when user is not a member of the allowed group' do
+        it 'returns false' do
+          expect(described_class.enabled?(user)).to be_falsy
+        end
+
+        it_behaves_like 'allowed user IDs are cached'
+      end
+
+      context 'when user is a member of the allowed group' do
+        before do
+          my_group.add_developer(user)
+        end
+
+        it 'returns true' do
+          expect(described_class.enabled?(user)).to be_truthy
+        end
+
+        it_behaves_like 'allowed user IDs are cached'
+      end
+    end
+
+    context 'when allowed group is nested', :nested_groups do
+      let!(:nested_my_group) { create(:group, parent: create(:group, path: 'my-org'), path: 'my-group') }
+
+      before do
+        create(:group, path: 'my-group')
+        nested_my_group.add_developer(user)
+        stub_application_setting(performance_bar_allowed_group_id: nested_my_group.id)
+      end
+
+      it 'returns the nested group' do
+        expect(described_class.enabled?(user)).to be_truthy
+      end
+    end
+
+    context 'when a nested group has the same path', :nested_groups do
+      before do
+        create(:group, :nested, path: 'my-group').add_developer(user)
+      end
+
+      it 'returns false' do
+        expect(described_class.enabled?(user)).to be_falsy
+      end
+    end
+  end
+end
diff --git a/spec/models/application_setting_spec.rb b/spec/models/application_setting_spec.rb
index 166a4474abf9482bf8c28358f2dbc0ba4f7a8ebb..fb485d0b2c672502f8914812590b787e8b83eb9e 100644
--- a/spec/models/application_setting_spec.rb
+++ b/spec/models/application_setting_spec.rb
@@ -214,6 +214,160 @@ describe ApplicationSetting, models: true do
     end
   end
 
+  describe 'performance bar settings' do
+    describe 'performance_bar_allowed_group_id=' do
+      context 'with a blank path' do
+        before do
+          setting.performance_bar_allowed_group_id = create(:group).full_path
+        end
+
+        it 'persists nil for a "" path and clears allowed user IDs cache' do
+          expect(Gitlab::PerformanceBar).to receive(:expire_allowed_user_ids_cache)
+
+          setting.performance_bar_allowed_group_id = ''
+
+          expect(setting.performance_bar_allowed_group_id).to be_nil
+        end
+      end
+
+      context 'with an invalid path' do
+        it 'does not persist an invalid group path' do
+          setting.performance_bar_allowed_group_id = 'foo'
+
+          expect(setting.performance_bar_allowed_group_id).to be_nil
+        end
+      end
+
+      context 'with a path to an existing group' do
+        let(:group) { create(:group) }
+
+        it 'persists a valid group path and clears allowed user IDs cache' do
+          expect(Gitlab::PerformanceBar).to receive(:expire_allowed_user_ids_cache)
+
+          setting.performance_bar_allowed_group_id = group.full_path
+
+          expect(setting.performance_bar_allowed_group_id).to eq(group.id)
+        end
+
+        context 'when the given path is the same' do
+          context 'with a blank path' do
+            before do
+              setting.performance_bar_allowed_group_id = nil
+            end
+
+            it 'clears the cached allowed user IDs' do
+              expect(Gitlab::PerformanceBar).not_to receive(:expire_allowed_user_ids_cache)
+
+              setting.performance_bar_allowed_group_id = ''
+            end
+          end
+
+          context 'with a valid path' do
+            before do
+              setting.performance_bar_allowed_group_id = group.full_path
+            end
+
+            it 'clears the cached allowed user IDs' do
+              expect(Gitlab::PerformanceBar).not_to receive(:expire_allowed_user_ids_cache)
+
+              setting.performance_bar_allowed_group_id = group.full_path
+            end
+          end
+        end
+      end
+    end
+
+    describe 'performance_bar_allowed_group' do
+      context 'with no performance_bar_allowed_group_id saved' do
+        it 'returns nil' do
+          expect(setting.performance_bar_allowed_group).to be_nil
+        end
+      end
+
+      context 'with a performance_bar_allowed_group_id saved' do
+        let(:group) { create(:group) }
+
+        before do
+          setting.performance_bar_allowed_group_id = group.full_path
+        end
+
+        it 'returns the group' do
+          expect(setting.performance_bar_allowed_group).to eq(group)
+        end
+      end
+    end
+
+    describe 'performance_bar_enabled' do
+      context 'with the Performance Bar is enabled' do
+        let(:group) { create(:group) }
+
+        before do
+          setting.performance_bar_allowed_group_id = group.full_path
+        end
+
+        it 'returns true' do
+          expect(setting.performance_bar_enabled).to be_truthy
+        end
+      end
+    end
+
+    describe 'performance_bar_enabled=' do
+      context 'when the performance bar is enabled' do
+        let(:group) { create(:group) }
+
+        before do
+          setting.performance_bar_allowed_group_id = group.full_path
+        end
+
+        context 'when passing true' do
+          it 'does not clear allowed user IDs cache' do
+            expect(Gitlab::PerformanceBar).not_to receive(:expire_allowed_user_ids_cache)
+
+            setting.performance_bar_enabled = true
+
+            expect(setting.performance_bar_allowed_group_id).to eq(group.id)
+            expect(setting.performance_bar_enabled).to be_truthy
+          end
+        end
+
+        context 'when passing false' do
+          it 'disables the performance bar and clears allowed user IDs cache' do
+            expect(Gitlab::PerformanceBar).to receive(:expire_allowed_user_ids_cache)
+
+            setting.performance_bar_enabled = false
+
+            expect(setting.performance_bar_allowed_group_id).to be_nil
+            expect(setting.performance_bar_enabled).to be_falsey
+          end
+        end
+      end
+
+      context 'when the performance bar is disabled' do
+        context 'when passing true' do
+          it 'does nothing and does not clear allowed user IDs cache' do
+            expect(Gitlab::PerformanceBar).not_to receive(:expire_allowed_user_ids_cache)
+
+            setting.performance_bar_enabled = true
+
+            expect(setting.performance_bar_allowed_group_id).to be_nil
+            expect(setting.performance_bar_enabled).to be_falsey
+          end
+        end
+
+        context 'when passing false' do
+          it 'does nothing and does not clear allowed user IDs cache' do
+            expect(Gitlab::PerformanceBar).not_to receive(:expire_allowed_user_ids_cache)
+
+            setting.performance_bar_enabled = false
+
+            expect(setting.performance_bar_allowed_group_id).to be_nil
+            expect(setting.performance_bar_enabled).to be_falsey
+          end
+        end
+      end
+    end
+  end
+
   describe 'usage ping settings' do
     context 'when the usage ping is disabled in gitlab.yml' do
       before do
diff --git a/spec/requests/api/features_spec.rb b/spec/requests/api/features_spec.rb
index 1d8aaeea8f2279f58a9b2ba4025207925609cce1..7e21006b2548170402ba2eb2334dd3b34073e93d 100644
--- a/spec/requests/api/features_spec.rb
+++ b/spec/requests/api/features_spec.rb
@@ -113,6 +113,20 @@ describe API::Features do
               { 'key' => 'actors', 'value' => ["User:#{user.id}"] }
             ])
         end
+
+        it 'creates an enabled feature for the given user and feature group when passed user=username and feature_group=perf_team' do
+          post api("/features/#{feature_name}", admin), value: 'true', user: user.username, feature_group: 'perf_team'
+
+          expect(response).to have_http_status(201)
+          expect(json_response).to eq(
+            'name' => 'my_feature',
+            'state' => 'conditional',
+            'gates' => [
+              { 'key' => 'boolean', 'value' => false },
+              { 'key' => 'groups', 'value' => ['perf_team'] },
+              { 'key' => 'actors', 'value' => ["User:#{user.id}"] }
+            ])
+        end
       end
 
       it 'creates a feature with the given percentage if passed an integer' do