diff --git a/charts/mastodon/Chart.yaml b/charts/mastodon/Chart.yaml
index 5f8102f57b46ab90775e2c1c19558ad1e6f1525f..542f565e829758a3cda970975333c2eadc0971af 100644
--- a/charts/mastodon/Chart.yaml
+++ b/charts/mastodon/Chart.yaml
@@ -11,7 +11,7 @@ sources:
     - https://git.shivering-isles.com/shivering-isles/infrastructure-gitops/-/tree/main/charts/mastodon
 
 type: application
-version: 6.1.0
+version: 6.2.0
 # renovate: image=ghcr.io/mastodon/mastodon
 appVersion: "v4.1.7"
 
@@ -27,3 +27,4 @@ dependencies:
   - name: redis
     version: 18.0.2
     repository: https://raw.githubusercontent.com/bitnami/charts/archive-full-index/bitnami
+    condition: redis.enabled
diff --git a/charts/mastodon/templates/configmap-env.yaml b/charts/mastodon/templates/configmap-env.yaml
index 36750daae73b54aaa7df22c137a10be50fce7669..dd1eedd0469fb0d2341dea2eac936e7ec01032bc 100644
--- a/charts/mastodon/templates/configmap-env.yaml
+++ b/charts/mastodon/templates/configmap-env.yaml
@@ -39,8 +39,20 @@ data:
   MALLOC_ARENA_MAX: "2"
   NODE_ENV: "production"
   RAILS_ENV: "production"
+  {{- if .Values.redis.enabled }}
   REDIS_HOST: {{ template "mastodon.redis.fullname" . }}-master
   REDIS_PORT: "6379"
+  {{- else }}
+  {{ with .Values.redis.host }}
+  REDIS_HOST: {{ . }}
+  {{- end }}
+  {{ with .Values.redis.port }}
+  REDIS_PORT: {{ . | quote }}
+  {{- end }}
+  {{ with .Values.redis.redisUrl }}
+  REDIS_URL: {{ . | quote }}
+  {{- end }}
+  {{- end }}
   {{- if .Values.mastodon.s3.enabled }}
   S3_BUCKET: {{ .Values.mastodon.s3.bucket }}
   S3_ENABLED: "true"
diff --git a/charts/mastodon/templates/cronjob-media-remove.yaml b/charts/mastodon/templates/cronjob-media-remove.yaml
index 41f1feb82566fd5cd65440d72f5f50652344fc4c..f0cf4b8c766e592a45214e4292db088d6b2c436c 100644
--- a/charts/mastodon/templates/cronjob-media-remove.yaml
+++ b/charts/mastodon/templates/cronjob-media-remove.yaml
@@ -64,7 +64,7 @@ spec:
                   valueFrom:
                     secretKeyRef:
                       name: {{ template "mastodon.redis.secretName" . }}
-                      key: redis-password
+                      key: {{ .Values.redis.auth.existingSecretPasswordKey | default "redis-password" }}
                 - name: "PORT"
                   value: {{ .Values.mastodon.web.port | quote }}
               {{- if (not .Values.mastodon.s3.enabled) }}
diff --git a/charts/mastodon/templates/deployment-sidekiq.yaml b/charts/mastodon/templates/deployment-sidekiq.yaml
index 47905321b870963641a4d51e757b4e7c4c6ebd33..14abed897f2a4eb7179c24a81a50d20da2b32189 100644
--- a/charts/mastodon/templates/deployment-sidekiq.yaml
+++ b/charts/mastodon/templates/deployment-sidekiq.yaml
@@ -86,7 +86,7 @@ spec:
               valueFrom:
                 secretKeyRef:
                   name: {{ template "mastodon.redis.secretName" $context }}
-                  key: redis-password
+                  key: {{ $context.Values.redis.auth.existingSecretPasswordKey | default "redis-password" }}
             {{- if (and $context.Values.mastodon.s3.enabled $context.Values.mastodon.s3.existingSecret) }}
             - name: "AWS_SECRET_ACCESS_KEY"
               valueFrom:
