diff --git a/aleksis/core/managers.py b/aleksis/core/managers.py
index a0871078015df8e117a09e23a593b384f7b25dc2..02a0cb6fb6504d931b3d848217b154951d8a0932 100644
--- a/aleksis/core/managers.py
+++ b/aleksis/core/managers.py
@@ -79,3 +79,15 @@ class SchoolTermRelatedQuerySet(QuerySet):
             return self.for_school_term(current_school_term)
         else:
             return None
+
+
+class GroupManager(CurrentSiteManagerWithoutMigrations):
+    """Manager adding specific methods to groups."""
+
+    def get_queryset(self):
+        """Ensure all related data is loaded as well."""
+        return super().get_queryset().select_related("school_term")
+
+
+class GroupQuerySet(SchoolTermRelatedQuerySet):
+    pass
diff --git a/aleksis/core/mixins.py b/aleksis/core/mixins.py
index d4a8fcf7023f431857c05fad2362658fdadbe321..b9d96809dd3caea14039612a267f6d4112c672a0 100644
--- a/aleksis/core/mixins.py
+++ b/aleksis/core/mixins.py
@@ -115,7 +115,7 @@ class ExtensibleModel(models.Model, metaclass=_ExtensibleModelBase):
 
         return CRUDEvent.objects.filter(
             object_id=self.pk, content_type=content_type
-        ).select_related("user")
+        ).select_related("user", "user__person")
 
     @property
     def crud_event_create(self) -> Optional[CRUDEvent]:
diff --git a/aleksis/core/models.py b/aleksis/core/models.py
index bd1cfe12d531e95e4a5d0b7d1e480cf60b91717f..2231fb36057c2c33edec8d6b4e1384e5693ac331 100644
--- a/aleksis/core/models.py
+++ b/aleksis/core/models.py
@@ -19,11 +19,17 @@ from django.utils.text import slugify
 from django.utils.translation import gettext_lazy as _
 
 import jsonstore
+from cache_memoize import cache_memoize
 from dynamic_preferences.models import PerInstancePreferenceModel
 from phonenumber_field.modelfields import PhoneNumberField
 from polymorphic.models import PolymorphicModel
 
-from .managers import CurrentSiteManagerWithoutMigrations, SchoolTermQuerySet
+from .managers import (
+    CurrentSiteManagerWithoutMigrations,
+    GroupManager,
+    GroupQuerySet,
+    SchoolTermQuerySet,
+)
 from .mixins import ExtensibleModel, PureDjangoModel, SchoolTermRelatedExtensibleModel
 from .tasks import send_notification
 from .util.core_helpers import get_site_preferences, now_tomorrow
@@ -59,6 +65,7 @@ class SchoolTerm(ExtensibleModel):
     date_end = models.DateField(verbose_name=_("End date"))
 
     @classmethod
+    @cache_memoize(3600)
     def get_current(cls, day: Optional[date] = None):
         if not day:
             day = timezone.now().date()
@@ -313,6 +320,8 @@ class Group(SchoolTermRelatedExtensibleModel):
     classes, clubs, and the like.
     """
 
+    objects = GroupManager.from_queryset(GroupQuerySet)()
+
     class Meta:
         ordering = ["short_name", "name"]
         verbose_name = _("Group")
@@ -681,9 +690,10 @@ class CustomMenu(ExtensibleModel):
         return self.name if self.name != "" else self.id
 
     @classmethod
+    @cache_memoize(3600)
     def get_default(cls, name):
         """Get a menu by name or create if it does not exist."""
-        menu, _ = cls.objects.get_or_create(name=name)
+        menu, _ = cls.objects.prefetch_related("items").get_or_create(name=name)
         return menu
 
     class Meta:
diff --git a/aleksis/core/util/core_helpers.py b/aleksis/core/util/core_helpers.py
index 788a4debec2a9ec7b3fb6c52f97121dbe9179340..9875c6429cd2e0fa623f9b9c8423d512576dbe9e 100644
--- a/aleksis/core/util/core_helpers.py
+++ b/aleksis/core/util/core_helpers.py
@@ -134,6 +134,7 @@ def lazy_get_favicon_url(
 ) -> Callable[[str, str], Any]:
     """Lazily get the URL to a favicon image."""
 
+    @cache_memoize(3600)
     def _get_favicon_url(size: int, rel: str) -> Any:
         from favicon.models import Favicon  # noqa