Accueil / Articles

Au-delà du P95 : Mesurer la latence réellement ressentie par vos utilisateurs

Un P95 sain peut être placé à côté d’un produit lent. Comment le temps d’attente dans la file et la dispersion des données échappent aux tableaux de bord, et comment une observabilité par étape met fin aux accusations de latence.

Éditeur : REACTAPP.TOP17 min de lecture3974 mots

Sources: Your P95 Latency Is Lying to You.

Ce que le P95 vous indique et ne vous indique pas

Il est utile d’être précis avant de critiquer cette métrique. Le P95 correspond à la valeur ou inférieure à laquelle 95 % des requêtes mesurées sont terminées. C’est un chiffre véritablement utile, et il représente une amélioration considérable par rapport à la latence moyenne. La moyenne est justement ce qui fait disparaître les problèmes en production : si quatre-vingt-dix-neuf requêtes se terminent en 50 ms et qu’une seule prend cinq secondes, la moyenne est d’environ 100 ms, un chiffre que personne ne communiquerait à quiconque. Un percentile, au moins, oriente votre attention vers les extrémités de la distribution.

Le percentile en lui-même n’est donc pas le problème. Le problème réside dans le rôle que les équipes lui attribuent après l’avoir lu. L’affirmation « Le P95 est acceptable » sert souvent de certificat d’innocence qui met fin à la discussion. Cette approche oublie discrètement quelque chose de fondamental : personne qui utilise votre produit ne prend connaissance d’un percentile. Les utilisateurs subissent des délais d’attente. Ils appuient sur un bouton et se demandent si leur action a été enregistrée. Ils voient une page qui semble affichée mais qui ne répond pas. Ils observent un indicateur de chargement tandis que plusieurs services en arrière-plan affichent tous des valeurs tout à fait normales.

Une API peut présenter un P95 excellent, tandis que le produit qui s’appuie sur elle semble lent. Prendre en compte ces deux faits simultanément constitue le point de départ de tout ce qui suit.

Trois horloges fonctionnent lors de chaque requête

La plupart des discussions sur la latence partent du principe d’une seule horloge. En pratique, il y en a au moins trois, et elles mesurent des choses différentes.

  • L’horloge du serveur. Une demande arrive vers votre service, une réponse est envoyée, le chronomètre s’arrête. C’est ce que rapportent la plupart des tableaux de bord backend.
  • L’horloge des dépendances. Au sein de cette demande et autour d’elle, le temps est consacré à l’authentification, à l’attente d’une connexion à une base de données partagée, aux appels HTTP internes, aux manques dans le cache, aux tentatives de réessai, aux files d’attente, aux vérifications des flags fonctionnels, aux API de tiers, ainsi qu’à tous les composants qui sont « généralement rapides ».
  • L’horloge de l’utilisateur. L’utilisateur clique, puis attend, avant que l’écran ne devienne utilisable. C’est le seul intervalle qui importe pour l’utilisateur.

Les équipes ont tendance à optimiser le premier temps de réponse avant de décrire le produit comme rapide. Le diagramme ci-dessous les montre côte à côte : le service indique 180 ms, tandis que la chaîne de dépendances comprend une tentative de réessai prenant 600 ms, et la personne devant le clavier se demande encore pourquoi la page charge.

SERVER CLOCK

request in  ------------------------------> response out
              "API P95: 180ms"

DEPENDENCY CLOCK
request in  ---> auth ---> db ---> service A ---> retry ---> service B ---> response out
                 40ms    70ms      120ms        600ms       90ms

HUMAN CLOCK
click  ----------------------------------------------------------------> usable screen
       "Why is this still loading?"

Rien n’est incorrect dans le temps de réponse du serveur. Il est simplement incomplet. Évaluer la vitesse d’un produit en se basant dessus, c’est comme prendre la température de quelqu’un et déclarer que tous ses organes sont en bonne santé : parfois, cette mesure est précisément ce qui compte, mais parfois elle manque la véritable maladie.

