diff --git a/.env.defaults b/.env.defaults
index cce505ceeb37500f8a48f62c00127bce104d979e..0131a288d98357fad451d8e9d3626f59137212c4 100644
--- a/.env.defaults
+++ b/.env.defaults
@@ -8,8 +8,9 @@ EXPOSE_API_DOCS=false
 COMPRESS_FILE_SIZE=600
 COMPRESS_FILE_TYPES=application/javascript application/json application/x-javascript application/xml application/xml+rss text/css text/html text/javascript text/plain text/xml image/svg+xml
 
-REDIS_PORT=6379
+REDIS_MODE=standalone
+REDIS_SENTINEL_MASTER_ID=mymaster
 REDIS_DB=0
 REDIS_PREFIX=ui-middleware
-REDIS_HOST=localhost
+REDIS_HOSTS=localhost:6379
 ORIGINS=*
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 5c6a88a51e5f7bd4b45535e1ac2df1b1ea17d47f..165dc3da093e1d9613be8d0a2b79c3d665e5034a 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -16,9 +16,6 @@ integration tests:
   script:
     - yarn --non-interactive --no-progress -s
     - yarn integration --ci --coverage
-  variables:
-    # app specific settings
-    REDIS_HOST: redis
 
 deploy preview with prefix:
   extends: .auto-deploy-preview-chart
diff --git a/.gitlab/preview-prefix/values-template.yaml b/.gitlab/preview-prefix/values-template.yaml
index 39b8f557a5a74bad89394de5681626f421242587..5d03dcfc6f2fa839c22efb276e252dda5ec24c6e 100644
--- a/.gitlab/preview-prefix/values-template.yaml
+++ b/.gitlab/preview-prefix/values-template.yaml
@@ -3,17 +3,10 @@ imagePullSecrets:
 
 appRoot: /appsuite/
 
-ingress:
-  enabled: false
 image:
   registry: ${CI_REGISTRY}
   repository: frontend/ui-middleware
   tag: ${TAG_NAME}
   pullPolicy: Always
 
-redis:
-  enabled: true
-  host: preview-app-redis-master.${PREVIEW_APP_NAME}.svc.cluster.local
-  prefix: ${CI_COMMIT_REF_SLUG}-${OX_COMPONENT}-prefix
-
 existingConfigMap: preview-prefix-core-ui-middleware
diff --git a/.gitlab/preview/Chart.yaml b/.gitlab/preview/Chart.yaml
index 286a2206b77fbf5870d7a1cd096a4b5a0a6a1b5e..5d0bf4ebf38e5794f545b0b19e4a5850808b71c7 100644
--- a/.gitlab/preview/Chart.yaml
+++ b/.gitlab/preview/Chart.yaml
@@ -30,7 +30,4 @@ dependencies:
   - name: core-ui-middleware
     version: ">=1.0.0-0"
     repository: "file://../../helm/core-ui-middleware"
-  - name: redis
-    version: ^17.9.0
-    repository: https://charts.bitnami.com/bitnami
-    condition: redis.enabled, global.redis.enabled
+
diff --git a/.gitlab/preview/values-template.yaml b/.gitlab/preview/values-template.yaml
index 673e3693c234841908b059baccb285892e7d812f..c66f4c2fe39a7d441b07038d197a94e6cb8a2f73 100644
--- a/.gitlab/preview/values-template.yaml
+++ b/.gitlab/preview/values-template.yaml
@@ -2,10 +2,6 @@ core-ui-middleware:
   image:
     repository: ${CI_REGISTRY_IMAGE}
     tag: ${TAG_NAME}
-  redis:
-    enabled: true
-    host: preview-app-redis-master.${PREVIEW_APP_NAME}.svc.cluster.local
-    prefix: ${CI_COMMIT_REF_SLUG}-${OX_COMPONENT}
 host: ${PREVIEW_APP_NAME}.dev.oxui.de
 
 appsuite:
