diff --git a/.gitignore b/.gitignore
index 9f6c4b4137c76f0df6c78d59c44410c7e12e08be..4545270b30b38e4ab44900596551ddb6aaab719f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -17,36 +17,36 @@
 /log/*
 !/log/.keep
 /tmp
-coverage
-public/system
-public/assets
-public/packs
-public/packs-test
+/coverage
+/public/system
+/public/assets
+/public/packs
+/public/packs-test
 .env
 .env.production
 .env.development
-node_modules/
-build/
+/node_modules/
+/build/
 
 # Ignore Vagrant files
 .vagrant/
 
 # Ignore Capistrano customizations
-config/deploy/*
+/config/deploy/*
 
 # Ignore IDE files
 .vscode/
 .idea/
 
 # Ignore postgres + redis + elasticsearch volume optionally created by docker-compose
-postgres
-redis
-elasticsearch
+/postgres
+/redis
+/elasticsearch
 
 # ignore Helm lockfile, dependency charts, and local values file
-chart/Chart.lock
-chart/charts/*.tgz
-chart/values.yaml
+/chart/Chart.lock
+/chart/charts/*.tgz
+/chart/values.yaml
 
 # Ignore Apple files
 .DS_Store
diff --git a/Gemfile.lock b/Gemfile.lock
index 96572bde567aa1c0c4838214bfa9e3ba0972cbf7..fcea810025777bdaa4551dae76347b1e1c487340 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -444,8 +444,6 @@ GEM
       rack (>= 1.0, < 3)
     rack-cors (1.1.1)
       rack (>= 2.0.0)
-    rack-protection (2.0.8.1)
-      rack
     rack-proxy (0.6.5)
       rack
     rack-test (1.1.0)
@@ -570,11 +568,10 @@ GEM
       nokogiri (>= 1.8.0)
       nokogumbo (~> 2.0)
     semantic_range (2.3.0)
-    sidekiq (6.0.7)
+    sidekiq (6.1.0)
       connection_pool (>= 2.2.2)
       rack (~> 2.0)
-      rack-protection (>= 2.0.0)
-      redis (>= 4.1.0)
+      redis (>= 4.2.0)
     sidekiq-bulk (0.2.0)
       sidekiq
     sidekiq-scheduler (3.0.1)
diff --git a/app/lib/activitypub/activity.rb b/app/lib/activitypub/activity.rb
index ee35e1e8da299f169b1bd6ad0d3aa61459378160..58cec7ac49fa61f80a4db1e4a638ed5517248a78 100644
--- a/app/lib/activitypub/activity.rb
+++ b/app/lib/activitypub/activity.rb
@@ -132,7 +132,7 @@ class ActivityPub::Activity
   end
 
   def delete_arrived_first?(uri)
-    redis.exists("delete_upon_arrival:#{@account.id}:#{uri}")
+    redis.exists?("delete_upon_arrival:#{@account.id}:#{uri}")
   end
 
   def delete_later!(uri)
diff --git a/app/lib/activitypub/activity/move.rb b/app/lib/activitypub/activity/move.rb
index 12bb82d259a9dac0bafa154330557984c3aebeab..2103f503f20a6c97231f98a2b7c9128501361509 100644
--- a/app/lib/activitypub/activity/move.rb
+++ b/app/lib/activitypub/activity/move.rb
@@ -33,7 +33,7 @@ class ActivityPub::Activity::Move < ActivityPub::Activity
   end
 
   def processed?
-    redis.exists("move_in_progress:#{@account.id}")
+    redis.exists?("move_in_progress:#{@account.id}")
   end
 
   def mark_as_processing!
diff --git a/app/lib/feed_manager.rb b/app/lib/feed_manager.rb
index efb4f6e2c218775121e48216173e8fcfd35c4db4..53ff31f5ecb19dc6022acbf0e6504f3850204b1a 100644
--- a/app/lib/feed_manager.rb
+++ b/app/lib/feed_manager.rb
@@ -169,7 +169,7 @@ class FeedManager
   private
 
   def push_update_required?(timeline_id)
-    redis.exists("subscribed:#{timeline_id}")
+    redis.exists?("subscribed:#{timeline_id}")
   end
 
   def blocks_or_mutes?(receiver_id, account_ids, context)
diff --git a/app/models/account_conversation.rb b/app/models/account_conversation.rb
index 0c03747e2ae7b0793e8ffc16411d17d57290f765..b43816588521b479130462aaf501a3cad7773a6e 100644
--- a/app/models/account_conversation.rb
+++ b/app/models/account_conversation.rb
@@ -108,7 +108,7 @@ class AccountConversation < ApplicationRecord
   end
 
   def subscribed_to_timeline?
-    Redis.current.exists("subscribed:#{streaming_channel}")
+    Redis.current.exists?("subscribed:#{streaming_channel}")
   end
 
   def streaming_channel
diff --git a/app/models/encrypted_message.rb b/app/models/encrypted_message.rb
index 5e0aba4342a661d3d5fa8c72ff3a9cb34a380b35..aa4182b4e12667a0605a8e9ec3c361c904ed75a5 100644
--- a/app/models/encrypted_message.rb
+++ b/app/models/encrypted_message.rb
@@ -32,16 +32,13 @@ class EncryptedMessage < ApplicationRecord
   private
 
   def push_to_streaming_api
-    Rails.logger.info(streaming_channel)
-    Rails.logger.info(subscribed_to_timeline?)
-
     return if destroyed? || !subscribed_to_timeline?
 
     PushEncryptedMessageWorker.perform_async(id)
   end
 
   def subscribed_to_timeline?
-    Redis.current.exists("subscribed:#{streaming_channel}")
+    Redis.current.exists?("subscribed:#{streaming_channel}")
   end
 
   def streaming_channel
diff --git a/app/models/home_feed.rb b/app/models/home_feed.rb
index 1fd506138be7db87e0730427393f792abca52370..0fe9dae464164f997e9dc559b31b01f33238e273 100644
--- a/app/models/home_feed.rb
+++ b/app/models/home_feed.rb
@@ -8,6 +8,6 @@ class HomeFeed < Feed
   end
 
   def regenerating?
-    redis.exists("account:#{@id}:regeneration")
+    redis.exists?("account:#{@id}:regeneration")
   end
 end
diff --git a/app/workers/publish_announcement_reaction_worker.rb b/app/workers/publish_announcement_reaction_worker.rb
index 418dc71275cb2686650bb49e8d2c163b7598336b..03da56550aadb8f555997d9f5581adaf068fa95b 100644
--- a/app/workers/publish_announcement_reaction_worker.rb
+++ b/app/workers/publish_announcement_reaction_worker.rb
@@ -14,7 +14,7 @@ class PublishAnnouncementReactionWorker
     payload = Oj.dump(event: :'announcement.reaction', payload: payload)
 
     FeedManager.instance.with_active_accounts do |account|
-      redis.publish("timeline:#{account.id}", payload) if redis.exists("subscribed:timeline:#{account.id}")
+      redis.publish("timeline:#{account.id}", payload) if redis.exists?("subscribed:timeline:#{account.id}")
     end
   rescue ActiveRecord::RecordNotFound
     true
diff --git a/app/workers/publish_scheduled_announcement_worker.rb b/app/workers/publish_scheduled_announcement_worker.rb
index 1392efed06fee821c15e2d8089599e00e7ce28ed..c23eae6af7c4a4f18584d3a7bae86b039de92ec8 100644
--- a/app/workers/publish_scheduled_announcement_worker.rb
+++ b/app/workers/publish_scheduled_announcement_worker.rb
@@ -15,7 +15,7 @@ class PublishScheduledAnnouncementWorker
     payload = Oj.dump(event: :announcement, payload: payload)
 
     FeedManager.instance.with_active_accounts do |account|
-      redis.publish("timeline:#{account.id}", payload) if redis.exists("subscribed:timeline:#{account.id}")
+      redis.publish("timeline:#{account.id}", payload) if redis.exists?("subscribed:timeline:#{account.id}")
     end
   end
 
diff --git a/app/workers/unpublish_announcement_worker.rb b/app/workers/unpublish_announcement_worker.rb
index e99d70cf87af8a9aef914864245428fa80608cdb..e58c07554a75e5b9dfb1f394da7fafdc76ea215d 100644
--- a/app/workers/unpublish_announcement_worker.rb
+++ b/app/workers/unpublish_announcement_worker.rb
@@ -8,7 +8,7 @@ class UnpublishAnnouncementWorker
     payload = Oj.dump(event: :'announcement.delete', payload: announcement_id.to_s)
 
     FeedManager.instance.with_active_accounts do |account|
-      redis.publish("timeline:#{account.id}", payload) if redis.exists("subscribed:timeline:#{account.id}")
+      redis.publish("timeline:#{account.id}", payload) if redis.exists?("subscribed:timeline:#{account.id}")
     end
   end
 end
diff --git a/config/application.rb b/config/application.rb
index a1da9d61f6019dfd9e9b3b8af6c113e565f9d097..a3c37b042af45e68e1cacb0877e56ac6a0f756bc 100644
--- a/config/application.rb
+++ b/config/application.rb
@@ -7,6 +7,7 @@ require 'rails/all'
 Bundler.require(*Rails.groups)
 
 require_relative '../app/lib/exceptions'
+require_relative '../lib/redis/namespace_extensions'
 require_relative '../lib/paperclip/url_generator_extensions'
 require_relative '../lib/paperclip/attachment_extensions'
 require_relative '../lib/paperclip/media_type_spoof_detector_extensions'
diff --git a/config/initializers/redis.rb b/config/initializers/redis.rb
index 510194044eb8f11779ae227c2a4a98b5a146d338..7573fc9f77533f59fa55900ab680be5a1b268fba 100644
--- a/config/initializers/redis.rb
+++ b/config/initializers/redis.rb
@@ -1,7 +1,5 @@
 # frozen_string_literal: true
 
-Redis.exists_returns_integer = false
-
 redis_connection = Redis.new(
   url: ENV['REDIS_URL'],
   driver: :hiredis
diff --git a/lib/redis/namespace_extensions.rb b/lib/redis/namespace_extensions.rb
new file mode 100644
index 0000000000000000000000000000000000000000..310a4f465bfde528f6d78ba97d429ce87ab99c1d
--- /dev/null
+++ b/lib/redis/namespace_extensions.rb
@@ -0,0 +1,12 @@
+# frozen_string_literal: true
+
+class Redis
+  module NamespaceExtensions
+    def exists?(*args, &block)
+      call_with_namespace('exists?', *args, &block)
+    end
+  end
+end
+
+Redis::Namespace::COMMANDS['exists?'] = [:first]
+Redis::Namespace.prepend(Redis::NamespaceExtensions)