Un point de terminaison est une porte, un parcours utilisateur est un bâtiment

Un modèle mental utile : un point de terminaison backend est une seule porte, tandis qu’un parcours utilisateur correspond à une promenade à travers tout un bâtiment. Les tableaux de bord mesurent principalement le nombre de portes. Une requête entre, une réponse sort, le graphique est mis à jour, et tout le monde se détend.

Cependant, les utilisateurs ne sont pas là pour admirer une porte. Ils veulent atteindre un objectif : ouvrir l’écran d’accueil, effectuer un paiement, passer une commande, télécharger un relevé, accomplir une tâche réelle sans avoir l’impression que le logiciel hésite à répondre. Cette tâche correspond rarement à une seule requête vers le système backend. L’ouverture d’un tableau de bord dans une application typique à page unique ressemble davantage au schéma en étoile ci-dessous, où l’interface demande d’abord des informations sur le profil, les permissions, les comptes, les offres, les notifications et les limites avant que quoi que ce soit d’utile ne apparaisse.

User Clicks "Open Dashboard"
        |
        v
+----------------------+
| Frontend Shell       |
+----------------------+
        |
        +------> GET /profile
        |
        +------> GET /permissions
        |
        +------> GET /accounts
        |
        +------> GET /offers
        |
        +------> GET /notifications
        |
        +------> GET /limits
        |
        v
Screen Finally Becomes Useful

Chacun de ces six points d’entrée peut sembler fonctionnel en isolation, tandis que l’ensemble du processus paraît défaillant. Un service peut respecter ses SLA tout en contribuant à un produit lent. Une équipe peut atteindre ses propres objectifs tout en nuisant à l’expérience utilisateur. Lorsque les appels sont effectués séquentiellement, leurs latences s’additionnent ; lorsqu’ils sont exécutés en parallèle, c’est le plus lent qui dicte le rythme, et les limites de connexion par origine du navigateur ou des dépendances entre appels peuvent sérialiser des opérations que l’on pensait concurrentes.

C’est pourquoi l’affirmation « notre API est rapide » n’est que le début d’une enquête, et non une réponse. Les questions qui suivent sont délicates mais nécessaires : rapide par rapport à quoi, rapide pour qui, et rapidement mesuré depuis où ? À l’intérieur des limites de votre service, ou dès le moment où l’utilisateur a cliqué ?

Les cinq pour cent restants ne sont pas une erreur d’arrondi

Le nom « P95 » donne l’impression que le problème est mineur. Cinq pour cent semble être un coût acceptable pour fonctionner à grande échelle, quelque chose que un comité de direction serein peut accepter.

Cependant, imaginez un volume réel. Un système qui traite un million de requêtes par jour avec une limite P95 enregistre cinquante mille requêtes au-dessus de cette limite chaque jour. Chacune d’elles représente un moment où quelqu’un pourrait cliquer à nouveau, actualiser la page ou abandonner le processus en blâmant le produit.

Même cette façon de présenter les choses est trop simpliste, car les requêtes lentes ne sont pas réparties uniformément parmi les utilisateurs :

  • Un utilisateur malchanceux peut se retrouver à affronter des délais lents à plusieurs reprises.
  • Un seul client entreprise peut être bloqué sur un shard surchargé.
  • Une région entière peut connaître des problèmes de performance tandis que la moyenne globale reste acceptable.
  • Un flux de travail à haute valeur peut être lent, tandis que des appels peu coûteux et fréquents maintiennent de bons résultats au niveau du percentile.

Le tableau de bord montre une distribution. L’utilisateur concerné vit une expérience personnelle. Du point de vue du système, une fraction des requêtes était lente ; du point de vue de l’utilisateur, le produit a gaspillé son temps spécifiquement.

