diff --git a/aleksis/core/apps.py b/aleksis/core/apps.py
index 680299673400ff4824e7dcac4f0b15d30f417754..a3efe2ce8fc43d490a90de14f5b869ccc8e45d85 100644
--- a/aleksis/core/apps.py
+++ b/aleksis/core/apps.py
@@ -30,7 +30,7 @@ class CoreConfig(AppConfig):
     def preference_updated(
         self,
         sender: Any,
-        section: Optional[str] = None,,
+        section: Optional[str] = None,
         name: Optional[str] = None,
         old_value: Optional[Any] = None,
         new_value: Optional[Any] = None,
diff --git a/aleksis/core/preferences.py b/aleksis/core/preferences.py
index d13421c39557e7c8b4aefb7bb235f8bbd079cbc1..494a972d5da39d53641581e723a7ad1d4c434b2d 100644
--- a/aleksis/core/preferences.py
+++ b/aleksis/core/preferences.py
@@ -3,11 +3,12 @@ from django.forms import EmailField, URLField
 from django.utils.translation import gettext_lazy as _
 
 from colorfield.widgets import ColorWidget
-from dynamic_preferences.types import BooleanPreference, StringPreference
+from dynamic_preferences.types import BooleanPreference, ChoicePreference, StringPreference
 from dynamic_preferences.preferences import Section
 from dynamic_preferences.registries import global_preferences_registry
 from dynamic_preferences.users.registries import user_preferences_registry
 
+from .util.notifications import get_notification_choices_lazy
 
 general = Section("general")
 theme = Section("theme")
@@ -110,7 +111,8 @@ class AdressingNameFormat(ChoicePreference):
 
 
 @user_preferences_registry.register
-class NotificationChannels(MultipleChoicePreference):
+class NotificationChannels(ChoicePreference):
+    # FIXME should be a MultipleChoicePreference
     section = notification
     name = "channels"
     default = ["email"]
diff --git a/aleksis/core/settings.py b/aleksis/core/settings.py
index 21c1264745a684767647334487aa6914200a0c7b..b712b87998fe2757b14eb8da0d87565b4d1d1a9e 100644
--- a/aleksis/core/settings.py
+++ b/aleksis/core/settings.py
@@ -410,9 +410,9 @@ if _settings.get("celery.enabled", False):
         INSTALLED_APPS += ("djcelery_email",)
         EMAIL_BACKEND = "djcelery_email.backends.CeleryEmailBackend"
 
-PWA_APP_NAME = lazy_config("general", "title")
-PWA_APP_DESCRIPTION = lazy_config("general", "description")
-PWA_APP_THEME_COLOR = lazy_config("theme", "primary")
+PWA_APP_NAME = lazy_preference("general", "title")
+PWA_APP_DESCRIPTION = lazy_preference("general", "description")
+PWA_APP_THEME_COLOR = lazy_preference("theme", "primary")
 PWA_APP_BACKGROUND_COLOR = "#ffffff"
 PWA_APP_DISPLAY = "standalone"
 PWA_APP_ORIENTATION = "any"
diff --git a/aleksis/core/static/theme.scss b/aleksis/core/static/theme.scss
index 907c444f5bf99ef3616ae47a4c6df8b2e82b011e..1b38e9bda22c7b63601a4a227d58981e2e3a8d45 100644
--- a/aleksis/core/static/theme.scss
+++ b/aleksis/core/static/theme.scss
@@ -34,11 +34,11 @@
 // 1. Colors
 // ==========================================================================
 
-$primary-color: adjust-color(get-colour(get-config(COLOUR_PRIMARY)), $alpha: 1);
+$primary-color: adjust-color(get-colour(get-preference(theme, primary)), $alpha: 1);
 $primary-color-light: lighten($primary-color, 15%) !default;
 $primary-color-dark: darken($primary-color, 15%) !default;
 
-$secondary-color: adjust-color(get-colour(get-config(COLOUR_SECONDARY)), $alpha: 1);
+$secondary-color: adjust-color(get-colour(get-preference(theme, secondary)), $alpha: 1);
 $success-color: color("green", "base") !default;
 $error-color: color("red", "base") !default;
 $link-color: color("light-blue", "darken-1") !default;
diff --git a/aleksis/core/util/apps.py b/aleksis/core/util/apps.py
index 50c9c242dbd8584480ee3b48fe1619edc3b892f6..45cde67f17ce63448c6390801742cbc93f42c1dd 100644
--- a/aleksis/core/util/apps.py
+++ b/aleksis/core/util/apps.py
@@ -36,7 +36,7 @@ class AppConfig(django.apps.AppConfig):
         user_logged_out.connect(self.user_logged_out)
 
         # Getting an app ready means it should look at its config once
-        self.config_updated()
+        self.preference_updated(self)
 
         # Register system checks of this app
         try:
@@ -129,7 +129,7 @@ class AppConfig(django.apps.AppConfig):
     def preference_updated(
         self,
         sender: Any,
-        section: Optional[str] = None,,
+        section: Optional[str] = None,
         name: Optional[str] = None,
         old_value: Optional[Any] = None,
         new_value: Optional[Any] = None,
diff --git a/aleksis/core/util/core_helpers.py b/aleksis/core/util/core_helpers.py
index 6f80f2a24282abc5f1493eeda909a6f384551aff..56acf80295546ac73cbffd4bc0e36770d8bb3687 100644
--- a/aleksis/core/util/core_helpers.py
+++ b/aleksis/core/util/core_helpers.py
@@ -13,8 +13,6 @@ from django.http import HttpRequest
 from django.utils import timezone
 from django.utils.functional import lazy
 
-from dynamic_preferences.registries import global_preferences_registry
-
 
 def copyright_years(years: Sequence[int], seperator: str = ", ", joiner: str = "–") -> str:
     """ Takes a sequence of integegers and produces a string with ranges
@@ -95,6 +93,9 @@ def lazy_preference(section: str, name: str) -> Callable[[str, str], Any]:
     """
 
     def _get_preference(section: str, name: str) -> Any:
+        from dynamic_preferences.registries import global_preferences_registry  # noqa
+        global_preferences = global_preferences_registry.manager()
+
         return global_preferences["%s__%s" % (section, name)]
 
     # The type is guessed from the default value to improve lazy()'s behaviour
diff --git a/aleksis/core/util/notifications.py b/aleksis/core/util/notifications.py
index 7f309d1cc2e0a0a046334683f5e2100f28fdae2c..57243a00c99410c30f0a34d952efed7e2d162e21 100644
--- a/aleksis/core/util/notifications.py
+++ b/aleksis/core/util/notifications.py
@@ -15,7 +15,7 @@ try:
 except ImportError:
     TwilioClient = None
 
-from .core_helpers import celery_optional, lazy_config
+from .core_helpers import celery_optional, lazy_preference
 
 
 def send_templated_sms(
@@ -38,7 +38,7 @@ def _send_notification_email(notification: "Notification", template: str = "noti
     }
     send_templated_mail(
         template_name=template,
-        from_email=lazy_config("MAIL_OUT"),
+        from_email=lazy_preference("notification__mail_out"),
         recipient_list=[notification.recipient.email],
         context=context,
     )
@@ -63,7 +63,7 @@ def _send_notification_sms(
 # - Check for availability
 # - Send notification through it
 _CHANNELS_MAP = {
-    "email": (_("E-Mail"), lambda: lazy_config("MAIL_OUT"), _send_notification_email),
+    "email": (_("E-Mail"), lambda: lazy_preference("notification__mail_out"), _send_notification_email),
     "sms": (_("SMS"), lambda: getattr(settings, "TWILIO_SID", None), _send_notification_sms),
 }
 
@@ -75,7 +75,7 @@ def send_notification(notification: Union[int, "Notification"], resend: bool = F
     previously marked as sent.
     """
 
-    channels = lazy_config("NOTIFICATION_CHANNELS")
+    channels = lazy_preference("notification__channels")
 
     if isinstance(notification, int):
         Notification = apps.get_model("core", "Notification")