@@ -14,8 +10,6 @@ appsuite:
       commit-ref: "${CI_COMMIT_SHORT_SHA}"
     deploymentAnnotations:
       commit-ref: "${CI_COMMIT_SHORT_SHA}"
-    redis:
-      prefix: ${CI_COMMIT_REF_SLUG}-${OX_COMPONENT}
   core-guidedtours:
     podAnnotations:
       commit-ref: "${CI_COMMIT_SHORT_SHA}"
diff --git a/.gitlab/preview/values.yaml b/.gitlab/preview/values.yaml
index 628d8ec007454f0da91e26def91c54911335a3de..bcca0d2b761d93e39bcef9182a7652701cf4ad48 100644
--- a/.gitlab/preview/values.yaml
+++ b/.gitlab/preview/values.yaml
@@ -5,10 +5,6 @@ global:
 core-ui-middleware:
   replicaCount: 1
   existingConfigMap: preview-core-ui-middleware
-  containerPort: 8080
-
-  ingress:
-    enabled: false
 
   defaultRegistry: ""
 
@@ -26,31 +22,10 @@ core-ui-middleware:
   resources:
     limits:
       cpu: 1
-      memory: 196Mi
+      memory: 384Mi
     requests:
       cpu: 100m
-      memory: 196Mi
-
-redis:
-  enabled: true
-  architecture: standalone
-  auth:
-    enabled: false
-  master:
-    persistence:
-      enabled: false
-  replica:
-    persistence:
-      enabled: false
-  metrics:
-    enabled: true
-  resources:
-    requests:
-      memory: 128Mi
-      cpu: 100m
-    limits:
-      memory: 256Mi
-      cpu: 250m
+      memory: 384Mi
 
 appsuite:
   core-ui-middleware:
diff --git a/README.md b/README.md
index 3dffb39317939a12e34957e332e45e1c27c8d35c..5e3a0845275680b371cb1f615b2cbdf02ad7e3f4 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-# ui-middleware
+# UI Middleware
 
 > Provides the collected manifest.json of services in a cluster as well as a list of dependencies
 > for each source file. This information can be used to dynamically compile all ui components at
@@ -7,36 +7,23 @@
 
 ## Architecture
 