C’est pourquoi les plaintes des utilisateurs méritent d’être considérées comme des données. Les gens ne communiquent pas en pourcentiles, mais par des récits : « Le système bloque à chaque fois que j’appuie sur soumettre. » « La page s’affiche, mais les chiffres arrivent tard. » « Je dois recharger deux fois. » « Ça fonctionne, mais c’est lent. » Aucun de ces témoignages n’est vague ; chacun constitue un rapport de performance rédigé en langage simple, et le problème commun est de le traduire en mauvaise métrique pour en conclure qu’il n’y a aucun problème.

Deux services, un P95, risques très différents

SERVICE A

Most Requests        120ms - 260ms
Slow Requests        300ms - 380ms
Disaster Requests    Rare

SERVICE B

Most Requests        40ms - 80ms
Slow Requests        300ms
Disaster Requests    8s - 12s

Les deux peuvent indiquer un P95 à peu près identique. Seul le Service B présente un problème caché, situé entièrement au-delà du 95e percentile, hors de portée des chiffres. C’est en examinant le P99, le P99,9 et la valeur maximale, ou encore en consultant un histogramme ou une carte thermique de la latence, que l’on peut déceler cette différence.

Règle pratique : un tableau de bord basé sur des percentiles doit ouvrir une discussion, jamais la clore. La question n’est pas seulement « quel est notre P95 ? », mais plutôt « quel type de problème se cache derrière ce chiffre ? »

La pire latence existe entre les équipes

Certains problèmes de latence sont presque faciles à résoudre, car leur cause est évidente. Une requête lente bénéficie d’un index. Un cache manquant est ajouté avec prudence. Un en-tête trop volumineux est réduit. Une boucle inefficace est réécrite. Tout le monde comprend ces solutions.

Ces problèmes difficiles apparaissent plutôt dans les interférences entre équipes. Le backend indique que l’API fonctionne correctement. Le frontend signale qu’il attend une réponse du backend. La plateforme affirme que le gateway est en ordre. L’équipe de la base de données confirme que celle-ci fonctionne bien. Le service produit rapporte que les utilisateurs restent insatisfaits. Chacun dit la vérité, ce qui rend la situation d’autant plus frustrante.

