diff --git a/api/config/settings/common.py b/api/config/settings/common.py
index a20081dd2f3905c90baade172c51ee1fbe506f13..f33c338a9c38e400744061dc982c7759225a985e 100644
--- a/api/config/settings/common.py
+++ b/api/config/settings/common.py
@@ -816,6 +816,11 @@ SESSION_ENGINE = "django.contrib.sessions.backends.cache"
 # XXX: deprecated, see #186
 PLAYLISTS_MAX_TRACKS = env.int("PLAYLISTS_MAX_TRACKS", default=250)
 
+# not hard limits, but only applied in API responses
+ARTIST_MAX_ALBUMS = env.int("_ARTIST_MAX_ALBUMS", default=12)
+ALBUM_MAX_TRACKS = env.int("_ALBUM_MAX_TRACKS", default=50)
+TRACK_MAX_UPLOADS = env.int("_TRACK_MAX_UPLOADS", default=5)
+
 ACCOUNT_USERNAME_BLACKLIST = [
     "funkwhale",
     "library",
diff --git a/api/funkwhale_api/music/serializers.py b/api/funkwhale_api/music/serializers.py
index 77854d437647a3e661ea462c33217db0b3425447..6c97dd0f61b13c890669644f08f83e4adf7c441d 100644
--- a/api/funkwhale_api/music/serializers.py
+++ b/api/funkwhale_api/music/serializers.py
@@ -77,9 +77,10 @@ class ArtistAlbumSerializer(serializers.ModelSerializer):
 
 
 class ArtistWithAlbumsSerializer(serializers.ModelSerializer):
-    albums = ArtistAlbumSerializer(many=True, read_only=True)
     tags = serializers.SerializerMethodField()
     attributed_to = serializers.SerializerMethodField()
+    albums = serializers.SerializerMethodField()
+    albums_count = serializers.SerializerMethodField()
     tracks_count = serializers.SerializerMethodField()
 
     class Meta:
@@ -94,6 +95,7 @@ class ArtistWithAlbumsSerializer(serializers.ModelSerializer):
             "is_local",
             "tags",
             "attributed_to",
+            "albums_count",
             "tracks_count",
         )
 
@@ -107,6 +109,16 @@ class ArtistWithAlbumsSerializer(serializers.ModelSerializer):
         tracks = getattr(o, "_prefetched_tracks", None)
         return len(tracks) if tracks else None
 
+    def get_albums(self, o):
+        ordered_albums = list(o.albums.all())[: settings.ARTIST_MAX_ALBUMS]
+        return [
+            ArtistAlbumSerializer(album).data
+            for album in ordered_albums[: settings.ARTIST_MAX_ALBUMS]
+        ]
+
+    def get_albums_count(self, o):
+        return len(list(o.albums.all()))
+
 
 def serialize_artist_simple(artist):
     return {
@@ -150,6 +162,7 @@ class AlbumSerializer(serializers.ModelSerializer):
     artist = serializers.SerializerMethodField()
     cover = cover_field
     is_playable = serializers.SerializerMethodField()
+    tracks_count = serializers.SerializerMethodField()
     tags = serializers.SerializerMethodField()
     attributed_to = serializers.SerializerMethodField()
 
@@ -169,6 +182,7 @@ class AlbumSerializer(serializers.ModelSerializer):
             "is_local",
             "tags",
             "attributed_to",
+            "tracks_count",
         )
 
     get_attributed_to = serialize_attributed_to
@@ -177,8 +191,11 @@ class AlbumSerializer(serializers.ModelSerializer):
         return serialize_artist_simple(o.artist)
 
     def get_tracks(self, o):
-        ordered_tracks = o.tracks.all()
-        return [serialize_album_track(track) for track in ordered_tracks]
+        ordered_tracks = list(o.tracks.all())[: settings.ALBUM_MAX_TRACKS]
+        return [
+            serialize_album_track(track)
+            for track in ordered_tracks[: settings.ALBUM_MAX_TRACKS]
+        ]
 
     def get_is_playable(self, obj):
         try:
@@ -192,6 +209,9 @@ class AlbumSerializer(serializers.ModelSerializer):
         tagged_items = getattr(obj, "_prefetched_tagged_items", [])
         return [ti.tag.name for ti in tagged_items]
 
+    def get_tracks_count(self, o):
+        return len(list(o.tracks.all()))
+
 
 class TrackAlbumSerializer(serializers.ModelSerializer):
     artist = serializers.SerializerMethodField()