diff --git a/charts/mastodon/templates/deployment-streaming.yaml b/charts/mastodon/templates/deployment-streaming.yaml
index bec303cf952631025058d32a85b2ebdb287e62aa..8e90ac81510dc54f068cae7c7863abbbac5074f3 100644
--- a/charts/mastodon/templates/deployment-streaming.yaml
+++ b/charts/mastodon/templates/deployment-streaming.yaml
@@ -4,6 +4,7 @@ metadata:
   name: {{ include "mastodon.fullname" . }}-streaming
   labels:
     {{- include "mastodon.labels" . | nindent 4 }}
+    app.kubernetes.io/component: streaming
 spec:
   replicas: {{ .Values.mastodon.streaming.replicas }}
   selector:
@@ -57,7 +58,7 @@ spec:
               valueFrom:
                 secretKeyRef:
                   name: {{ template "mastodon.redis.secretName" . }}
-                  key: redis-password
+                  key: {{ .Values.redis.auth.existingSecretPasswordKey | default "redis-password" }}
             - name: "PORT"
               value: {{ .Values.mastodon.streaming.port | quote }}
           ports:
diff --git a/charts/mastodon/templates/deployment-web.yaml b/charts/mastodon/templates/deployment-web.yaml
index c1ec2327e8e11cae961ce0b8db1d396e498796dd..abfec687123896d3b4eaed41681f6e8e44cac626 100644
--- a/charts/mastodon/templates/deployment-web.yaml
+++ b/charts/mastodon/templates/deployment-web.yaml
@@ -71,7 +71,7 @@ spec:
               valueFrom:
                 secretKeyRef:
                   name: {{ template "mastodon.redis.secretName" . }}
-                  key: redis-password
+                  key: {{ .Values.redis.auth.existingSecretPasswordKey | default "redis-password" }}
             - name: "PORT"
               value: {{ .Values.mastodon.web.port | quote }}
             {{- if (and .Values.mastodon.s3.enabled .Values.mastodon.s3.existingSecret) }}
diff --git a/charts/mastodon/templates/job-assets-precompile.yaml b/charts/mastodon/templates/job-assets-precompile.yaml
index 95019629c668c2043a58faef11ce6915724292bd..8f946685a87b18bef2a4d758ca356effdbd527b2 100644
--- a/charts/mastodon/templates/job-assets-precompile.yaml
+++ b/charts/mastodon/templates/job-assets-precompile.yaml
@@ -55,7 +55,7 @@ spec:
               valueFrom:
                 secretKeyRef:
                   name: {{ template "mastodon.redis.secretName" . }}
-                  key: redis-password
+                  key: {{ .Values.redis.auth.existingSecretPasswordKey | default "redis-password" }}
             - name: "PORT"
               value: {{ .Values.mastodon.web.port | quote }}
           {{- if (not .Values.mastodon.s3.enabled) }}
diff --git a/charts/mastodon/templates/job-chewy-upgrade.yaml b/charts/mastodon/templates/job-chewy-upgrade.yaml
index 1ecb00518aac0efe9949b13968623a40cb4740b3..27b8fc29ffc2203857c444835d7c864fe2275f29 100644
--- a/charts/mastodon/templates/job-chewy-upgrade.yaml
+++ b/charts/mastodon/templates/job-chewy-upgrade.yaml
@@ -56,7 +56,7 @@ spec:
               valueFrom:
                 secretKeyRef:
                   name: {{ template "mastodon.redis.secretName" . }}
-                  key: redis-password
+                  key: {{ .Values.redis.auth.existingSecretPasswordKey | default "redis-password" }}
             - name: "PORT"
               value: {{ .Values.mastodon.web.port | quote }}
           {{- if (not .Values.mastodon.s3.enabled) }}
diff --git a/charts/mastodon/templates/job-create-admin.yaml b/charts/mastodon/templates/job-create-admin.yaml
index 2338e37380c2585cf29e0ffbd036e386952e7a5b..86512c7e12ab506b00423156ab592b17f6dc4fab 100644
--- a/charts/mastodon/templates/job-create-admin.yaml
+++ b/charts/mastodon/templates/job-create-admin.yaml
@@ -61,7 +61,7 @@ spec:
               valueFrom:
                 secretKeyRef:
                   name: {{ template "mastodon.redis.secretName" . }}
