diff --git a/Dockerfile b/Dockerfile
index c68406e15ee89081d9aa17a4465880e508901f38..0800cf06e23a7b50cb5f3c0a7b6b7e7130ab9d03 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -17,13 +17,13 @@ WORKDIR /home/worker/code
 ENV PYTHONPATH=/home/worker/code
 ENV PATH="/home/worker/.local/bin:${PATH}"
 
-COPY ./start_service_uvicorn.sh /home/worker/code/start.sh
-COPY ./scripts/prestart.sh /home/worker/code/prestart.sh
+COPY --chown=worker:worker ./start_service_uvicorn.sh ./start.sh
+COPY --chown=worker:worker ./scripts/prestart.sh ./prestart.sh
 
 COPY --chown=worker:worker requirements.txt ./requirements.txt
 
 RUN pip install --user --no-cache-dir --upgrade -r requirements.txt
 
-COPY --chown=worker:worker ./app /home/worker/code/app
+COPY --chown=worker:worker ./app ./app
 
 CMD ["./start.sh"]
diff --git a/app/api/api.py b/app/api/api.py
index 3ba0060f85d9dc0c78a3ea8ff2d2afded3f9e462..0a2071438bd996ebf26256cfcbf3cd41f85c8286 100644
--- a/app/api/api.py
+++ b/app/api/api.py
@@ -4,6 +4,7 @@ from fastapi import APIRouter, Depends, status
 
 from app.api.dependencies import decode_bearer_token
 from app.api.endpoints import bucket_permissions, buckets, s3key
+from app.api.endpoints.miscellaneous_endpoints import router as miscellaneous_router
 from app.schemas.security import ErrorDetail
 
 alternative_responses: Dict[Union[int, str], Dict[str, Any]] = {
@@ -40,3 +41,4 @@ api_router.include_router(
     dependencies=[Depends(decode_bearer_token)],
     responses=alternative_responses,
 )
+api_router.include_router(miscellaneous_router)
diff --git a/app/api/dependencies.py b/app/api/dependencies.py
index 69be9130118e79c9c33aaa97573f4a6e1e2d8fbc..c4182daa3f466dc3090da5020caf6288d0d9d136 100644
--- a/app/api/dependencies.py
+++ b/app/api/dependencies.py
@@ -44,7 +44,7 @@ def get_s3_resource() -> S3ServiceResource:
 S3Resource = Annotated[S3ServiceResource, Depends(get_s3_resource)]
 
 
-async def get_db() -> AsyncGenerator[AsyncSession, None]:
+async def get_db() -> AsyncGenerator[AsyncSession, None]:  # pragma: no cover
     """
     Get a Session with the database.
 
@@ -142,7 +142,7 @@ async def get_current_user(token: Annotated[JWT, Depends(decode_bearer_token)],
     """
     try:
         uid = UUID(token.sub)
-    except ValueError:
+    except ValueError:  # pragma: no cover
         raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="Malformed JWT")
     user = await CRUDUser.get(db, uid)
     if user:
diff --git a/app/api/miscellaneous_endpoints.py b/app/api/endpoints/miscellaneous_endpoints.py
similarity index 85%
rename from app/api/miscellaneous_endpoints.py
rename to app/api/endpoints/miscellaneous_endpoints.py
index 0f4f786b06506ed0843fceb5f84a7a791441ab2e..1d188ffc6b6dc20bf7d360e6b4740f5539078a59 100644
--- a/app/api/miscellaneous_endpoints.py
+++ b/app/api/endpoints/miscellaneous_endpoints.py
@@ -2,10 +2,10 @@ from typing import Dict
 
 from fastapi import APIRouter, status
 