@@ -231,6 +251,7 @@ class TrackSerializer(serializers.ModelSerializer):
     artist = serializers.SerializerMethodField()
     album = TrackAlbumSerializer(read_only=True)
     uploads = serializers.SerializerMethodField()
+    uploads_count = serializers.SerializerMethodField()
     listen_url = serializers.SerializerMethodField()
     tags = serializers.SerializerMethodField()
     attributed_to = serializers.SerializerMethodField()
@@ -254,6 +275,7 @@ class TrackSerializer(serializers.ModelSerializer):
             "is_local",
             "tags",
             "attributed_to",
+            "uploads_count",
         )
 
     get_attributed_to = serialize_attributed_to
@@ -265,7 +287,15 @@ class TrackSerializer(serializers.ModelSerializer):
         return obj.listen_url
 
     def get_uploads(self, obj):
-        return [serialize_upload(u) for u in getattr(obj, "playable_uploads", [])]
+        return [
+            serialize_upload(u)
+            for u in list(getattr(obj, "playable_uploads", []))[
+                : settings.TRACK_MAX_UPLOADS
+            ]
+        ]
+
+    def get_uploads_count(self, obj):
+        return len(list(getattr(obj, "playable_uploads", [])))
 
     def get_tags(self, obj):
         tagged_items = getattr(obj, "_prefetched_tagged_items", [])
diff --git a/api/tests/music/test_serializers.py b/api/tests/music/test_serializers.py
index 4eaf54ad54aa0559a3c05662c8f78b2960276b1b..e1b420665fff8656be97f295bd0fbe9a1eb1fd52 100644
--- a/api/tests/music/test_serializers.py
+++ b/api/tests/music/test_serializers.py
@@ -56,9 +56,11 @@ def test_artist_album_serializer(factories, to_api_date):
     assert serializer.data == expected
 
 
-def test_artist_with_albums_serializer(factories, to_api_date):
+def test_artist_with_albums_serializer(factories, to_api_date, settings):
+    settings.ARTIST_MAX_ALBUMS = 1
     actor = factories["federation.Actor"]()
     track = factories["music.Track"](album__artist__attributed_to=actor)
+    factories["music.Album"](artist=track.album.artist)
     artist = track.artist
     artist = artist.__class__.objects.with_albums().get(pk=artist.pk)
     album = list(artist.albums.all())[0]
@@ -74,6 +76,7 @@ def test_artist_with_albums_serializer(factories, to_api_date):
         "tags": [],
         "attributed_to": federation_serializers.APIActorSerializer(actor).data,
         "tracks_count": 42,
+        "albums_count": 2,
     }
     serializer = serializers.ArtistWithAlbumsSerializer(artist)
     assert serializer.data == expected
@@ -159,10 +162,12 @@ def test_upload_owner_serializer(factories, to_api_date):
     assert serializer.data == expected
 
 
-def test_album_serializer(factories, to_api_date):
+def test_album_serializer(factories, to_api_date, settings):
+    settings.ALBUM_MAX_TRACKS = 2
     actor = factories["federation.Actor"]()
     track1 = factories["music.Track"](position=2, album__attributed_to=actor)
     track2 = factories["music.Track"](position=1, album=track1.album)
+    factories["music.Track"](position=3, album=track1.album)
     album = track1.album
     expected = {
         "id": album.id,
@@ -183,13 +188,15 @@ def test_album_serializer(factories, to_api_date):
         "is_local": album.is_local,
         "tags": [],
         "attributed_to": federation_serializers.APIActorSerializer(actor).data,
+        "tracks_count": 3,
     }
     serializer = serializers.AlbumSerializer(album)
 
     assert serializer.data == expected
 
 
-def test_track_serializer(factories, to_api_date):
+def test_track_serializer(factories, to_api_date, settings):
+    settings.TRACK_MAX_UPLOADS = 1
     actor = factories["federation.Actor"]()
     upload = factories["music.Upload"](
         track__license="cc-by-4.0",
@@ -198,7 +205,8 @@ def test_track_serializer(factories, to_api_date):
         track__attributed_to=actor,
     )
     track = upload.track