-                  key: redis-password
+                  key: {{ .Values.redis.auth.existingSecretPasswordKey | default "redis-password" }}
             - name: "PORT"
               value: {{ .Values.mastodon.web.port | quote }}
           {{- if (not .Values.mastodon.s3.enabled) }}
diff --git a/charts/mastodon/templates/job-db-migrate.yaml b/charts/mastodon/templates/job-db-migrate.yaml
index 1f4c60a0d145dd3e6fbf83c38f99c155beecf685..51949f9733069650c316f4ae95fe28cc58c0dd3e 100644
--- a/charts/mastodon/templates/job-db-migrate.yaml
+++ b/charts/mastodon/templates/job-db-migrate.yaml
@@ -55,7 +55,7 @@ spec:
               valueFrom:
                 secretKeyRef:
                   name: {{ template "mastodon.redis.secretName" . }}
-                  key: redis-password
+                  key: {{ .Values.redis.auth.existingSecretPasswordKey | default "redis-password" }}
             - name: "PORT"
               value: {{ .Values.mastodon.web.port | quote }}
           {{- if (not .Values.mastodon.s3.enabled) }}
diff --git a/charts/mastodon/templates/job-db-pre-migrate.yaml b/charts/mastodon/templates/job-db-pre-migrate.yaml
index f5dfa1c76fa45a7521ad919f799af858761cbf88..0129091f8f804d6ebe353e8d0c63e43bc53070c2 100644
--- a/charts/mastodon/templates/job-db-pre-migrate.yaml
+++ b/charts/mastodon/templates/job-db-pre-migrate.yaml
@@ -55,7 +55,7 @@ spec:
               valueFrom:
                 secretKeyRef:
                   name: {{ template "mastodon.redis.secretName" . }}
-                  key: redis-password
+                  key: {{ .Values.redis.auth.existingSecretPasswordKey | default "redis-password" }}
             - name: "PORT"
               value: {{ .Values.mastodon.web.port | quote }}
             - name: SKIP_POST_DEPLOYMENT_MIGRATIONS
diff --git a/charts/mastodon/templates/pdb-sidekiq.yaml b/charts/mastodon/templates/pdb-sidekiq.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..358ff6cac9d63e8168717f20f696c48159d7f6f1
--- /dev/null
+++ b/charts/mastodon/templates/pdb-sidekiq.yaml
@@ -0,0 +1,19 @@
+{{- $context := . }}
+{{- range .Values.mastodon.sidekiq.workers }}
+---
+apiVersion: policy/v1
+kind: PodDisruptionBudget
+metadata:
+  name: {{ include "mastodon.fullname" $context }}-sidekiq-{{ .name }}
+  labels:
+    {{- include "mastodon.labels" $context | nindent 4 }}
+    app.kubernetes.io/component: sidekiq-{{ .name }}
+    app.kubernetes.io/part-of: rails
+spec:
+  selector:
+    matchLabels:
+      {{- include "mastodon.selectorLabels" $context | nindent 6 }}
+      app.kubernetes.io/component: sidekiq-{{ .name }}
+      app.kubernetes.io/part-of: rails
+  maxUnavailable: 1
+{{- end }}
\ No newline at end of file
diff --git a/charts/mastodon/templates/pdb-streaming.yaml b/charts/mastodon/templates/pdb-streaming.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..4132d3e95a412801d9c507caa471325e17f47726
--- /dev/null
+++ b/charts/mastodon/templates/pdb-streaming.yaml
@@ -0,0 +1,13 @@
+apiVersion: policy/v1
+kind: PodDisruptionBudget
+metadata:
+  name: {{ include "mastodon.fullname" . }}-streaming
+  labels:
+    {{- include "mastodon.labels" . | nindent 4 }}
+    app.kubernetes.io/component: streaming
+spec:
+  selector:
+    matchLabels:
+      {{- include "mastodon.selectorLabels" . | nindent 6 }}
+      app.kubernetes.io/component: streaming
+  maxUnavailable: 1
\ No newline at end of file
diff --git a/charts/mastodon/templates/pdb-web.yaml b/charts/mastodon/templates/pdb-web.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..5586f503e8db99e92ec351e246b0f5fc369377f6
--- /dev/null
+++ b/charts/mastodon/templates/pdb-web.yaml
@@ -0,0 +1,15 @@
+apiVersion: policy/v1
+kind: PodDisruptionBudget
+metadata:
+  name: {{ include "mastodon.fullname" . }}-web
+  labels:
+    {{- include "mastodon.labels" . | nindent 4 }}
+    app.kubernetes.io/component: web
+    app.kubernetes.io/part-of: rails
+spec:
+  selector:
+    matchLabels:
+      {{- include "mastodon.selectorLabels" . | nindent 6 }}
+      app.kubernetes.io/component: web
+      app.kubernetes.io/part-of: rails
+  maxUnavailable: 1
\ No newline at end of file
diff --git a/charts/mastodon/tests/50_sidekiq_test.yaml b/charts/mastodon/tests/50_sidekiq_test.yaml
index 37c7a6abb87188454213e6d8b52862f9faab9292..4c5bbf66665dd14f75362e0f3356045c49d40ff6 100644
--- a/charts/mastodon/tests/50_sidekiq_test.yaml
+++ b/charts/mastodon/tests/50_sidekiq_test.yaml
@@ -2,6 +2,7 @@ suite: sidekiq
 templates:
   - configmap-env.yaml
   - deployment-sidekiq.yaml