-miscellaneous_router = APIRouter(include_in_schema=False)
+router = APIRouter(include_in_schema=False)
 
 
-@miscellaneous_router.get(
+@router.get(
     "/health",
     tags=["Miscellaneous"],
     responses={
diff --git a/app/main.py b/app/main.py
index fff58814b75024bda371b0a6ef0bdb8989f72152..0fad3197f0c886c5da38e9e5f986a1dac288bc44 100644
--- a/app/main.py
+++ b/app/main.py
@@ -2,10 +2,10 @@ from contextlib import asynccontextmanager
 from hashlib import md5
 from typing import AsyncGenerator
 
+from brotli_asgi import BrotliMiddleware
 from fastapi import FastAPI, Request, Response, status
 from fastapi.exception_handlers import http_exception_handler, request_validation_exception_handler
 from fastapi.exceptions import RequestValidationError, StarletteHTTPException
-from fastapi.middleware.gzip import GZipMiddleware
 from fastapi.openapi.docs import get_swagger_ui_html
 from fastapi.responses import HTMLResponse, JSONResponse
 from fastapi.routing import APIRoute
@@ -19,7 +19,6 @@ from opentelemetry.sdk.trace.export import BatchSpanProcessor
 from opentelemetry.trace import Status, StatusCode
 
 from app.api.api import api_router
-from app.api.miscellaneous_endpoints import miscellaneous_router
 from app.core.config import settings
 
 description = """
@@ -49,7 +48,7 @@ app = FastAPI(
         "email": "dgoebel@techfak.uni-bielefeld.de",
     },
     generate_unique_id_function=custom_generate_unique_id,
-    # license_info={"name": "MIT", "url": "https://mit-license.org/"},
+    license_info={"name": "Apache 2.0", "url": "https://www.apache.org/licenses/LICENSE-2.0"},
     root_path=settings.API_PREFIX,
     openapi_url=None,  # create it manually to enable caching on client side
     lifespan=lifespan,
@@ -84,12 +83,11 @@ FastAPIInstrumentor.instrument_app(
     app, excluded_urls="health,docs,openapi.json", tracer_provider=trace.get_tracer_provider()
 )
 
-# Enable gzip compression for large responses
-app.add_middleware(GZipMiddleware, minimum_size=500)
+# Enable br compression for large responses, fallback gzip
+app.add_middleware(BrotliMiddleware)
 
 # Include all routes
 app.include_router(api_router)
-app.include_router(miscellaneous_router)
 
 
 # manually add Swagger UI route
diff --git a/app/schemas/__init__.py b/app/schemas/__init__.py
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..926fe48166e02c6c576eba62e455c3a82b51fc63 100644
--- a/app/schemas/__init__.py
+++ b/app/schemas/__init__.py
@@ -0,0 +1,6 @@
+from typing import Annotated
+from uuid import UUID as NativeUUID
+
+from pydantic.functional_serializers import PlainSerializer
+
+UUID = Annotated[NativeUUID, PlainSerializer(lambda uuid: str(uuid), return_type=str, when_used="unless-none")]
diff --git a/app/schemas/bucket.py b/app/schemas/bucket.py
index c30770b7c515f734eac3ace2356c74a78c944116..bb81a3834c2f5bd7115847737c459b2bc4066804 100644
--- a/app/schemas/bucket.py
+++ b/app/schemas/bucket.py
@@ -1,10 +1,11 @@
 import re
 from typing import Optional
-from uuid import UUID
 
 from clowmdb.models import Bucket
 from pydantic import BaseModel, ConfigDict, Field, field_validator
 
+from app.schemas import UUID
+
 ip_like_regex = re.compile(r"^(\d+\.){3}\d+$")
 
 
diff --git a/app/schemas/bucket_permission.py b/app/schemas/bucket_permission.py
index 99217183c251d9d139e0067eda9fc5767d35eaa2..6a1225e2dfb47773ad6259a77942cf65ac274da3 100644
--- a/app/schemas/bucket_permission.py
+++ b/app/schemas/bucket_permission.py
@@ -1,10 +1,11 @@
 import hashlib
 from datetime import datetime
 from typing import Any, Dict, List, Optional, Union
-from uuid import UUID
 
 from clowmdb.models import BucketPermission as BucketPermissionDB
-from pydantic import BaseModel, Field, field_serializer
+from pydantic import BaseModel, Field
+
+from app.schemas import UUID
 
 
 class BucketPermissionParameters(BaseModel):
@@ -32,10 +33,6 @@ class BucketPermissionIn(BucketPermissionParameters):
     uid: UUID = Field(..., description="UID of the grantee", examples=["1d3387f3-95c0-4813-8767-2cad87faeebf"])
     bucket_name: str = Field(..., description="Name of Bucket", examples=["test-bucket"])
 
-    @field_serializer("uid")
-    def serialize_uid(self, uid: UUID, _info: Any) -> str:
-        return str(uid)
-
     def to_hash(self, uid: UUID) -> str:
         """
         Combine the bucket name and user id and produce the MD5 hash of it.
diff --git a/app/schemas/s3key.py b/app/schemas/s3key.py
index eae80d27a78ccd1eb46149f1a6eed815f2a6e860..233a0e914051c58f4d4284959892d33d3f18a803 100644
--- a/app/schemas/s3key.py
+++ b/app/schemas/s3key.py
@@ -1,7 +1,6 @@
-from typing import Any
-from uuid import UUID
+from pydantic import BaseModel, Field
 
-from pydantic import BaseModel, Field, field_serializer
+from app.schemas import UUID
 
 
 class S3Key(BaseModel):
@@ -18,7 +17,3 @@ class S3Key(BaseModel):
         description="Secret of the S3 access key",
         examples=["2F5uNTI1qvt4oAroXV0wWct8rWclL2QvFXKqSqjS"],
     )
-
-    @field_serializer("uid")
-    def serialize_uid(self, uid: UUID, _info: Any) -> str:
-        return str(uid)
diff --git a/app/schemas/security.py b/app/schemas/security.py
index a6d7bd8293e64f047eeff0369271b577612a74e5..d065001db07cf1c76133a507398889f46f8a0bac 100644
--- a/app/schemas/security.py
+++ b/app/schemas/security.py
@@ -1,8 +1,8 @@
 from datetime import datetime
-from typing import Any
-from uuid import UUID
 
-from pydantic import BaseModel, Field, field_serializer
+from pydantic import BaseModel, Field
+
+from app.schemas import UUID
 
 
 class AuthzResponse(BaseModel):
@@ -15,10 +15,6 @@ class AuthzResponse(BaseModel):
     )
     result: bool = Field(..., description="Result of the Authz request")
 
-    @field_serializer("decision_id")
-    def serialize_decision_id(self, decision_id: UUID, _info: Any) -> str:
-        return str(decision_id)
-
 
 class AuthzRequest(BaseModel):
     """Schema for a Request to OPA"""
diff --git a/app/tests/api/test_bucket_permissions.py b/app/tests/api/test_bucket_permissions.py
index 6ea86c774cf1bc379fa3e00856cb54b4b4bd340e..153e0d8b0adee8eebb7ff1cbe2868464c609d5af 100644
--- a/app/tests/api/test_bucket_permissions.py
+++ b/app/tests/api/test_bucket_permissions.py
@@ -1,4 +1,3 @@
-import json
 from datetime import datetime
 from uuid import uuid4
 
@@ -14,7 +13,6 @@ from app.schemas.bucket_permission import BucketPermissionOut
 from app.schemas.bucket_permission import BucketPermissionParameters as BucketPermissionParametersSchema
 from app.tests.utils.bucket import add_permission_for_bucket
 from app.tests.utils.user import UserWithAuthHeader
-from app.tests.utils.utils import json_datetime_converter
 
 
 class _TestBucketPermissionRoutes:
@@ -604,7 +602,7 @@ class TestBucketPermissionRoutesUpdate(_TestBucketPermissionRoutes):
         response = await client.put(
             f"{self.base_path}/bucket/{random_bucket_permission_schema.bucket_name}/user/{str(random_bucket_permission_schema.uid)}",  # noqa:E501
             headers=random_user.auth_headers,
-            content=json.dumps(new_params.model_dump(), default=json_datetime_converter),
+            json=new_params.model_dump(),
         )
         assert response.status_code == status.HTTP_200_OK
         updated_permission = BucketPermissionOut.model_validate(response.json())
diff --git a/app/tests/utils/utils.py b/app/tests/utils/utils.py
index e20970d9ce67751af07a4fac165f3527fa906569..85cd4090ac8ea8bc2b2e5311f8a5dbb9908cdb42 100644
--- a/app/tests/utils/utils.py
+++ b/app/tests/utils/utils.py
@@ -1,7 +1,6 @@
 import random
 import string
-from datetime import datetime
-from typing import Any, Dict, Optional
+from typing import Dict
 
 import httpx
 
@@ -35,26 +34,6 @@ def random_ipv4_string() -> str:
     return ".".join(str(random.randint(0, 255)) for _ in range(4))
 
 
-def json_datetime_converter(obj: Any) -> Optional[str]:
-    """
-    Helper function for the json converter to covert the object into a string format if it is a datetime object.\n
-    Parse a datetime object into the format YYYY-MM-DDTHH:MM:SS, e.g. 2022-01-01T00:00:00
-
-    Parameters
-    ----------
-    obj : Any
-        Object to try convert as a datetime object.
-
-    Returns
-    -------
-    time : str | None
-        The str representation of a datetime object, None otherwise
-    """
-    if isinstance(obj, datetime):
-        return obj.strftime("%Y-%m-%dT%H:%M:%S")
-    return None
-
-
 def request_admin_permission(request: httpx.Request) -> bool:
     """
     Rudimentary helper function to determine if the authorization request needs the 'administrator' role.
diff --git a/pyproject.toml b/pyproject.toml
index 7e3d3f75d952f63ed36f9363f22d4e03863e69d8..cc3c81d43a9679ee28ba9f36b46ea5befe903f8f 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -8,7 +8,7 @@ line-length = 120
 
 [tool.ruff]
 line-length = 120
-target-version = "py311"
+target-version = "py312"
 
 [tool.mypy]
 plugins = ["pydantic.mypy", "sqlalchemy.ext.mypy.plugin"]
diff --git a/requirements.txt b/requirements.txt
index ddcfc6cd3b3b34b3839c96a0147d8f3dca097669..e4fb6fd35530ed153a77d488e63dba3be88ae9e2 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -18,6 +18,9 @@ rgwadmin>=2.4.0,<2.5.0
 tenacity>=8.2.0,<8.3.0
 httpx>=0.26.0,<0.27.0
 itsdangerous
+# Compression with br algorithm
+brotli-asgi>=1.4.0,<1.5.0
+
 # Monitoring
 opentelemetry-instrumentation-fastapi
 opentelemetry-exporter-otlp-proto-grpc