Dans de tels cas, le système n’est pas lent en un seul endroit évident. Il est lent aux points de jonction :

  • dans le transfert de données entre services ;
  • dans une tentative de réessai qui double la durée d’une appel ;
  • dans une deuxième requête qui n’aurait jamais dû être envoyée ;
  • dans une vérification de permissions qui s’exécute après que des tâches coûteuses ont déjà commencé ;
  • dans un échec de cache qui reste inaperçu car l’endpoint termine malgré tout en dessous du seuil d’alerte ;
  • dans un service tiers que tout le monde qualifie d’« dépendance externe », ce qui semble moins gênant que d’admettre qu’il fait partie de l’expérience utilisateur ;
  • dans une file d’attente, avant même que le parcours de votre code ne débute ;
  • dans la sérialisation, après que la logique métier ait été traitée ;
  • au niveau du frontend, parce que l’API a renvoyé des données conçues pour la base de données plutôt que pour l’écran, et que le client doit les réassembler.
  • P95 n’a trompé personne en étant faux. Il a trompé en étant isolé. Une métrique isolée permet à chaque équipe de prouver son innocence tandis que l’utilisateur continue d’attendre.

    Le temps passé dans une file d’attente reste de la latence

    Il existe un problème de mesure plus subtil : les compteurs temporels au niveau de l’application démarrent souvent trop tard. Au moment où votre gestionnaire ou contrôleur commence à s’exécuter, la requête a déjà pu passer du temps à attendre au niveau du balanceur de charge, en attendant une connexion, un travailleur ou un thread, ou encore derrière d’autres tâches, car le processus était techniquement actif mais en réalité saturé. Dans Node.js, cet effet se manifeste sous forme de retard du cycle d’événements : un cycle occupé signifie que les appels de retour, y compris votre gestionnaire de requête, démarrent plus tard que le moment où le socket a reçu les données.

    Puis votre compteur temporel démarre, votre code s’exécute rapidement, et vos métriques enregistrent une requête rapide. L’utilisateur ne se soucie pas de l’endroit où se situait la limite de votre chronomètre ; attendre avant que le compteur ne démarre compte également. De même, attendre lors des tentatives de réessai, attendre que le navigateur envoie la prochaine requête nécessaire, ou encore attendre qu’un bouton désactivé devienne cliquable compte aussi.

    C’est là le piège des limites de mesure. Les équipes mesurent ce que leur service peut observer, puis traitent implicitement tout ce qui se trouve en dehors de cette vue comme inexistant. La latence que l’on ne peut pas voir n’est pas imaginaire ; c’est une latence à laquelle personne ne s’attribue la responsabilité, et une latence non assumée a tendance à être la plus coûteuse, car personne n’est chargé de la réduire. Les temps de traitement des requêtes par le chargeur de balayage, les métriques d’attente du pool de connexions, le retard du cycle d’événements et les temps de traitement côté navigateur sont les moyens habituels pour rendre ces intervalles visibles à nouveau.

    Dénommer chaque étape de la requête

    Ce qui résout généralement ces débats, ce n’est pas un autre tableau de bord, un nouveau fournisseur ou un budget d’observabilité plus important. C’est rendre impossible de cacher les parties lentes en donnant à chaque étape de la requête un nom clair et précis.

    Le fragment ci-dessous correspond à un gestionnaire Spring Boot en Java, mais ce schéma s’applique directement à Express, Fastify ou NestJS. Une LatencyTrace est initiée pour la requête GET /home et associée à l’en-tête X-Request-Id fourni. Chaque étape importante – chargement de l’utilisateur, récupération des permissions, appel aux services relatifs aux comptes et aux offres, ainsi que mise en forme de la réponse – est encadrée par trace.time(...) accompagné d’une étiquette descriptive. Dans le bloc finally, l’instruction trace.logIfTotalCrosses(Duration.ofMillis(700)) affiche le détail uniquement lorsque la durée totale de la requête dépasse 700 ms, de sorte que les journaux restent silencieux pour un trafic normal et détaillés pour un trafic lent. L’implémentation exacte importe moins que l’habitude qu’elle favorise.

    @GetMapping("/home")
    public HomeResponse home(@RequestHeader("X-Request-Id") String requestId) {
        LatencyTrace trace = LatencyTrace.start("GET /home", requestId);
    try {
            User user = trace.time("db.user", () ->
                userRepository.findActiveUser()
            );
            Permissions permissions = trace.time("auth.permissions", () ->
                permissionClient.fetch(user.id())
            );
            List<Account> accounts = trace.time("accounts.http", () ->
                accountClient.fetchAccounts(user.id())
            );
            List<Offer> offers = trace.time("offers.http", () ->
                offerClient.fetchEligibleOffers(user.id())
            );
            return trace.time("response.mapping", () ->
                HomeResponse.from(user, permissions, accounts, offers)
            );
        } finally {
            trace.logIfTotalCrosses(Duration.ofMillis(700));
        }
    }
    

    Deux points méritent d’être notés. Premièrement, le bloc finally garantit que la détection d’erreur est enregistrée même si l’un des étapes génère une exception, ce qui correspond précisément au moment où on en a le plus besoin. Deuxièmement, les étapes s’exécutent une après l’autre, de sorte que le temps total est approximativement la somme de leurs temps respectifs ; si vous parallélisez des appels indépendants tels que ceux concernant les comptes et les offres, le suivi doit néanmoins mesurer chaque appel afin de déterminer lequel dicte le rythme.

    Comparez ce que vous obtenez avec un simple journal de latence à ce que produit cette méthode. La version classique se limite à une seule ligne indiquant un temps total :

    GET /home took 1180ms
    

    Ce résultat est précis mais presque inutile, car il ne donne aucune information sur l’emploi des 1 180 ms. La version détaillée par étape répond immédiatement à cette question :

    GET /home took 1180ms
    
    db.user              42ms
    auth.permissions     81ms
    accounts.http        156ms
    offers.http          823ms
    response.mapping     28ms
    

    Avec cette sortie présentée devant un groupe, le ton de la discussion change. Personne n’a besoin de deviner ou de défendre son propre service, et l’argument « ça marche chez moi » cesse d’être une contribution utile. Les offres commerciales représentent environ 70 pour cent des demandes, ce qui fait passer la conversation de l’opinion aux preuves concrètes. C’est là le véritable avantage d’une bonne instrumentation : pas plus de graphiques, mais moins de débats.

    Dans une base de code Node.js, vous pouvez obtenir le même effet en utilisant performance.now() autour de chaque appel en attente ainsi qu’un outil d’écriture des journaux structuré, ou de manière plus systématique avec les spans d’OpenTelemetry, qui conservent les mêmes noms d’étapes au-delà des limites des services, de sorte que l’analyse reste fiable même lorsque l’étape lente se trouve dans le service d’un autre utilisateur. Pour en savoir plus sur la combinaison de journaux, de métriques et d’empreintes, consultez la création d’API Node.js observables.

    Pourquoi des benchmarks propres peuvent nettoyer un système en désordre

    C’est ici que, normalement, un rapport de performance présenterait un tableau de benchmarks. Il y a une bonne raison de ne pas le faire dans ce cas. Les benchmarks sont utiles lorsqu’ils sont honnêtes, mais en inventer un pour ce problème ne serait qu’un autre chiffre trompeur présenté sous une apparence formelle.

    Le problème n’est pas que les ingénieurs ne peuvent pas effectuer des tests contrôlés. Il s’agit plutôt du fait que ces tests ont tendance à éliminer précisément le chaos qui nuit aux utilisateurs :

    • Un benchmark teste un seul point d’entrée ; une action réelle de l’utilisateur en déclenche de nombreux autres.
    • Un benchmark s’exécute avec des caches préchauffés ; les utilisateurs apparaissent après les déploiements, les mises à jour et l’exécution de chemins de code non préchargés.
    • Un benchmark mesure les réponses réussies ; les utilisateurs doivent faire face à des échecs partiels, des tentatives de réessai, des délais d’attente et des écrans désactivés.
    • Un benchmark suppose des dépendances stables ; les dépendances en production fonctionnent bien jusqu’au jour où elles cesseront de le faire.
    • Un benchmark isole un seul service ; ce avec quoi interagissent les utilisateurs est le résultat de la combinaison de nombreux services, ainsi que de navigateurs, de réseaux, de files d’attente, de contrats API et de choix pris par des équipes qui ne communiquent plus entre elles.

    C’est comme polir du laiton pendant que le sol s’effondre. Le travail local est attrayant car il est entièrement sous votre contrôle. La latence globale est plus complexe à gérer, car son amélioration implique d’autres équipes, des contrats anciens, des choix de produits et une architecture que personne n’a envie de remettre en question. Cependant, les utilisateurs ne récompensent pas l’élégance technique ; ils récompensent les actions accomplies. Une fonction rapide est agréable, un point d’entrée rapide est encore mieux, mais c’est le parcours global qui compte vraiment. Avant d’optimiser un seul composant, il est utile de s’assurer qu’il se trouve sur le chemin critique d’un parcours qui importe aux utilisateurs.

    Lorsque la dépendance la plus lente est une décision

    Tous les problèmes de latence ne sont pas techniques. Certains sont des décisions qui se sont intégrées à l’architecture :

    • Le frontend appelle six API alors qu’une seule réponse agrégée suffirait.
  • Chaque écran demande à nouveau au service d’autorisation l’autorisation, au lieu de réutiliser un résultat antérieur.
  • Les tentatives sont effectuées de manière synchrone au sein du chemin de requête destiné à l’utilisateur.
  • Un widget publicitaire bloque l’affichage de toute la page d’accueil.
  • Les événements d’analyse doivent être enregistrés avant que l’utilisateur ne puisse continuer.
  • L’API renvoie des objets de forme similaire à celle d’une base de données, laissant le front-end gérer leur interprétation.
  • Un service intermédiaire est qualifié de « critique » parce que personne n’a voulu admettre que ses fonctionnalités pourraient être chargées ultérieurement.
  • La partie la plus lente d’un système est souvent le choix d’un produit qui n’a jamais été évalué, un manque de responsabilité claire, ou une réunion ancienne dont les conséquences se traduisent par des latences permanentes. De nombreuses solutions existent pour ces problèmes, telles qu’un backend dédié au frontend permettant d’agréger les appels, un chargement différé des widgets non essentiels, le décalage des tentatives de récupération et des analyses hors du chemin critique, ainsi que des formats de réponse conçus en fonction de l’écran. Cependant, chaque solution exige que quelqu’un ait l’autorité de modifier une décision prise précédemment.

    C’est pourquoi le travail d’amélioration des performances devient politique une fois que les solutions simples ont été appliquées. Les latences restantes deviennent alors une question de responsabilité : qui a le droit de déclarer une dépendance obligatoire ? Qui est responsable de l’ensemble du processus ? Qui peut supprimer un appel ? Qui est tenu pour responsable lorsque tous les services fonctionnent correctement mais que l’expérience utilisateur reste médiocre ? Le P95 ne peut répondre à aucune de ces questions, et il n’était jamais destiné à le faire.

    Les tableaux de bord verts peuvent rendre les équipes moins curieuses

    Une observation moins agréable : un tableau de bord vert peut amener une équipe à cesser de poser des questions. Pas toujours, mais suffisamment souvent pour avoir de l’importance. Lorsqu’un graphique devient rouge, tout le monde enquête. Lorsque le graphique est vert et qu’un utilisateur se plaint, la conversation tend à chercher des excuses pour justifier cette plainte. Peut-être que leur réseau était mauvais. Peut-être que leur navigateur était lent. Peut-être s’agit-il d’un cas isolé, ou le service client a exagéré, ou l’interface a fait quelque chose d’étrange, ou le client a cliqué trop tôt, ou la plainte est plutôt émotionnelle que technique.

    C’est ainsi que les équipes perdent la confiance, non pas à cause d’un manque de données, mais en utilisant ces données comme prétexte pour ne pas écouter. L’utilisateur n’a pas votre tableau de bord ; il a votre produit. S’il trouve que celui-ci est lent, c’est une preuve. Ce n’est pas une preuve complète ou parfaite, mais c’en est une.

    Une culture d’ingénierie saine considère le graphique comme un témoin et l’utilisateur comme un autre, la production étant le lieu à examiner. Une culture qui considère les graphiques comme la vérité et les utilisateurs comme du bruit est celle qui lance des produits lents tout en croyant qu’ils sont rapides.

    Partez de ce que l’utilisateur essayait de faire

    Les discussions sur les performances sont généralement organisées autour des composants : quel service, quel point de terminaison, quelle requête est lente. Ce sont de bonnes questions, mais elles ne constituent rarement la meilleure première question. Une approche plus pertinente est : que cherchait à accomplir l’utilisateur ? Une fois cette question répondue, les bonnes mesures apparaissent naturellement :

    • Pour ouvrir un tableau de bord, mesurez le temps nécessaire jusqu’à ce que celui-ci soit réellement prêt à être utilisé.
    • Pour soumettre un formulaire, mesurez le temps entre la soumission et l’affichage de la confirmation.
    • Pour télécharger un rapport, mesurez le temps entre le clic et la disponibilité du fichier.
  • Pour un paiement, mesurez de l’état initial à l’état final réglé.
  • Cela semble évident, pourtant de nombreux systèmes ne sont pas instrumentés de cette manière. On les mesure le long des frontières des équipes, car celles-ci sont faciles à instrumenter et permettent d’obtenir des tableaux de bord bien organisés. Les parcours utilisateurs sont plus difficiles à mesurer et donnent des résultats moins flatteurs, or c’est justement de ces résultats moins flatteurs que proviennent les améliorations du produit. Du côté client, des API de navigateur telles que les interfaces Performance et User Timing permettent d’indiquer explicitement « l’utilisateur a cliqué » et « l’écran est utilisable », et en corrélant ces indications avec un ID de requête, on relie le temps perçu par l’utilisateur aux traces serveur. Si la lenteur provient du rendu plutôt que du réseau, l’article sur le diagnostic des problèmes de performance React au-delà du temps de réponse API aborde ce aspect du problème.

    Abordez les métriques avec une suspicion respectueuse

    Rien de tout cela ne justifie l’élimination du P95 de vos tableaux de bord. Il a sa place là-bas et il est important. Il ne faut simplement pas lui faire confiance seul. Un bon percentile devrait plutôt éveiller votre curiosité, en vous orientant vers les requêtes situées au-delà du seuil :

    • Qui fait précisément partie de ces cinq pour cent lents, et s’agit-il toujours des mêmes personnes ?
    • À quels parcours d’utilisateur appartiennent ces requêtes ?
    • Une dépendance particulière est-elle responsable de la majeure partie des problèmes ?
    • Une région spécifique présente-t-elle des défaillances alors que la vue globale semble normale ?
    • Un locataire particulier subit-il systématiquement les pires conséquences ?
    • Les tentatives de réessai transforment-elles silencieusement les échecs en longues attentes ?
    • Combien de temps les requêtes restent-elles en file d’attente avant même que le compteur temporel de l’application ne commence à fonctionner ?
  • Y a-t-il un état côté frontend qui empêche l’écran de se débloquer après que le backend a déjà répondu ?
  • Un service semble-il fonctionnel en théorie mais nuit-il au produit dans la pratique ?
  • La bonne attitude vis-à-vis d’une métrique n’est ni l’idolâtrie ni le rejet. C’est une suspicion respectueuse. Une métrique est un témoin, et les témoins peuvent omettre des éléments importants.

    Points clés

    Le scénario dangereux n’est pas celui d’une métrique clairement fausse ; il serait facile de s’en apercevoir. C’est plutôt celui d’une métrique qui affirme une petite vérité avec tant de certitude que tout le monde cesse de chercher la vérité plus large. La prochaine fois que quelqu’un dira que le P95 est acceptable, ne discutez pas du chiffre ; demandez plutôt ce qu’il a exclu. A-t-il pris en compte le temps d’attente dans la file, les tentatives de réessai, l’attente côté frontend, l’appel vers un tiers, le fait que l’utilisateur clique à nouveau parce qu’il ne se passe rien, ainsi que le moment précis où l’écran devient réellement utilisable pour la tâche que le client voulait effectuer ?

    • P95 dépasse les moyennes mais masque la forme de la distribution, la gravité des extrêmes et les utilisateurs concernés ; l’accompagner de pourcentiles plus élevés, d’histogrammes ainsi que de analyses par locataire ou par région.
    • Distinguer les horloges du serveur, des dépendances et celles des utilisateurs, et s’assurer qu’une personne est responsable de chacune d’elles.
    • Le parcours d’un utilisateur se divise généralement en de nombreuses étapes ; mesurer l’ensemble du parcours, et non seulement ses points d’arrivée.
    • Les chronométrages des applications négligent souvent les temps d’attente en file d’attente, les délais de connexion et les retards liés au boucle d’événements ; mesurer ces éléments explicitement.
    • Chronométrer chaque étape d’une requête et enregistrer les détails lorsqu’un seuil est atteint permet de remplacer les accusations par des preuves.
    • Une partie de la latence est le résultat de décisions liées au produit et à sa gestion, et pour y remédier, il faut quelqu’un ayant l’autorité de les modifier.
    • Considérer les plaintes des utilisateurs comme des rapports de performance et les tableaux de bord comme un seul témoin parmi plusieurs.

    Lectures complémentaires