+  - pdb-sidekiq.yaml
   - secrets.yaml
 tests:
   - it: should match basic snapshot
diff --git a/charts/mastodon/tests/50_web_test.yaml b/charts/mastodon/tests/50_web_test.yaml
index 9d17ba46dcaf7129b72fd56b2127be2fe9df5e21..9d6ea0244418bad1a2eb5921d9a1a656a4b95efa 100644
--- a/charts/mastodon/tests/50_web_test.yaml
+++ b/charts/mastodon/tests/50_web_test.yaml
@@ -3,6 +3,7 @@ templates:
   - configmap-env.yaml
   - deployment-web.yaml
   - ingress.yaml
+  - pdb-web.yaml
   - secrets.yaml
   - service-web.yaml
 tests:
diff --git a/charts/mastodon/tests/98_snapshot_test.yaml b/charts/mastodon/tests/98_snapshot_test.yaml
index 87290ef4079a6a7c4835a78e9dc13e35560977dc..44c3a2fbc4b10a140acec70411aeba16c9179893 100644
--- a/charts/mastodon/tests/98_snapshot_test.yaml
+++ b/charts/mastodon/tests/98_snapshot_test.yaml
@@ -11,6 +11,9 @@ templates:
   - job-create-admin.yaml
   - job-db-migrate.yaml
   - job-db-pre-migrate.yaml
+  - pdb-sidekiq.yaml
+  - pdb-streaming.yaml
+  - pdb-web.yaml
   - pvc-assets.yaml
   - pvc-system.yaml
   - secrets.yaml
diff --git a/charts/mastodon/tests/__snapshot__/50_sidekiq_test.yaml.snap b/charts/mastodon/tests/__snapshot__/50_sidekiq_test.yaml.snap
index aae9120646d81f6394b5a5b1a4c98b88fd8c7de5..f119198bfea3a5e75e3dce3f6a0bc8adbe39e555 100644
--- a/charts/mastodon/tests/__snapshot__/50_sidekiq_test.yaml.snap
+++ b/charts/mastodon/tests/__snapshot__/50_sidekiq_test.yaml.snap
@@ -132,6 +132,27 @@ should match basic snapshot:
               persistentVolumeClaim:
                 claimName: RELEASE-NAME-mastodon-system
   3: |
+    apiVersion: policy/v1
+    kind: PodDisruptionBudget
+    metadata:
+      labels:
+        app.kubernetes.io/component: sidekiq-all-queues
+        app.kubernetes.io/instance: RELEASE-NAME
+        app.kubernetes.io/managed-by: Helm
+        app.kubernetes.io/name: mastodon
+        app.kubernetes.io/part-of: rails
+        app.kubernetes.io/version: 4.5.6
+        helm.sh/chart: mastodon-1.2.3
+      name: RELEASE-NAME-mastodon-sidekiq-all-queues
+    spec:
+      maxUnavailable: 1
+      selector:
+        matchLabels:
+          app.kubernetes.io/component: sidekiq-all-queues
+          app.kubernetes.io/instance: RELEASE-NAME
+          app.kubernetes.io/name: mastodon
+          app.kubernetes.io/part-of: rails
+  4: |
     apiVersion: v1
     data:
       OTP_SECRET: ZHVtbXktb3RwX3NlY3JldA==
