Performance
La performance est une fonctionnalité. Concevez pour le P99, pas pour la moyenne. Mesurez avant d'optimiser — l'intuition a presque toujours tort sur l'origine des temps d'exécution.
Règles
- Profiler avant d'optimiser. Deviner le chemin critique fait perdre des jours. Utilisez d'abord des flame graphs, des traces APM ou
EXPLAIN ANALYZE. - Éliminer les requêtes N+1. La plus grande source de latence dans le code de service. Privilégiez les jointures, les récupérations par lots ou
IN (...)plutôt que les recherches ligne par ligne. - Paginer chaque endpoint de liste. Des ensembles de résultats illimités finiront par faire planter un pod par OOM ou saturer la base de données. Par défaut, utilisez une pagination basée sur curseur pour les grandes tables.
- Indexer sur les prédicats de requête, pas sur chaque colonne. Chaque index supplémentaire ralentit les écritures et gonfle le stockage. Ajoutez un index uniquement lorsqu'une requête connue en a besoin.
- Projeter uniquement les colonnes nécessaires.
SELECT *dans un DTO large gaspille le réseau, la mémoire et le GC. Renvoyez des projections réduites pour les APIs de liste. - Mettre en cache les données souvent lues et idempotentes. Mais décidez de la stratégie d'invalidation avant d'ajouter le cache — un cache sans plan d'éviction est une usine à bugs.
- Définir explicitement les tailles des pools de connexions et de threads. Les valeurs par défaut sont rarement adaptées à votre charge de travail. Dimensionnez-les en fonction de la capacité en aval, pas en amont.
- Regrouper les appels sortants. Une requête avec 100 éléments bat 100 requêtes avec un élément sur tous les axes — latence, CPU, connexions à la base de données.
- Éviter les chaînes synchrones d'appels distants. La latence se cumule. Parallélisez les appels ou déplacez le travail en asynchrone.
- Garder les charges utiles petites. Compressez les réponses, supprimez les champs inutilisés, utilisez des protocoles binaires lorsque c'est important (gRPC, Protobuf).
Drapeaux rouges
- Boucles qui interrogent la base de données.
- APIs qui renvoient « tous les enregistrements ».
- Caches sans TTL ni invalidation.
- Pools de threads / pools de connexions réglés sur la valeur par défaut du framework en production.
- Tableaux de bord de latence qui n'affichent que des moyennes (pas de P95/P99).