diff --git a/app/models/environment.rb b/app/models/environment.rb
index ed4369f7fd68f39324281c4e7787d971ac5654d7..6fce9327cf7955b47157b0521b04f5a2bd6fd3b6 100644
--- a/app/models/environment.rb
+++ b/app/models/environment.rb
@@ -571,6 +571,18 @@ def deploy_freezes
     end
   end
 
+  def ensure_environment_tier
+    self.tier ||= guess_tier
+  end
+
+  def set_default_auto_stop_setting
+    self.auto_stop_setting = if Feature.enabled?(:new_default_for_auto_stop, project)
+                               production? || staging? ? :with_action : :always
+                             else
+                               :always
+                             end
+  end
+
   private
 
   def run_stop_action!(job, link_identity:)
@@ -617,10 +629,6 @@ def generate_slug
     self.slug = Gitlab::Slug::Environment.new(name).generate
   end
 
-  def ensure_environment_tier
-    self.tier ||= guess_tier
-  end
-
   def merge_request_not_changed
     if merge_request_id_changed? && persisted?
       errors.add(:merge_request, 'merge_request cannot be changed')
diff --git a/app/services/environments/create_service.rb b/app/services/environments/create_service.rb
index 8a576c923287e7d590b175c9649b28ae8833a34a..6736e98404ffab69df6a190cee9290afa3923671 100644
--- a/app/services/environments/create_service.rb
+++ b/app/services/environments/create_service.rb
@@ -20,7 +20,10 @@ def execute
       end
 
       begin
-        environment = project.environments.create!(**params.slice(*ALLOWED_ATTRIBUTES))
+        environment = project.environments.new(**params.slice(*ALLOWED_ATTRIBUTES))
+        environment.ensure_environment_tier
+        environment.set_default_auto_stop_setting unless params[:auto_stop_setting]
+        environment.save!
         ServiceResponse.success(payload: { environment: environment })
       rescue ActiveRecord::RecordInvalid => err
         ServiceResponse.error(message: err.record.errors.full_messages, payload: { environment: nil })
diff --git a/config/feature_flags/beta/new_default_for_auto_stop.yml b/config/feature_flags/beta/new_default_for_auto_stop.yml
new file mode 100644
index 0000000000000000000000000000000000000000..c730a05d18ad94006126c0f7d538d96d49baa11e
--- /dev/null
+++ b/config/feature_flags/beta/new_default_for_auto_stop.yml
@@ -0,0 +1,9 @@
+---
+name: new_default_for_auto_stop
+feature_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/428625
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/181746
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/523169
+milestone: '17.10'
+group: group::environments
+type: beta
+default_enabled: false
diff --git a/doc/ci/environments/_index.md b/doc/ci/environments/_index.md
index 0ba973e707334517241714c8c02fe4fff4a542a5..ae783dd12c4810812e3f505b7d19221d5d9444be 100644
--- a/doc/ci/environments/_index.md
+++ b/doc/ci/environments/_index.md
@@ -421,6 +421,18 @@ To stop an environment in the GitLab UI:
 1. Next to the environment you want to stop, select **Stop**.
 1. On the confirmation dialog, select **Stop environment**.
 