diff --git a/charts/mastodon/tests/__snapshot__/50_web_test.yaml.snap b/charts/mastodon/tests/__snapshot__/50_web_test.yaml.snap
index 9cdc3e704f3ac05b94ad437d2f27a0851cd56541..8d0d152332bfbb20c3f51df5ea058c6664e15529 100644
--- a/charts/mastodon/tests/__snapshot__/50_web_test.yaml.snap
+++ b/charts/mastodon/tests/__snapshot__/50_web_test.yaml.snap
@@ -170,6 +170,27 @@ should match basic snapshot:
             - mastodon.local
           secretName: mastodon-tls
   4: |
+    apiVersion: policy/v1
+    kind: PodDisruptionBudget
+    metadata:
+      labels:
+        app.kubernetes.io/component: web
+        app.kubernetes.io/instance: RELEASE-NAME
+        app.kubernetes.io/managed-by: Helm
+        app.kubernetes.io/name: mastodon
+        app.kubernetes.io/part-of: rails
+        app.kubernetes.io/version: 4.5.6
+        helm.sh/chart: mastodon-1.2.3
+      name: RELEASE-NAME-mastodon-web
+    spec:
+      maxUnavailable: 1
+      selector:
+        matchLabels:
+          app.kubernetes.io/component: web
+          app.kubernetes.io/instance: RELEASE-NAME
+          app.kubernetes.io/name: mastodon
+          app.kubernetes.io/part-of: rails
+  5: |
     apiVersion: v1
     data:
       OTP_SECRET: ZHVtbXktb3RwX3NlY3JldA==
@@ -186,7 +207,7 @@ should match basic snapshot:
         helm.sh/chart: mastodon-1.2.3
       name: RELEASE-NAME-mastodon
     type: Opaque
-  5: |
+  6: |
     apiVersion: v1
     kind: Service
     metadata:
diff --git a/charts/mastodon/tests/__snapshot__/98_snapshot_test.yaml.snap b/charts/mastodon/tests/__snapshot__/98_snapshot_test.yaml.snap
index 185f24a63fb08a85812be043485b44cac9288ca6..6e1337b21136135f4af0d3d9f39ccbb1b3b2fcfb 100644
--- a/charts/mastodon/tests/__snapshot__/98_snapshot_test.yaml.snap
+++ b/charts/mastodon/tests/__snapshot__/98_snapshot_test.yaml.snap
@@ -204,6 +204,7 @@ should match basic snapshot:
     kind: Deployment
     metadata:
       labels:
+        app.kubernetes.io/component: streaming
         app.kubernetes.io/instance: RELEASE-NAME
         app.kubernetes.io/managed-by: Helm
         app.kubernetes.io/name: mastodon
@@ -714,6 +715,67 @@ should match basic snapshot:
               persistentVolumeClaim:
                 claimName: RELEASE-NAME-mastodon-system
   12: |