-    setattr(track, "playable_uploads", [upload])
+    hidden_upload = factories["music.Upload"]()
+    setattr(track, "playable_uploads", [upload, hidden_upload])
     expected = {
         "id": track.id,
         "fid": track.fid,
@@ -209,6 +217,7 @@ def test_track_serializer(factories, to_api_date):
         "position": track.position,
         "disc_number": track.disc_number,
         "uploads": [serializers.serialize_upload(upload)],
+        "uploads_count": 2,
         "creation_date": to_api_date(track.creation_date),
         "listen_url": track.listen_url,
         "license": upload.track.license.code,
diff --git a/docs/swagger.yml b/docs/swagger.yml
index a6952098b1243f8b2dc76e5db7285331c4712803..b9d4ed246ab0d643ad8ecc91a7a9d5517135c20c 100644
--- a/docs/swagger.yml
+++ b/docs/swagger.yml
@@ -1282,8 +1282,14 @@ definitions:
             example: 42
           albums:
             type: "array"
+            description: "List of albums associated with this artist. The list is truncated to avoid returning 100s of objects."
             items:
               $ref: "#/definitions/ArtistAlbum"
+          albums_count:
+            type: "number"
+            minimum: 0
+            example: 12
+            description: "Total number of albums associated with the artist"
 
   BaseAlbum:
     type: "object"
@@ -1330,8 +1336,14 @@ definitions:
         properties:
           tracks:
             type: "array"
+            description: "List of tracks associated with this album. The list is truncated to avoid returning 100s of objects."
             items:
               $ref: "#/definitions/AlbumTrack"
+          tracks_count:
+            type: "number"
+            minimum: 0
+            example: 12
+            description: "Total number of tracks associated with the album"
 
   ArtistAlbum:
     type: "object"
@@ -1499,9 +1511,14 @@ definitions:
             $ref: "#/definitions/BaseArtist"
           uploads:
             type: "array"
-            description: "List of uploads associated with this track"
+            description: "List of uploads associated with this track. The list is truncated to avoid returning 100s of objects."
             items:
               $ref: "#/definitions/Upload"
+          uploads_count:
+            type: "number"
+            minimum: 0
+            example: 12
+            description: "Total number of uploads associated with the track"
   Upload:
     type: "object"
     properties:
diff --git a/front/src/components/audio/PlayButton.vue b/front/src/components/audio/PlayButton.vue
index 96e210e7df5362486b6e49163e6ff5b8392e54bc..ed9397c903245a190511c390d7d0e29204858509 100644
--- a/front/src/components/audio/PlayButton.vue
+++ b/front/src/components/audio/PlayButton.vue
@@ -199,7 +199,7 @@ export default {
           let params = {'artist': self.artist.id, 'ordering': 'album__release_date,position'}
           self.getTracksPage(1, params, resolve)
         } else if (self.album) {
-          let params = {'album': self.album.id, 'ordering': 'position'}
+          let params = {'album': self.album.id, 'ordering': 'position,creation_date'}
           self.getTracksPage(1, params, resolve)
         }
       })
diff --git a/front/src/components/audio/album/Card.vue b/front/src/components/audio/album/Card.vue
index 67d1eb706cc68e3145583c26f464f0017bd3a1ec..3c145a33eefc527f40281f3ab65b366c04356db7 100644
--- a/front/src/components/audio/album/Card.vue
+++ b/front/src/components/audio/album/Card.vue
@@ -45,7 +45,7 @@
         </div>
       </div>
       <div class="extra content">
-        <play-button class="mini basic orange right floated" :tracks="tracksWithAlbum" :album="album">
+        <play-button class="mini basic orange right floated" :is-playable="album.is_playable" :album="album">
           <translate translate-context="Content/Queue/Button.Label/Short, Verb">Play all</translate>
         </play-button>
         <span>
diff --git a/front/src/components/library/AlbumBase.vue b/front/src/components/library/AlbumBase.vue
index e42f3e826be6cec0707577b85203af0d2e6c71c6..f11e66ad8c0a1a1bc7d5bcf4aa072924c1995468 100644
--- a/front/src/components/library/AlbumBase.vue
+++ b/front/src/components/library/AlbumBase.vue
@@ -18,7 +18,7 @@
           <div class="header-buttons">
 
             <div class="ui buttons">
-              <play-button class="orange" :tracks="object.tracks">
+              <play-button class="orange" :album="object" :is-playable="object.is_playable">
                 <translate translate-context="Content/Queue/Button.Label/Short, Verb">Play all</translate>
               </play-button>
             </div>
@@ -161,6 +161,7 @@ export default {
         self.object = backend.Album.clean(response.data)
         self.discs = self.object.tracks.reduce(groupByDisc, [])
         self.isLoading = false
+        // todoooo
       })
     }
   },