diff --git a/CTFd/api/v1/scoreboard.py b/CTFd/api/v1/scoreboard.py
index f9a67f8a2ea45e5dac14f1d8f188c84b3cb3f94b..c4d35ed8580e172fe070abf33333ed121c59399c 100644
--- a/CTFd/api/v1/scoreboard.py
+++ b/CTFd/api/v1/scoreboard.py
@@ -27,86 +27,124 @@ class ScoreboardList(Resource):
     @check_score_visibility
     @cache.cached(timeout=60, key_prefix=make_cache_key)
     def get(self):
-        standings = get_standings()
-        response = []
         mode = get_config("user_mode")
         account_type = get_mode_as_word()
-
+        freeze = get_config("freeze")
+        
+        standings = get_standings()
+        team_ids = [x.account_id for x in standings]
+        
+        fails_query = db.session.query(
+            Fails.account_id, 
+            Fails.challenge_id,
+            Fails.value
+        ).filter(Fails.account_id.in_(team_ids))
+        
+        if freeze:
+            fails_query = fails_query.filter(Fails.date < unix_time_to_utc(freeze))
+        
+        # Précharger toutes les informations de challenges en une seule requête
+        from sqlalchemy import distinct
+        challenge_ids = db.session.query(distinct(Fails.challenge_id)).filter(
+            Fails.account_id.in_(team_ids)
+        ).all()
+        challenge_ids = [c[0] for c in challenge_ids]
+        
+        challenges = {}
+        if challenge_ids:
+            challenges_data = db.session.query(
+                Challenges.id, 
+                Challenges.type, 
+                Challenges.value
+            ).filter(Challenges.id.in_(challenge_ids)).all()
+            
+            challenges = {c.id: c for c in challenges_data}
+        
+        potential_scores = defaultdict(int)
+        for fail in fails_query.all():
+            challenge = challenges.get(fail.challenge_id)
+            if not challenge:
+                continue
+                
+            if challenge.type in ("manual", "manualRecursive", "flash"):
+                potential_scores[fail.account_id] += challenge.value
+            elif challenge.type == "sport":
+                potential_scores[fail.account_id] += fail.value
+        
+        response = []
+        
         if mode == TEAMS_MODE:
-            r = db.session.execute(
-                select(
-                    [
-                        Users.id,
-                        Users.name,
-                        Users.oauth_id,
-                        Users.team_id,
-                        Users.hidden,
-                        Users.color,
-                        Users.banned,
-                        Users.bracket_id,
-                        Brackets.name.label("bracket_name"),
-                    ]
-                )
-                .where(Users.team_id.isnot(None))
-                .join(Brackets, Users.bracket_id == Brackets.id, isouter=True)
+            users_query = db.session.query(
+                Users.id,
+                Users.name,
+                Users.oauth_id,
+                Users.team_id,
+                Users.hidden,
+                Users.color,
+                Users.banned,
+                Users.bracket_id,
+                Brackets.name.label("bracket_name")
+            ).filter(
+                Users.team_id.isnot(None),
+                Users.hidden.is_(False),
+                Users.banned.is_(False)
+            ).join(
+                Brackets, 
+                Users.bracket_id == Brackets.id, 
+                isouter=True
             )
-            users = r.fetchall()
+            
             membership = defaultdict(dict)
-            for u in users:
-                if u.hidden is False and u.banned is False:
-                    membership[u.team_id][u.id] = {
-                        "id": u.id,
-                        "oauth_id": u.oauth_id,
-                        "name": u.name,
-                        "color": u.color,
-                        "score": 0,
-                        "bracket_id": u.bracket_id,
-                        "bracket_name": u.bracket_name,
-                    }
-
-            # Get user_standings as a dict so that we can more quickly get member scores
+            for u in users_query.all():
+                membership[u.team_id][u.id] = {
+                    "id": u.id,
+                    "oauth_id": u.oauth_id,
+                    "name": u.name,
+                    "color": u.color,
+                    "score": 0,
+                    "bracket_id": u.bracket_id,
+                    "bracket_name": u.bracket_name,
+                }
+                
             user_standings = get_user_standings()
+            
             for u in user_standings:
-                membership[u.team_id][u.user_id]["score"] = int(u.score)
-
-        
-        
-
-        for i, x in enumerate(standings):
+                if u.team_id in membership and u.user_id in membership[u.team_id]:
+                    membership[u.team_id][u.user_id]["score"] = int(u.score)
             
-            potentialScore = 0
-            team_ids = [x.account_id for team in standings]
-            fails = Fails.query.filter(Fails.account_id.in_(team_ids))
-
-            freeze = get_config("freeze")
-            if freeze:
-                fails = fails.filter(Fails.date < unix_time_to_utc(freeze))
-
-            for fail in fails:
-                challenge = Challenges.query.filter_by(id=fail.challenge_id).first_or_404()
-                if challenge.type == "manual" or challenge.type == "manualRecursive" or challenge.type == "flash":
-                    potentialScore += challenge.value
-                elif challenge.type == "sport":
-                    potentialScore += fail.value
-
-            entry = {
-                "pos": i + 1,
-                "account_id": x.account_id,
-                "account_url": generate_account_url(account_id=x.account_id),
-                "account_type": account_type,
-                "oauth_id": x.oauth_id,
-                "color": x.color,
-                "name": x.name,
-                "score": int(x.score),
-                "bracket_id": x.bracket_id,
-                "bracket_name": x.bracket_name,
-                "potential_score": potentialScore,
-            }
-
-            if mode == TEAMS_MODE:
-                entry["members"] = list(membership[x.account_id].values())
-
-            response.append(entry)
+            for i, x in enumerate(standings):
+                entry = {
+                    "pos": i + 1,
+                    "account_id": x.account_id,
+                    "account_url": generate_account_url(account_id=x.account_id),
+                    "account_type": account_type,
+                    "oauth_id": x.oauth_id,
+                    "color": x.color,
+                    "name": x.name,
+                    "score": int(x.score),
+                    "bracket_id": x.bracket_id,
+                    "bracket_name": x.bracket_name,
+                    "potential_score": potential_scores.get(x.account_id, 0),
+                    "members": list(membership.get(x.account_id, {}).values())
+                }
+                response.append(entry)
+        else:
+            for i, x in enumerate(standings):
+                entry = {
+                    "pos": i + 1,
+                    "account_id": x.account_id,
+                    "account_url": generate_account_url(account_id=x.account_id),
+                    "account_type": account_type,
+                    "oauth_id": x.oauth_id,
+                    "color": x.color,
+                    "name": x.name,
+                    "score": int(x.score),
+                    "bracket_id": x.bracket_id,
+                    "bracket_name": x.bracket_name,
+                    "potential_score": potential_scores.get(x.account_id, 0),
+                }
+                response.append(entry)
+                
         return {"success": True, "data": response}