+    apiVersion: policy/v1
+    kind: PodDisruptionBudget
+    metadata:
+      labels:
+        app.kubernetes.io/component: sidekiq-all-queues
+        app.kubernetes.io/instance: RELEASE-NAME
+        app.kubernetes.io/managed-by: Helm
+        app.kubernetes.io/name: mastodon
+        app.kubernetes.io/part-of: rails
+        app.kubernetes.io/version: 4.5.6
+        helm.sh/chart: mastodon-1.2.3
+      name: RELEASE-NAME-mastodon-sidekiq-all-queues
+    spec:
+      maxUnavailable: 1
+      selector:
+        matchLabels:
+          app.kubernetes.io/component: sidekiq-all-queues
+          app.kubernetes.io/instance: RELEASE-NAME
+          app.kubernetes.io/name: mastodon
+          app.kubernetes.io/part-of: rails
+  13: |
+    apiVersion: policy/v1
+    kind: PodDisruptionBudget
+    metadata:
+      labels:
+        app.kubernetes.io/component: streaming
+        app.kubernetes.io/instance: RELEASE-NAME
+        app.kubernetes.io/managed-by: Helm
+        app.kubernetes.io/name: mastodon
+        app.kubernetes.io/version: 4.5.6
+        helm.sh/chart: mastodon-1.2.3
+      name: RELEASE-NAME-mastodon-streaming
+    spec:
+      maxUnavailable: 1
+      selector:
+        matchLabels:
+          app.kubernetes.io/component: streaming
+          app.kubernetes.io/instance: RELEASE-NAME
+          app.kubernetes.io/name: mastodon
+  14: |
+    apiVersion: policy/v1
+    kind: PodDisruptionBudget
+    metadata:
+      labels:
+        app.kubernetes.io/component: web
+        app.kubernetes.io/instance: RELEASE-NAME
+        app.kubernetes.io/managed-by: Helm
+        app.kubernetes.io/name: mastodon
+        app.kubernetes.io/part-of: rails
+        app.kubernetes.io/version: 4.5.6
+        helm.sh/chart: mastodon-1.2.3
+      name: RELEASE-NAME-mastodon-web
+    spec:
+      maxUnavailable: 1
+      selector:
+        matchLabels:
+          app.kubernetes.io/component: web
+          app.kubernetes.io/instance: RELEASE-NAME
+          app.kubernetes.io/name: mastodon
+          app.kubernetes.io/part-of: rails
+  15: |
     apiVersion: v1
     kind: PersistentVolumeClaim
     metadata:
@@ -731,7 +793,7 @@ should match basic snapshot:
         requests:
           storage: 10Gi
       storageClassName: null
-  13: |
+  16: |
     apiVersion: v1
     kind: PersistentVolumeClaim
     metadata:
@@ -749,7 +811,7 @@ should match basic snapshot:
         requests:
           storage: 100Gi
       storageClassName: null
-  14: |
+  17: |
     apiVersion: v1
     data:
       OTP_SECRET: ZHVtbXktb3RwX3NlY3JldA==
@@ -766,7 +828,7 @@ should match basic snapshot:
         helm.sh/chart: mastodon-1.2.3
       name: RELEASE-NAME-mastodon
     type: Opaque
-  15: |
+  18: |
     apiVersion: v1
     kind: ServiceAccount
     metadata:
@@ -777,7 +839,7 @@ should match basic snapshot:
         app.kubernetes.io/version: 4.5.6
         helm.sh/chart: mastodon-1.2.3
       name: RELEASE-NAME-mastodon
-  16: |
+  19: |
     apiVersion: v1
     kind: Service
     metadata:
@@ -799,7 +861,7 @@ should match basic snapshot:
         app.kubernetes.io/instance: RELEASE-NAME
         app.kubernetes.io/name: mastodon
       type: ClusterIP
-  17: |
+  20: |
     apiVersion: v1
     kind: Service
     metadata:
diff --git a/charts/mastodon/values.yaml b/charts/mastodon/values.yaml
index cf075d243a6d87658392f26f6a98e768ed1bb8c8..2bf3c3104b781904cd032da4348d546c6aa53140 100644
--- a/charts/mastodon/values.yaml
+++ b/charts/mastodon/values.yaml
@@ -264,13 +264,23 @@ postgresql:
 
 # https://github.com/bitnami/charts/tree/master/bitnami/redis#parameters
 redis:
+  # -- disable if you want to use an existing redis; in which case the values
+  # below must match those of that external redis instance
+  enabled: true
+  # -- hostname, usually service, that provides redis
+  host: null
+  # -- port at which redis is available
+  port: "6379"
+  # -- redisUrl overwrites redis.host and redis.port. It allows to use sentinal redis installations
+  redisUrl: null
   auth:
     # -- you must set a password; the password generated by the redis chart will be
     # rotated on each upgrade:
     password: ""
     # you can also specify the name of an existing Secret
     # with a key of redis-password set to the password you want
-    # existingSecret: ""
+    existingSecret: null
+    existingSecretPasswordKey: null
 
 # @ignored
 service: