diff --git a/doc/settings/redis.md b/doc/settings/redis.md
index 7244146d42bb12026ffc00fa9acaf8d6d57b4fbc_ZG9jL3NldHRpbmdzL3JlZGlzLm1k..ab5ec89a6381cd873d9826c9e8cce9d7ba88a5fd_ZG9jL3NldHRpbmdzL3JlZGlzLm1k 100644
--- a/doc/settings/redis.md
+++ b/doc/settings/redis.md
@@ -232,6 +232,18 @@
 redis['io_threads_do_reads'] = true
 ```
 
+### Client Timeouts
+
+By default, the [Ruby client for Redis](https://github.com/redis-rb/redis-client?tab=readme-ov-file#configuration)
+uses a 1-second default for the connect, read, and write timeouts. You may need to tune these values to account for local network latency.
+For example, if you see `Connection timed out - user specified timeout` errors, you may need to raise `connect_timeout`:
+
+```ruby
+gitlab_rails['redis_connect_timeout'] = 3
+gitlab_rails['redis_read_timeout'] = 1
+gitlab_rails['redis_write_timeout'] = 1
+```
+
 ## Provide sensitive configuration to Redis clients without plain text storage
 
 For more information, see the example in [configuration documentation](../settings/configuration.md#provide-redis-password-to-redis-server-and-client-components).
diff --git a/files/gitlab-config-template/gitlab.rb.template b/files/gitlab-config-template/gitlab.rb.template
index 7244146d42bb12026ffc00fa9acaf8d6d57b4fbc_ZmlsZXMvZ2l0bGFiLWNvbmZpZy10ZW1wbGF0ZS9naXRsYWIucmIudGVtcGxhdGU=..ab5ec89a6381cd873d9826c9e8cce9d7ba88a5fd_ZmlsZXMvZ2l0bGFiLWNvbmZpZy10ZW1wbGF0ZS9naXRsYWIucmIudGVtcGxhdGU= 100644
--- a/files/gitlab-config-template/gitlab.rb.template
+++ b/files/gitlab-config-template/gitlab.rb.template
@@ -810,6 +810,9 @@
 # gitlab_rails['redis_tls_ca_cert_file'] = '/opt/gitlab/embedded/ssl/certs/cacert.pem'
 # gitlab_rails['redis_tls_client_cert_file'] = nil
 # gitlab_rails['redis_tls_client_key_file'] = nil
+# gitlab_rails['redis_connect_timeout'] = nil
+# gitlab_rails['redis_read_timeout'] = nil
+# gitlab_rails['redis_write_timeout'] = nil
 
 #### Redis local UNIX socket (will be disabled if TCP method is used)
 # gitlab_rails['redis_socket'] = "/var/opt/gitlab/redis/redis.socket"
diff --git a/files/gitlab-cookbooks/gitlab/attributes/default.rb b/files/gitlab-cookbooks/gitlab/attributes/default.rb
index 7244146d42bb12026ffc00fa9acaf8d6d57b4fbc_ZmlsZXMvZ2l0bGFiLWNvb2tib29rcy9naXRsYWIvYXR0cmlidXRlcy9kZWZhdWx0LnJi..ab5ec89a6381cd873d9826c9e8cce9d7ba88a5fd_ZmlsZXMvZ2l0bGFiLWNvb2tib29rcy9naXRsYWIvYXR0cmlidXRlcy9kZWZhdWx0LnJi 100644
--- a/files/gitlab-cookbooks/gitlab/attributes/default.rb
+++ b/files/gitlab-cookbooks/gitlab/attributes/default.rb
@@ -446,6 +446,9 @@
 default['gitlab']['gitlab_rails']['redis_host'] = "127.0.0.1"
 default['gitlab']['gitlab_rails']['redis_port'] = nil
 default['gitlab']['gitlab_rails']['redis_ssl'] = false
+default['gitlab']['gitlab_rails']['redis_connect_timeout'] = nil
+default['gitlab']['gitlab_rails']['redis_read_timeout'] = nil
+default['gitlab']['gitlab_rails']['redis_write_timeout'] = nil
 default['gitlab']['gitlab_rails']['redis_tls_ca_cert_dir'] = "#{node['package']['install-dir']}/embedded/ssl/certs/"
 default['gitlab']['gitlab_rails']['redis_tls_ca_cert_file'] = "#{node['package']['install-dir']}/embedded/ssl/certs/cacert.pem"
 default['gitlab']['gitlab_rails']['redis_tls_client_cert_file'] = nil
diff --git a/files/gitlab-cookbooks/gitlab/recipes/gitlab-rails.rb b/files/gitlab-cookbooks/gitlab/recipes/gitlab-rails.rb
index 7244146d42bb12026ffc00fa9acaf8d6d57b4fbc_ZmlsZXMvZ2l0bGFiLWNvb2tib29rcy9naXRsYWIvcmVjaXBlcy9naXRsYWItcmFpbHMucmI=..ab5ec89a6381cd873d9826c9e8cce9d7ba88a5fd_ZmlsZXMvZ2l0bGFiLWNvb2tib29rcy9naXRsYWIvcmVjaXBlcy9naXRsYWItcmFpbHMucmI= 100644
--- a/files/gitlab-cookbooks/gitlab/recipes/gitlab-rails.rb
+++ b/files/gitlab-cookbooks/gitlab/recipes/gitlab-rails.rb
@@ -200,6 +200,9 @@
 redis_tls_client_key_file = node['gitlab']['gitlab_rails']['redis_tls_client_key_file']
 redis_encrypted_settings_file = node['gitlab']['gitlab_rails']['redis_encrypted_settings_file']
 redis_extra_config_command = node['gitlab']['gitlab_rails']['redis_extra_config_command']
+redis_connect_timeout = node['gitlab']['gitlab_rails']['redis_connect_timeout']
+redis_read_timeout = node['gitlab']['gitlab_rails']['redis_read_timeout']
+redis_write_timeout = node['gitlab']['gitlab_rails']['redis_write_timeout']
 
 templatesymlink "Create a secrets.yml and create a symlink to Rails root" do
   link_from File.join(gitlab_rails_source_dir, "config/secrets.yml")
@@ -238,7 +241,10 @@
     redis_tls_client_cert_file: redis_tls_client_cert_file,
     redis_tls_client_key_file: redis_tls_client_key_file,
     redis_encrypted_settings_file: redis_encrypted_settings_file,
-    redis_extra_config_command: redis_extra_config_command
+    redis_extra_config_command: redis_extra_config_command,
+    redis_connect_timeout: redis_connect_timeout,
+    redis_read_timeout: redis_read_timeout,
+    redis_write_timeout: redis_write_timeout
   )
   dependent_services.each { |svc| notifies :restart, svc }
   sensitive true
diff --git a/files/gitlab-cookbooks/gitlab/templates/default/resque.yml.erb b/files/gitlab-cookbooks/gitlab/templates/default/resque.yml.erb
index 7244146d42bb12026ffc00fa9acaf8d6d57b4fbc_ZmlsZXMvZ2l0bGFiLWNvb2tib29rcy9naXRsYWIvdGVtcGxhdGVzL2RlZmF1bHQvcmVzcXVlLnltbC5lcmI=..ab5ec89a6381cd873d9826c9e8cce9d7ba88a5fd_ZmlsZXMvZ2l0bGFiLWNvb2tib29rcy9naXRsYWIvdGVtcGxhdGVzL2RlZmF1bHQvcmVzcXVlLnltbC5lcmI= 100644
--- a/files/gitlab-cookbooks/gitlab/templates/default/resque.yml.erb
+++ b/files/gitlab-cookbooks/gitlab/templates/default/resque.yml.erb
@@ -5,6 +5,15 @@
   <% if !@redis_enable_client %>
   id:
   <% end %>
+  <% if @redis_connect_timeout %>
+  connect_timeout: <%= @redis_connect_timeout %>
+  <% end %>
+  <% if @redis_read_timeout %>
+  read_timeout: <%= @redis_read_timeout %>
+  <% end %>
+  <% if @redis_write_timeout %>
+  write_timeout: <%= @redis_write_timeout %>
+  <% end %>
   <% if defined?(@cluster_nodes) && !@cluster_nodes.empty? %>
   <%- if @cluster_username %>username: <%= @cluster_username %><% end %>
   <%- if @cluster_password %>password: <%= @cluster_password %><% end %>
diff --git a/spec/chef/cookbooks/gitlab/recipes/gitlab-rails_spec.rb b/spec/chef/cookbooks/gitlab/recipes/gitlab-rails_spec.rb
index 7244146d42bb12026ffc00fa9acaf8d6d57b4fbc_c3BlYy9jaGVmL2Nvb2tib29rcy9naXRsYWIvcmVjaXBlcy9naXRsYWItcmFpbHNfc3BlYy5yYg==..ab5ec89a6381cd873d9826c9e8cce9d7ba88a5fd_c3BlYy9jaGVmL2Nvb2tib29rcy9naXRsYWIvcmVjaXBlcy9naXRsYWItcmFpbHNfc3BlYy5yYg== 100644
--- a/spec/chef/cookbooks/gitlab/recipes/gitlab-rails_spec.rb
+++ b/spec/chef/cookbooks/gitlab/recipes/gitlab-rails_spec.rb
@@ -229,6 +229,9 @@
         expect(chef_run).to render_file(config_file).with_content { |content|
           expect(content).to match(%r(url: unix:///var/opt/gitlab/redis/redis.socket$))
           expect(content).not_to match(/id:/)
+          expect(content).not_to match(/connect_timeout:/)
+          expect(content).not_to match(/read_timeout:/)
+          expect(content).not_to match(/write_timeout:/)
         }
       end
 
@@ -243,6 +246,9 @@
 
         expect(chef_run).to render_file('/var/opt/gitlab/gitlab-rails/etc/cable.yml').with_content { |content|
           expect(content).to match(%r(url: unix:///var/opt/gitlab/redis/redis.socket$))
+          expect(content).not_to match(/connect_timeout:/)
+          expect(content).not_to match(/read_timeout:/)
+          expect(content).not_to match(/write_timeout:/)
         }
       end
 
@@ -268,8 +274,11 @@
             redis_port: 8888,
             redis_database: 2,
             redis_password: 'my pass',
-            redis_enable_client: false
+            redis_enable_client: false,
+            redis_connect_timeout: 3,
+            redis_read_timeout: 4,
+            redis_write_timeout: 5
           }
         )
       end
 
@@ -272,9 +281,9 @@
           }
         )
       end
 
-      it 'creates the config file with custom host, port, password and database' do
+      it 'creates the config file with custom host, port, password, database, and timeouts' do
         expect(chef_run).to create_templatesymlink('Create a resque.yml and create a symlink to Rails root').with_variables(
           hash_including(
             redis_url: URI('redis://:my%20pass@redis.example.com:8888/2'),
             redis_sentinels: [],
@@ -277,11 +286,14 @@
         expect(chef_run).to create_templatesymlink('Create a resque.yml and create a symlink to Rails root').with_variables(
           hash_including(
             redis_url: URI('redis://:my%20pass@redis.example.com:8888/2'),
             redis_sentinels: [],
-            redis_enable_client: false
+            redis_enable_client: false,
+            redis_connect_timeout: 3,
+            redis_read_timeout: 4,
+            redis_write_timeout: 5
           )
         )
 
         expect(chef_run).to render_file(config_file).with_content { |content|
           expect(content).to match(%r(url: redis://:my%20pass@redis.example.com:8888/2))
           expect(content).to match(/id:$/)
@@ -282,9 +294,12 @@
           )
         )
 
         expect(chef_run).to render_file(config_file).with_content { |content|
           expect(content).to match(%r(url: redis://:my%20pass@redis.example.com:8888/2))
           expect(content).to match(/id:$/)
+          expect(content).to match(/connect_timeout: 3/)
+          expect(content).to match(/read_timeout: 4/)
+          expect(content).to match(/write_timeout: 5/)
         }
       end