diff --git a/Gemfile b/Gemfile
index ebfa37967248110875b61d5224be43d044083076..37964d454fab1f28baaaed79aae3815cbf9dba04 100644
--- a/Gemfile
+++ b/Gemfile
@@ -184,8 +184,8 @@ group :unicorn do
 end
 
 group :puma do
-  gem 'gitlab-puma', '~> 4.3.3.gitlab.2', require: false
-  gem 'gitlab-puma_worker_killer', '~> 0.1.1.gitlab.1', require: false
+  gem 'puma', '~> 5.1.1', require: false
+  gem 'puma_worker_killer', '~> 0.3.1', require: false
 end
 
 # State machine
@@ -410,7 +410,7 @@ group :test do
   gem 'rspec_profiling', '~> 0.0.6'
   gem 'rspec-parameterized', require: false
 
-  gem 'capybara', '~> 3.33.0'
+  gem 'capybara', '~> 3.34.0'
   gem 'capybara-screenshot', '~> 1.0.22'
   gem 'selenium-webdriver', '~> 3.142'
 
diff --git a/Gemfile.lock b/Gemfile.lock
index 427596e619ca5024a7c86e6807311674391ef361..47538b82386c90da74d3070bf9dc65fd6dcd0d36 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -152,7 +152,7 @@ GEM
       bundler (>= 1.2.0, < 3)
       thor (~> 0.18)
     byebug (11.1.3)
-    capybara (3.33.0)
+    capybara (3.34.0)
       addressable
       mini_mime (>= 0.1.3)
       nokogiri (~> 1.8)
@@ -447,11 +447,6 @@ GEM
     gitlab-markup (1.7.1)
     gitlab-net-dns (0.9.1)
     gitlab-pg_query (1.3.1)
-    gitlab-puma (4.3.5.gitlab.3)
-      nio4r (~> 2.0)
-    gitlab-puma_worker_killer (0.1.1.gitlab.1)
-      get_process_mem (~> 0.2)
-      gitlab-puma (>= 2.7, < 5)
     gitlab-sidekiq-fetcher (0.5.2)
       sidekiq (~> 5)
     gitlab-styles (5.4.0)
@@ -876,6 +871,11 @@ GEM
     pry-rails (0.3.9)
       pry (>= 0.10.4)
     public_suffix (4.0.6)
+    puma (5.1.1)
+      nio4r (~> 2.0)
+    puma_worker_killer (0.3.1)
+      get_process_mem (~> 0.2)
+      puma (>= 2.7)
     pyu-ruby-sasl (0.0.3.3)
     raabro (1.1.6)
     racc (1.5.2)
@@ -1301,7 +1301,7 @@ DEPENDENCIES
   browser (~> 4.2)
   bullet (~> 6.1.0)
   bundler-audit (~> 0.6.1)
-  capybara (~> 3.33.0)
+  capybara (~> 3.34.0)
   capybara-screenshot (~> 1.0.22)
   carrierwave (~> 1.3)
   charlock_holmes (~> 0.7.7)
@@ -1365,8 +1365,6 @@ DEPENDENCIES
   gitlab-mail_room (~> 0.0.8)
   gitlab-markup (~> 1.7.1)
   gitlab-net-dns (~> 0.9.1)
-  gitlab-puma (~> 4.3.3.gitlab.2)
-  gitlab-puma_worker_killer (~> 0.1.1.gitlab.1)
   gitlab-sidekiq-fetcher (= 0.5.2)
   gitlab-styles (~> 5.4.0)
   gitlab_chronic_duration (~> 0.10.6.2)
@@ -1460,6 +1458,8 @@ DEPENDENCIES
   prometheus-client-mmap (~> 0.12.0)
   pry-byebug (~> 3.9.0)
   pry-rails (~> 0.3.9)
+  puma (~> 5.1.1)
+  puma_worker_killer (~> 0.3.1)
   rack (~> 2.2.3)
   rack-attack (~> 6.3.0)
   rack-cors (~> 1.0.6)
diff --git a/changelogs/unreleased/update-puma-to-v-5.yml b/changelogs/unreleased/update-puma-to-v-5.yml
new file mode 100644
index 0000000000000000000000000000000000000000..fa80a47718fed01ef4af0f102ae228c7eb4b2057
--- /dev/null
+++ b/changelogs/unreleased/update-puma-to-v-5.yml
@@ -0,0 +1,5 @@
+---
+title: Update puma & puma_worker_killer to upstream
+merge_request: 48897
+author:
+type: changed
diff --git a/config/puma.example.development.rb b/config/puma.example.development.rb
index ecbfac660c9e4b7070731b2ddfcc58cd79830a28..7e616ee476807bf41a424d4fcdf179c9155501b4 100644
--- a/config/puma.example.development.rb
+++ b/config/puma.example.development.rb
@@ -79,6 +79,11 @@
 #
 worker_timeout 60
 
+# https://github.com/puma/puma/blob/master/5.0-Upgrade.md#lower-latency-better-throughput
+if defined?(wait_for_less_busy_worker)
+  wait_for_less_busy_worker ENV.fetch('PUMA_WAIT_FOR_LESS_BUSY_WORKER', 0.001).to_f
+end
+
 # Use json formatter
 require_relative "/home/git/gitlab/lib/gitlab/puma_logging/json_formatter"
 
diff --git a/config/puma.rb.example b/config/puma.rb.example
index cd7adca157f2a0335b9a4af68c9131a3e996ed69..25e38626260701607f4db8ec730e24dd90ff3516 100644
--- a/config/puma.rb.example
+++ b/config/puma.rb.example
@@ -69,10 +69,15 @@ tag 'gitlab-puma-worker'
 #
 worker_timeout 60
 
+# https://github.com/puma/puma/blob/master/5.0-Upgrade.md#lower-latency-better-throughput
+if defined?(wait_for_less_busy_worker)
+  wait_for_less_busy_worker ENV.fetch('PUMA_WAIT_FOR_LESS_BUSY_WORKER', 0.001).to_f
+end
+
 # Use json formatter
 require_relative "/home/git/gitlab/lib/gitlab/puma_logging/json_formatter"
 
 json_formatter = Gitlab::PumaLogging::JSONFormatter.new
 log_formatter do |str|
   json_formatter.call(str)
-end
\ No newline at end of file
+end
diff --git a/config/puma_actioncable.example.development.rb b/config/puma_actioncable.example.development.rb
index c975f9e4f9badbfeee890c5255037fed16190901..106932606e0e2d8d844858f19ff472c39d1bd766 100644
--- a/config/puma_actioncable.example.development.rb
+++ b/config/puma_actioncable.example.development.rb
@@ -79,6 +79,11 @@
 #
 worker_timeout 60
 
+# https://github.com/puma/puma/blob/master/5.0-Upgrade.md#lower-latency-better-throughput
+if defined?(wait_for_less_busy_worker)
+  wait_for_less_busy_worker ENV.fetch('PUMA_WAIT_FOR_LESS_BUSY_WORKER', 0.001).to_f
+end
+
 # Use json formatter
 require_relative "/home/git/gitlab/lib/gitlab/puma_logging/json_formatter"