diff --git a/src/backend/.env.dist b/src/backend/.env.dist
index cf392f8b45ceaa7baed330c9aac91c22f62a1a60..add1bcada5513346988388c81602be2424439b2b 100644
--- a/src/backend/.env.dist
+++ b/src/backend/.env.dist
@@ -18,4 +18,7 @@ IDP_ENABLED=
 SP_HOST=
 
 ANONYMIZATION_HASH_PREFIX=anon
-ANONYMIZATION_DEFAULT_MINIMUM_COUNT=10
\ No newline at end of file
+ANONYMIZATION_DEFAULT_MINIMUM_COUNT=10
+
+CACHE_BACKEND='redis'
+CACHE_URI='redis://127.0.0.1:6379'
\ No newline at end of file
diff --git a/src/backend/.env.test b/src/backend/.env.test
index 74be67365bf7ef9a65b8f0df607dee29c5961188..803a7a2d55e7d72604b45d92166ad0b6e2b10c5b 100644
--- a/src/backend/.env.test
+++ b/src/backend/.env.test
@@ -17,4 +17,7 @@ IDP_SERVER=https://aai-test-v3.ruhr-uni-bochum.de
 SP_HOST=
 
 ANONYMIZATION_HASH_PREFIX=anon
-ANONYMIZATION_DEFAULT_MINIMUM_COUNT=10
\ No newline at end of file
+ANONYMIZATION_DEFAULT_MINIMUM_COUNT=10
+
+CACHE_BACKEND='redis'
+CACHE_URI='redis://127.0.0.1:6379'
\ No newline at end of file
diff --git a/src/backend/settings.py b/src/backend/settings.py
index 258d1fccb833da1aebc6c376275a909edce17bff..e3bd093e044f0835095839898372a3c6a3ce8476 100644
--- a/src/backend/settings.py
+++ b/src/backend/settings.py
@@ -127,6 +127,15 @@ else:
         }
     }
 
+# Cache(s)
+# https://docs.djangoproject.com/en/4.1/topics/cache/
+CACHES = {
+    'default': {
+        'BACKEND': 'django.core.cache.backends.redis.RedisCache' if env("CACHE_BACKEND", default="file") == "redis"
+                    else 'django.core.cache.backends.filebased.FileBasedCache',
+        'LOCATION': '/tmp/django_cache' if env("CACHE_BACKEND", default="file") == 'file' else env("CACHE_URI", default='redis://127.0.0.1:6379') ,
+    }
+}
 
 # Password validation
 # https://docs.djangoproject.com/en/4.1/ref/settings/#auth-password-validators
diff --git a/src/consents/views.py b/src/consents/views.py
index 22ebda28fa15d924993da19689ed85b35c5bebb8..680047acf938f322b85c261c0abca97b6b2b333b 100644
--- a/src/consents/views.py
+++ b/src/consents/views.py
@@ -3,7 +3,9 @@ import string
 import random
 import os
 import secrets
+import time
 
+from django.core.cache import cache
 from django.conf import settings
 from django.core.exceptions import ObjectDoesNotExist
 from django.http.response import JsonResponse
@@ -391,18 +393,38 @@ class CreateUserConsentViaConnectServiceView(APIView):
         shib_id = shib_connector_resolver_to_pairwaise_id(email=email, provider=provider)
 
         user = CustomUser.objects.filter(shibboleth_connector_identifier=shib_id).first()
-        
+
+        message = "user exists"
         if not user:
-           user = CustomUser.objects.create(
-                shibboleth_connector_identifier=shib_id, # this is the pairwaise id 
-                email=''.join(random.choices(string.ascii_uppercase + string.digits, k=8)) + "@manual-created.polaris",
-                first_name=''.join(random.choices(string.ascii_uppercase + string.digits, k=8)),
-                last_name=''.join(random.choices(string.ascii_uppercase + string.digits, k=8))
-           )
+            lock_key = f"user_creation_lock_{shib_id}"  # "mutex" to prevent race conditions using a cache entry
+            if cache.add(lock_key, "locked", 2):  # 2 is a timeout value, after wich the cache entry is deleted
+                try:
+                    user = CustomUser.objects.create(
+                        shibboleth_connector_identifier=shib_id, # this is the pairwise id
+                        email=''.join(random.choices(string.ascii_uppercase + string.digits, k=8)) + "@manual-created.polaris",
+                        first_name=''.join(random.choices(string.ascii_uppercase + string.digits, k=8)),
+                        last_name=''.join(random.choices(string.ascii_uppercase + string.digits, k=8))
+                    )
+                except Exception as e:
+                    return JsonResponse({"message": "user could not be created"}, safe=False,
+                                        status=status.HTTP_500_INTERNAL_SERVER_ERROR)
+                finally:
+                    message = "user has been created"
+                    cache.delete(lock_key)
+            else:
+                for _ in range(4):  # Wait up to 2x lock_timeout
+                    time.sleep(0.1)
+                    if not cache.get(lock_key):
+                        break
+                # Fetch the user created by another process
+                user = CustomUser.objects.filter(shibboleth_connector_identifier=shib_id).first()
+                if not user:
+                    return JsonResponse({"message": "user could not be created"}, safe=False,
+                                        status=status.HTTP_500_INTERNAL_SERVER_ERROR)
 
         return JsonResponse(
                     {
-                        "message": "user is created",
+                        "message": message,
                     },
                     safe=False,
                     status=status.HTTP_200_OK,
diff --git a/src/xapi/views.py b/src/xapi/views.py
index ed18d1db373f9e2eb5d28fc527f5da8a6c791b58..00262b44284ca4baeaa64ccc165bcad60879eb66 100644
--- a/src/xapi/views.py
+++ b/src/xapi/views.py
@@ -85,7 +85,7 @@ def shib_connector_resolver_to_pairwaise_id(email, provider):
          additionalData = None 
          shib_id = client.service.GetOrGenerateIdAndConnect(app_secret, user_id, lrs_type, linkType, processId, additionalData)
          if len(shib_id) != 1:
-            print("Multiple pairwaise ids found, only use the first one!")
+            print("Multiple pairwise ids found, only use the first one!")
          shib_id = shib_id[0]
          if settings.DEBUG:
              print("Result shib_id: {0}".format(shib_id))