Vous avez mis en place un test de charge. Tout roule en PREPROD. Et puis… en PROD, c’est le chaos.
Pourquoi ?
Parce que votre test envoie des requêtes comme un robot, pas comme de vrais utilisateurs.
Résultat ?
Vous pensez que votre API tient la charge… jusqu’à ce qu’elle se prenne un comportement imprévu (un pic, une charge longue) et explose en vol.
Voyons comment éviter ça en simulant un trafic réaliste !
Arrêtez les tests “ligne droite”
Le test classique :
- Vous envoyez exactement 1000 requêtes par seconde
- Chaque requête arrive pile au bon timing
- Tout est bien prévisible
Sauf que la vie réelle, ce n’est pas ça.
Vos utilisateurs n’ont pas un comportement déterministe et linéaire.
Ils arrivent en vagues, cliquent frénétiquement, actualisent la page… Bref, c’est “organique”.
💡 Ajoutez de l’aléatoire dans votre trafic. Simulez des motifs irréguliers comme des pauses, des actions répétées, des utilisateurs pressés et d’autres plus lents.
Pensez aux pics de charge
Vous avez testé un trafic stable, ça passe.
Mais avez-vous testé ?
-
Le lundi matin à 9h quand tout le monde se connecte en même temps ?
-
Le Black Friday quand vos serveurs se prennent une avalanche de commandes ?
-
Un pic viral (comme une campagne marketing qui débute, et BOOM 💥 le SUCCÈS)
-
Discutez avec vos équipes de la saisonnalité de votre charge. Personnellement je m’appuie sur les données de monitoring (quand je les ai) ou directement dans le parsing des logs si possible. Dans le commerce de pneumatiques par exemple, il y a des piques lors du changement des pneus été et hiver, et particulièrement entre midi et 14h.
-
Testez avec des montées en charge progressives (ramp-up), des pics soudains (spikes), des périodes de tensions soutenues (attention à la facture). Chaque motif permet de faire des investigations différentes (nous reviendrons dessus dans un prochain article).
-
Le comportement de l’application lors du retour à la normale est aussi important qu’au cours de la charge ! L’objectif est d’étudier la capacité de notre système à revenir à la normale après une période de stress.
💡 Bien considérer la distribution non uniforme de la charge et observer le retour à la normal.
Simulez des scénarios utilisateurs, pas juste des requêtes
Un test “bête” envoie des requêtes isolées.
Mais un utilisateur :
- 🔑 Se connecte
- 🔍 Cherche un produit
- 🛒 Ajoute au panier
- 💳 Valide sa commande
Et ça, c’est un scénario possible.
Il existe aussi différents comportements comme la comparaison de produits, l’ouverture dans plusieurs onglets, la recherche d’un élément spécifique (qui dure, qui dure parce que la barre de recherche ne comprend pas du tout ce que j’ai bien pu écrire…)
- Écrivez des scénarios complets plutôt qu’un simple bombardement de requêtes. Des outils comme k6, Gatling ou Artillery permettent de simuler des vrais parcours utilisateurs. Au-delà de l’aspect “envoi de beaucoup de requêtes”, vous pouvez chorégraphier les appels pour ressembler à un véritable comportement utilisateur.
- Inspirez-vous de vrais utilisateurs pour imiter leurs comportements.
- Les outils comme le Real Users Monitoring, l’observation des Heat Maps ou juste s’asseoir derrière vos utilisateurs (de vrais en chair et en os) permettent de comprendre leur comportement et de les imiter.
- Un coup de fil / visio avec vos partenaires qui intègrent votre API peut vous faire gagner beaucoup de temps ! Vous seriez étonnés de comprendre les scénarios d’usage que vous n’aviez pas envisagé.
💡 Ne pas hésiter à s’appuyer sur les outils de Logs type RUM (surveillance des utilisateurs réels) ou les chorégraphies d’appels de vos utilisateurs (les logs devraient vous aider pour les identifier) pour comprendre les usages et identifier les volumétries.
Les limites et blocages
Durant vos tests, vous envoyez 10 000 requêtes, tout tient… et pourtant, en prod, ça rame…
Pourquoi ?
🚫 Parce que (plusieurs cas possibles en même temps) :
-
Il y a un rate limit d’un service tiers que vous n’avez pas pris en compte
-
Votre cache masque les vrais problèmes : Et oui, utiliser exactement les mêmes données à chaque requête n’implique pas toute la chaîne de calcul
-
Votre base de données ne suit pas : elle est peut-être déjà chargée avec plus de données que votre environnement de tests
-
Un Batch se déclenche régulièrement sur le serveur API, et ça vous ne l’aviez pas considéré dans les tests
-
Simulez des utilisateurs avec des données différentes
- Plusieurs machines de tests pour varier les IPs
- Des identifiants différents
- Utiliser des jeux de données différents (personnellement, j’utilise des outils comme Faker.JS pour générer de fausses vraies données).
- Testez avec et sans cache
-
Désactivez les STUB (bouchons) sur les APIs tierces et tentez une simulation en “presque prod” :
- Attention cependant, ça peut vite coûter cher si vous payez à la requête !
- Par contre, vous pourriez-être surpris du nombre de SLAs tierces manquantes ou non respectées
-
Ne testez pas avec une DB à vide !
- Des index avec peu de données n’ont pas le même comportement qu’une table bien replète
- Et c’est la même chose pour tous les composants (files de message, disque de stockage…)
💡 Comme d’habitude en testing : des environnements au plus proches de la vrai PROD et attention au cache !
Mesurez ce qui compte vraiment
Ok, votre API tient à 1000 req/s. Mais ça veut dire quoi pour de vrai ?
- Temps de réponse moyen : OK, mais quid du p95 (au minimum des pires latences) et du p99 ? On oublie la moyenne cf. Pourquoi la moyenne ne veut rien dire
- Erreurs HTTP : 200, c’est bien, mais quid des 429 (too many requests) de vos services tiers, des 500 sauvages qui surviennent de temps à autre ?
- Impact sur l’infra : CPU, RAM, BDD, FileSystem… tout tient ou c’est en PLS ? Je vous invite fortement à corréler vos données de tests avec vos métriques d’infrastructure.
À bien faire attention
- Attention à vos agrégations de métriques : la moyenne n’est pas du tout pertinente ! Dès fois mieux vaut regarder le min / max (selon ce qui est observé).
- Regardez les métriques clés (latence, taux d’erreurs, durée des requêtes, utilisation et saturation CPU/mémoire, saturation IO) et pas juste “ça a l’air de marcher” comme ça du bout du doigt
- Regardez les métriques de retour à la normale après une charge : est-ce que mon système est capable de reprendre un comportement normal lorsque j’ai eu une grosse volumétrie ?
💡Trois concepts pertinents sur les métriques à étudier : Four Golden Signal, RED, USE
TL;DR – Tester la montée en charge d’une API de façon réaliste
Les tests de charge “lisses” (trafic linéaire, requêtes identiques, données stables) donnent une fausse confiance.
En production, le trafic est chaotique, irrégulier, imprévisible.
✅ Pour simuler un trafic réaliste :
- Ajoutez du bruit : pauses, pics, comportements irréguliers
- Reproduisez les usages réels : scénarios complets (login, recherche, commande…)
- Appuyez-vous sur des volumétries réelles et attendues : analyse rétrospective des chiffres passés, facteur d’incertidude
- Testez les situations critiques : pic à 9h, Black Friday, campagne virale
- Variez les données : cache, utilisateurs, IPs, base bien remplie
- Vérifiez les métriques : erreurs HTTP, saturation CPU/DB, retour à la normale
- Corrélez avec les données réelles : logs, APM, usages et besoins utilisateurs collectés en réel
Un bon test de charge, c’est un test qui ressemble à la vraie vie. Oublions les tests “lignes droites” et pensons comme nos utilisateurs : imprévisibles, impatients et toujours là où on ne les attend pas.
Et un test n’est jamais figé dans le marbre. J’ajuste régulièrement mes scénarios avec les données réelles observées (merci les APMs).
Attention à ne pas vivre en théorie, car en théorie tout se passe bien…