diff --git a/api/config/settings/common.py b/api/config/settings/common.py
index 43a7a29f52ffd53b49161cdcabe2468ea015facd..3237718e0cbd7ece155e668395cd12019f697189 100644
--- a/api/config/settings/common.py
+++ b/api/config/settings/common.py
@@ -515,7 +515,6 @@ CACHES = {
         "LOCATION": "local-cache",
     },
 }
-
 CACHES["default"]["BACKEND"] = "django_redis.cache.RedisCache"
 
 CHANNEL_LAYERS = {
@@ -530,7 +529,20 @@ CACHES["default"]["OPTIONS"] = {
     "IGNORE_EXCEPTIONS": True,  # mimics memcache behavior.
     # http://niwinz.github.io/django-redis/latest/#_memcached_exceptions_behavior
 }
-
+CACHEOPS_DURATION = env("CACHEOPS_DURATION", default=0)
+CACHEOPS_ENABLED = bool(CACHEOPS_DURATION)
+
+if CACHEOPS_ENABLED:
+    INSTALLED_APPS += ("cacheops",)
+    CACHEOPS_REDIS = env("CACHE_URL", default=CACHE_DEFAULT)
+    CACHEOPS_PREFIX = lambda _: "cacheops"  # noqa
+    CACHEOPS_DEFAULTS = {"timeout": CACHEOPS_DURATION}
+    CACHEOPS = {
+        "users.user": {"ops": "get"},
+        "music.album": {"ops": "count"},
+        "music.artist": {"ops": "count"},
+        "music.track": {"ops": "count"},
+    }
 
 # CELERY
 INSTALLED_APPS += ("funkwhale_api.taskapp.celery.CeleryConfig",)
diff --git a/api/requirements/base.txt b/api/requirements/base.txt
index 63b1063f69d92faf4ad64d250d90c68b22a3db13..4f87e1ba893112b69ab587fd5bc17b130a7fb54b 100644
--- a/api/requirements/base.txt
+++ b/api/requirements/base.txt
@@ -72,3 +72,4 @@ django-oauth-toolkit==1.2
 django-storages==1.7.1
 boto3<3
 unicode-slugify
+django-cacheops==4.2