-The ui-middleware is, as the name already suggests, a middleware component to support the App Suite UI.
-As an installation of App Suite UI can consist of multiple projects, like the [Core App Suite UI](https://gitlab.open-xchange.com/frontend/ui), [Documents UI]([https://gitlab.open-xchange.com/documents/office-web), [OX Guard UI](https://gitlab.open-xchange.com/appsuite/guard-ui), and other custom plugins, those components need to be combined at some point to be served to the browser.
+The UI Middleware is, as the name already suggests, a middleware component to support the App Suite UI.
+As an installation of App Suite UI can consist of multiple projects, like the [Core App Suite UI](https://gitlab.open-xchange.com/frontend/ui), [Documents UI](https://gitlab.open-xchange.com/documents/office-web), [OX Guard UI](https://gitlab.open-xchange.com/appsuite/guard-ui), and other custom plugins, those components need to be combined at some point to be served to the browser.
 This is handled by the ui-middleware component, by putting it between the Ingress Controller and the containers serving the individual components that make up the App Suite UI.
 
 If you prefer a picture, this is, how such an installation can look like.
 
 ![UI Middleware architecture](./docs/ui-mw-architecture.png)
 
-## Endpoint
+## Prerequisites
 
-- `/manifests`
-- `/dependencies`
+- A Redis server is required (standalone, sentinel and cluster mode supported)
 
 ## Deployments
 
-**local**
+### Kubernetes
 
-- adjust `.env`
-- run `yarn dev`
-
-**docker**
-
-```
-docker build -t ui-middleware .
-docker run -t -i -p 8080:8080 ui-middleware
-```
-
-**kubernetes**
-
-```
+```shell
 cd helm
 helm upgrade -i -f ui-middleware/values.yaml -f values/develop.yaml ui-middleware ./ui-middleware
 ```
@@ -45,39 +32,24 @@ It is possible to horizontally scale the UI Middleware, as more clients are fetc
 
 ## Configuration
 
-**local, docker**
-
-| Parameter                | Description                       | Default  |
-|--------------------------|-----------------------------------|----------|
-| `PORT`                   | Exposed port                      | `"8080"` |
-| `CACHE_TTL`              | Vite manifest caching time        | `30000`  |
-| `LOG_LEVEL`              | Pino log level                    | `"info"` |
-| `REDIS_HOST`             | Redis host (required)             |          |
-| `REDIS_PORT`             | Redis port (optional)             | `6379`   |
-| `REDIS_DB`               | Redis DB, e.g. `"1"` (optional)   | null     |
-| `REDIS_PASSWORD`         | Redis password (optional)         | null     |
-| `COMPRESS_FILE_SIZE`     | Larger files will be gzipped      | `600`    |
-| `COMPRESS_FILE_TYPES`    | Set of compression mime types     |see values|
-| `SLOW_REQUEST_THRESHOLD` | Slow request threshold in ms      | `4000`   |
-
-
-**kubernetes**
-
-| Parameter             | Description                        | Default  |
-|-----------------------|------------------------------------|----------|
-| `port`                | Exposed port                       | `"8080"` |
-| `cacheTTL`            | Vite manifest caching time         | `30000`  |
-| `logLevel`            | Pino log level                     | `"info"` |
-| `redis.enabled`       | Global switch Redis integration    |  false   |
-| `redis.host`          | Redis host                         |          |
-| `redis.port`          | Redis port (optional)              | `6379`   |
-| `redis.db`            | Redis DB, e.g. `"1"` (optional)    | null     |
-| `redis.password`      | Redis password (optional)          | null     |
-| `compressFileSize`    | Larger files will be gzipped       | `600`    |
-| `compressFileTypes`   | Set of compression mime types      |see values|
-| `slowRequestThreshold`| Slow request threshold in ms       | `4000`   |
-
-**config map**
+| Helm Variable (values)   | Environment Variable       | Description                                  | Default              |
+|--------------------------|----------------------------|----------------------------------------------|----------------------|
+| `port`                   | `PORT`                     | Exposed port                                 | `"8080"`             |
+| `cacheTTL`               | `CACHE_TTL`                | Vite manifest caching time                   | `30000`              |
+| `logLevel`               | `LOG_LEVEL`                | Pino log level                               | `"info"`             |
+| `redis.mode`             | `REDIS_MODE`               | Redis mode (standalone, sentinel or cluster) | `"standalone"`       |
+| `redis.sentinelMasterId` | `REDIS_SENTINEL_MASTER_ID` | Name of the `sentinel` masterSet             | `"mymaster"`         |
+| `redis.hosts`            | N/A (see below)            | Redis hosts as list                          | `["localhost:6379"]` |
+| N/A (see above)          | `REDIS_HOSTS`              | Redis hosts as string                        | `"localhost:6379"`   |
+| `redis.db`               | `REDIS_DB`                 | Redis DB, e.g. `"1"`                         | null                 |
+| `redis.prefix`           | `REDIS_PREFIX`             | Redis prefix                                 | `"ui-middleware"`    |
+| `redis.password`         | `REDIS_PASSWORD`           | Redis password                               | null                 |
+| `redis.sidecar.image`    | N/A                        | Redis sidecar image                          | `"redis:latest"`     |
+| `compressFileSize`       | `COMPRESS_FILE_SIZE`       | Larger files will be gzipped                 | `600`                |
+| `compressFileTypes`      | `COMPRESS_FILE_TYPES`      | Set of compression mime types                | application/javascript application/json application/x-javascript application/xml application/xml+rss text/css text/html text/javascript text/plain text/xml image/svg+xml |
+| `slowRequestThreshold`   | `SLOW_REQUEST_THRESHOLD`   | Slow request threshold in ms                 | `4000`               |
+
+### Config Map
 
 ```yaml
 # List of urls where to find ui containers
@@ -103,6 +75,10 @@ It is mandatory to load the UI over https with a valid certificate and there are
 - The UI needs a **service worker** to function. The service worker is used for file-caching and version-mismatch detection (the "reload"-banner). **Service workers** are only loaded over https with valid certificate to prevent man-in-the-middle attacks.
 - The UI consists of many small files, because it cannot be bundled as before. To improve file transfer time, HTTP/2 is required which requires https.
 - The **service worker** also increases boot time by loading zipped chunks of files and puts them in the browser-cache on initial boot. Without https no **service worker**, without **service worker** no zipped loading.
-- To reduce the transferred file-size, the **UI-middleware** uses **brotli** encoding for every transferred file (except the index.html). The UI-middleware will not check for accept-enconding headers due to performance reasons. Modern browsers will not load brotli over insecure connections and the UI won't load without it.
+- To reduce the transferred file-size, the **UI-middleware** uses **brotli** encoding for every transferred file (except the index.html). The UI-middleware will not check for accept-encoding headers due to performance reasons. Modern browsers will not load brotli over insecure connections and the UI won't load without it.
 
 It is noteworthy that localhost is an exception to the above rules and the UI including **service workers** and preloading (but not http2) will work on localhost for development environments.
+
+## Redis default setup
+
+For setups where scaling of the UI middleware is not necessary you can use the default values of the helm chart, which will deploy a redis server as a sidecar container.
diff --git a/helm/core-ui-middleware/Chart.yaml b/helm/core-ui-middleware/Chart.yaml
index 503e89960e3d584a08918bc39b3cf9f6bfeab665..74a553bfeee2964bcd6519248c628ccb75987743 100644
--- a/helm/core-ui-middleware/Chart.yaml
+++ b/helm/core-ui-middleware/Chart.yaml
@@ -15,7 +15,7 @@ type: application
 # This is the chart version. This version number should be incremented each time you make changes
 # to the chart and its templates, including the app version.
 # Versions are expected to follow Semantic Versioning (https://semver.org/)
-version: 1.6.0
+version: 2.0.0
 
 # This is the version number of the application being deployed. This version number should be
 # incremented each time you make changes to the application. Versions are not expected to
diff --git a/helm/core-ui-middleware/templates/deployment.yaml b/helm/core-ui-middleware/templates/deployment.yaml
index 450d95c5e5316bf5f101bd609ca67c081e435826..0b840113c911212b225cb1d6bca8de6b58d252d4 100644
--- a/helm/core-ui-middleware/templates/deployment.yaml
+++ b/helm/core-ui-middleware/templates/deployment.yaml
@@ -35,18 +35,16 @@ spec:
               value: "{{ .Values.compressFileTypes }}"
             - name: SLOW_REQUEST_THRESHOLD
               value: "{{ .Values.slowRequestThreshold }}"
-            {{- if .Values.redis.enabled }}
-            - name: REDIS_HOST
-              value: "{{ required "redis.host required" .Values.redis.host }}"
-            - name: REDIS_PORT
-              value: "{{ .Values.redis.port | default 6379 }}"
+            - name: REDIS_MODE
+              value: "{{ .Values.redis.mode }}"
+            - name: REDIS_HOSTS
+              value: "{{ .Values.redis.hosts | join "," }}"
             - name: REDIS_DB
               value: "{{ .Values.redis.db | int }}"
             - name: REDIS_PASSWORD
               value: "{{ .Values.redis.password }}"
             - name: REDIS_PREFIX
               value: "{{ .Values.redis.prefix }}"
-            {{- end }}
           ports:
             - name: http
               containerPort: {{ .Values.containerPort | default 8080 }}
@@ -73,8 +71,29 @@ spec:
           volumeMounts:
             - name: manifest-config
               mountPath: /app/config/
+        {{- if and (eq (len .Values.redis.hosts) 1) (eq (index .Values.redis.hosts 0) "localhost:6379") }}
+        - name: redis
+          image: {{ .Values.redis.sidecar.image }}
+          ports:
+            - name: redis
+              containerPort: 6379
+              protocol: TCP
+          volumeMounts:
+            - name: redis-data
+              mountPath: /data
+          resources:
+            limits:
+              memory: 96Mi
+            requests:
+              memory: 96Mi
+        {{- end }}
       volumes:
         - name: manifest-config
           configMap:
             name: {{ .Values.existingConfigMap | default (include "ox-common.names.fullname" .) }}
-
+        {{- if and (eq (len .Values.redis.hosts) 1) (eq (index .Values.redis.hosts 0) "localhost:6379") }}
+        - name: redis-data
+          emptyDir:
+            sizeLimit: 96Mi
+            medium: Memory
+        {{- end }}
diff --git a/helm/core-ui-middleware/values.yaml b/helm/core-ui-middleware/values.yaml
index 5bd638c5c30793fb279bf1a7e4c87789cc9e87b5..e7ecf74596333d1bbcedee5a184f06432d244729 100644
--- a/helm/core-ui-middleware/values.yaml
+++ b/helm/core-ui-middleware/values.yaml
@@ -116,9 +116,13 @@ extras:
     enabled: false
 
 redis:
-  enabled: false
-  host: ''
-  port: 6379
+  mode: 'standalone' # Other values: sentinel, cluster
+  hosts:
+    - localhost:6379
   db: 0
   password: null
   prefix: ui-middleware
+  # This is only used for development. A sidecar container is started in the pod.
+  # Note: This does not scale!
+  sidecar:
+    image: redis:latest
diff --git a/src/redis.js b/src/redis.js
index 6c78ae581a8f4fdfdff385e21bd344742f18eaba..59b9adf440c2a880a31fdf0d5346c2ee95c25a25 100644
--- a/src/redis.js
+++ b/src/redis.js
@@ -5,15 +5,35 @@ import { registerLatestVersionListener, updateVersionProcessor } from './version
 
 const commonQueueOptions = { enableReadyCheck: false, maxRetriesPerRequest: null }
 
-const createClient = (type, options = {}) => {
-  const client = new Redis({
-    host: process.env.REDIS_HOST,
-    port: Number(process.env.REDIS_PORT),
+const hosts = (process.env.REDIS_HOSTS || '').split(',').map(host => {
+  const [hostname, port] = host.split(':')
+  return { host: hostname, port: Number(port) }
+})
+
+function createClient (id, options = {}) {
+  options = {
     db: Number(process.env.REDIS_DB),
     password: process.env.REDIS_PASSWORD,
     ...options
-  })
-  client.on('ready', () => logger.info(`[Redis] Connected ${type} to redis on ${process.env.REDIS_HOST}`))
+  }
+
+  if (process.env.REDIS_MODE === 'sentinel') {
+    options = {
+      sentinels: hosts,
+      name: process.env.REDIS_SENTINEL_MASTER_ID,
+      ...options
+    }
+  } else if (process.env.REDIS_MODE === 'standalone') {
+    options = {
+      ...hosts[0],
+      ...options
+    }
+  }
+  const client = process.env.REDIS_MODE === 'cluster'
+    ? new Redis.Cluster(hosts, { redisOptions: options })
+    : new Redis(options)
+
+  client.on('ready', () => logger.info(`[Redis] Connected ${id} to redis on ${process.env.REDIS_HOSTS}`))
   client.on('error', (err) => logger.error(`[Redis] Connect error: ${err}`))
 
   return client