+### Default stopping behavior
+
+GitLab automatically stops environments when the associated branch is deleted or merged.
+This behavior persists even if no explicit `on_stop` CI/CD job is defined.
+
+However, [issue 428625](https://gitlab.com/gitlab-org/gitlab/-/issues/428625) proposes to change this behavior
+so that production and staging environments stop only if an explicit `on_stop` CI/CD job is defined.
+
+You can configure an environment's stopping behavior with the
+[`auto_stop_setting`](../../api/environments.md#update-an-existing-environment)
+parameter in the Environments API.
+
 ### Stop an environment when a branch is deleted
 
 You can configure environments to stop when a branch is deleted.
diff --git a/lib/api/environments.rb b/lib/api/environments.rb
index 89221534fea7f8bd2a4ff226322defd57f3438f9..9530fbde5f9c6a4b7260ee6334a9e1c7fb4bb541 100644
--- a/lib/api/environments.rb
+++ b/lib/api/environments.rb
@@ -72,7 +72,7 @@ class Environments < ::API::Base
         optional :kubernetes_namespace, type: String, desc: 'The Kubernetes namespace to associate with this environment'
         optional :flux_resource_path, type: String, desc: 'The Flux resource path to associate with this environment'
         optional :description, type: String, desc: 'The description of the environment'
-        optional :auto_stop_setting, type: String, default: "always", values: Environment.auto_stop_settings.keys, desc: 'The auto stop setting for the environment. Allowed values are `always` and `with_action`'
+        optional :auto_stop_setting, type: String, values: Environment.auto_stop_settings.keys, desc: 'The auto stop setting for the environment. Allowed values are `always` and `with_action`'
       end
       route_setting :authentication, job_token_allowed: true
       route_setting :authorization, job_token_policies: :admin_environments
diff --git a/spec/models/environment_spec.rb b/spec/models/environment_spec.rb
index 48c292a7b1fdfae1897c0905b383751b25dc0ec7..ac5f1ab56d3bf25bae58aea51db2ca50c795521b 100644
--- a/spec/models/environment_spec.rb
+++ b/spec/models/environment_spec.rb
@@ -2325,4 +2325,48 @@ def create_deployment_with_stop_action(status, pipeline, stop_action_name)
       is_expected.to match_array([environment])
     end
   end
+
+  describe '#set_default_auto_stop_setting' do
+    let(:environment) { create(:environment, project: project) }
+
+    subject { environment.set_default_auto_stop_setting }
+
+    context 'when auto_stop_setting is not set' do
+      %w[production staging].each do |tier|
+        context "when #{tier} environment" do
+          let(:environment) { create(:environment, project: project, name: 'production', tier: :production) }
+
+          it 'sets auto_stop_setting to :with_action' do
+            expect { subject }.to change { environment.auto_stop_setting }.from('always').to('with_action')
+          end
+        end
+      end
+
+      %w[testing development other].each do |tier|
+        context "when #{tier} environment" do
+          let(:environment) { create(:environment, project: project, name: tier, tier: tier.to_sym) }
+
+          it 'sets auto_stop_setting to :always' do
+            expect { subject }.not_to change { environment.auto_stop_setting }
+          end
+        end
+      end
+
+      context 'when feature flag is disabled' do
+        before do
+          stub_feature_flags(new_default_for_auto_stop: false)
+        end
+
+        %w[production staging testing development other].each do |tier|
+          context "when #{tier} environment" do
+            let(:environment) { create(:environment, project: project, name: tier, tier: tier.to_sym) }
+
+            it 'sets auto_stop_setting to :always' do
+              expect { subject }.not_to change { environment.auto_stop_setting }
+            end
+          end
+        end
+      end
+    end
+  end
 end
diff --git a/spec/requests/api/environments_spec.rb b/spec/requests/api/environments_spec.rb
index 5ed6e1c5501ab3e8d7ef80a3babd9d4501aa2e8e..0e4bfb77692185564eaf74dc8e6020ad653d7fba 100644
--- a/spec/requests/api/environments_spec.rb
+++ b/spec/requests/api/environments_spec.rb
@@ -151,7 +151,16 @@
         expect(json_response['slug']).to eq('mepmep')
         expect(json_response['tier']).to eq('staging')
         expect(json_response['external']).to be_nil
-        expect(json_response['auto_stop_setting']).to eq('always')
+        expect(json_response['auto_stop_setting']).to eq('with_action')
+      end
+
+      context 'when the tier is development' do
+        it 'creates an environment with auto_stop_setting set to always' do
+          post api("/projects/#{project.id}/environments", user), params: { name: "mepmep", tier: 'development' }
+
+          expect(response).to have_gitlab_http_status(:created)
+          expect(json_response['auto_stop_setting']).to eq('always')
+        end
       end
 
       context 'when associating a cluster agent' do
diff --git a/spec/services/environments/create_service_spec.rb b/spec/services/environments/create_service_spec.rb
index 5e57311e9ec3b06bd25fb033db14f6b8f1d245c5..00ca4dda1b3331285f113e38694938524509f9e7 100644
--- a/spec/services/environments/create_service_spec.rb
+++ b/spec/services/environments/create_service_spec.rb
@@ -14,7 +14,10 @@
   describe '#execute' do
     subject { service.execute }
 
-    let(:params) { { name: 'production', description: 'description', external_url: 'https://gitlab.com', tier: :production, auto_stop_setting: :always } }
+    let(:auto_stop_setting) { :always }
+    let(:env_name) { 'production' }
+    let(:tier) { nil }
+    let(:params) { { name: env_name, description: 'description', tier: tier, external_url: 'https://gitlab.com', auto_stop_setting: auto_stop_setting } }
 
     it 'creates an environment' do
       expect { subject }.to change { ::Environment.count }.by(1)
@@ -31,6 +34,119 @@
       expect(response.payload[:environment].auto_stop_setting).to eq('always')
     end
 
+    context 'when tier is provided' do
+      let(:tier) { 'production' }
+      let(:env_name) { 'testing' }
+
+      it 'creates an environment' do
+        expect { subject }.to change { ::Environment.count }.by(1)
+      end
+
+      it 'returns successful response' do
+        response = subject
+
+        expect(response).to be_success
+        expect(response.payload[:environment].name).to eq('testing')
+        expect(response.payload[:environment].tier).to eq('production')
+        expect(response.payload[:environment].auto_stop_setting).to eq('always')
+      end
+    end
+
+    context 'when tier is not provided' do
+      context 'when environment name is production' do
+        let(:env_name) { 'production' }
+
+        it 'guesses tier to production' do
+          response = subject
+
+          expect(response).to be_success
+          expect(response.payload[:environment].name).to eq('production')
+          expect(response.payload[:environment].tier).to eq('production')
+        end
+      end
+
+      context 'when environment name is testing' do
+        let(:env_name) { 'testing' }
+
+        it 'guesses tier to testing' do
+          response = subject
+
+          expect(response).to be_success
+          expect(response.payload[:environment].name).to eq('testing')
+          expect(response.payload[:environment].tier).to eq('testing')
+        end
+      end
+    end
+
+    context 'when auto_stop_setting is not provided' do
+      context 'when feature flag is disabled' do
+        before do
+          stub_feature_flags(new_default_for_auto_stop: false)
+        end
+
+        let(:tier) { 'production' }
+        let(:env_name) { 'production' }
+        let(:auto_stop_setting) { nil }
+
+        it 'creates an environment' do
+          expect { subject }.to change { ::Environment.count }.by(1)
+        end
+
+        it 'sets :always for auto_stop_setting' do
+          expect_next_instance_of(Environment) do |instance|
+            expect(instance).to receive(:set_default_auto_stop_setting).and_call_original
+          end
+
+          response = subject
+          expect(response).to be_success
+          expect(response.payload[:environment].name).to eq(env_name)
+          expect(response.payload[:environment].auto_stop_setting).to eq('always')
+        end
+      end
+
+      context 'when environment tier is production' do
+        let(:tier) { 'production' }
+        let(:env_name) { 'production' }
+        let(:auto_stop_setting) { nil }
+
+        it 'creates an environment' do
+          expect { subject }.to change { ::Environment.count }.by(1)
+        end
+
+        it 'sets :with_action for auto_stop_setting' do
+          expect_next_instance_of(Environment) do |instance|
+            expect(instance).to receive(:set_default_auto_stop_setting).and_call_original
+          end
+
+          response = subject
+          expect(response).to be_success
+          expect(response.payload[:environment].name).to eq(env_name)
+          expect(response.payload[:environment].auto_stop_setting).to eq('with_action')
+        end
+      end
+
+      context 'when environment tier is development' do
+        let(:tier) { 'development' }
+        let(:env_name) { 'development' }
+        let(:auto_stop_setting) { nil }
+
+        it 'creates an environment' do
+          expect { subject }.to change { ::Environment.count }.by(1)
+        end
+
+        it 'sets :always for auto_stop_setting' do
+          expect_next_instance_of(Environment) do |instance|
+            expect(instance).to receive(:set_default_auto_stop_setting).and_call_original
+          end
+
+          response = subject
+          expect(response).to be_success
+          expect(response.payload[:environment].name).to eq(env_name)
+          expect(response.payload[:environment].auto_stop_setting).to eq('always')
+        end
+      end
+    end
+
     context 'with a cluster agent' do
       let_it_be(:agent_management_project) { create(:project) }
       let_it_be(:cluster_agent) { create(:cluster_agent, project: agent_management_project) }