Ilustración editorial para Concurrencia en APIs de IA: cómo controlar colas, cuotas y latencia
Imagen generada con gpt-image-2.5-sunburst para InferamaSource ↗
01

Pourquoi une intégration fonctionnelle peut saturer

Une intégration avec un modèle peut fonctionner correctement en période de trafic habituel et pourtant se dégrader lorsque de nombreuses requêtes arrivent simultanément. Si l’application envoie chaque requête immédiatement, sans contrôler le nombre d’opérations en cours ni celui des requêtes en attente, un pic peut accumuler du travail plus vite que le service ne le traite. Les conséquences visibles peuvent être une latence accrue, des requêtes qui ne sont plus utiles lorsqu’elles aboutissent, des réponses signalant une limite atteinte ou une facture qui s’écarte des prévisions.

La concurrence compte parce qu’une requête n’occupe pas les ressources pendant une durée fixe. La génération peut durer plus ou moins longtemps selon la tâche, la taille de l’entrée et la quantité de sortie demandée. Le seul décompte des requêtes par seconde ne suffit donc pas à décrire la pression exercée par une intégration. Deux charges au même débit de requêtes peuvent avoir des temps de traitement et des consommations différents.

L’objectif du contrôle de charge n’est pas d’utiliser toute la capacité possible à n’importe quel prix. Il s’agit de protéger les objectifs de l’application : terminer les tâches utiles, respecter les priorités, limiter l’attente et éviter qu’une hausse temporaire de la demande ne transforme le système en file d’attente sans issue. Les choix de conception présentés ici sont des recommandations générales ; ils ne décrivent ni une limite universelle ni un remplacement des conditions documentées pour chaque API, modèle ou canal d’accès.

Il faut distinguer deux problèmes souvent confondus. L’admission détermine, avant l’envoi d’une requête, si l’application accepte la tâche, la conserve brièvement en attente ou la refuse. La politique de nouvelle tentative intervient après un échec ou un résultat incertain. Ce guide porte principalement sur la première décision et sur la gestion contrôlée de l’attente : réessayer automatiquement ne corrige pas une admission qui laisse entrer plus de travail que le système ne peut en traiter.

02

Que mesurer avant de fixer des limites

Commencez par observer une charge représentative plutôt que de choisir au hasard un niveau de concurrence. Enregistrez le débit d’arrivée et le nombre de requêtes simultanées, mais aussi, lorsqu’ils sont disponibles, la taille de l’entrée et celle de la sortie produite. Pour une décision d’admission prise avant l’envoi, la sortie n’est pas encore connue ; vous pouvez la mesurer ensuite afin d’améliorer vos estimations, mais pas la traiter comme une donnée future exacte.

Mesurez la latence de bout en bout et, si vous pouvez instrumenter les différentes phases, distinguez le temps passé dans la file d’attente du temps écoulé entre l’envoi et la réponse. Pour les réponses générées progressivement, mesurez également le délai avant le premier fragment et la durée totale. Un bon délai avant le premier fragment ne signifie pas que la tâche entière s’est terminée rapidement ; inversement, une durée totale élevée ne prouve pas à elle seule que la file d’attente en soit la cause.

Utilisez des percentiles, comme p95 et p99, en complément des moyennes. Une moyenne résume une tendance, mais peut masquer une minorité de requêtes qui attendent beaucoup plus longtemps. Associez ces mesures au nombre de requêtes terminées, annulées, arrivées à expiration et refusées ; aux erreurs renvoyées par le fournisseur ; à l’utilisation des jetons lorsqu’elle est disponible ; et au coût par tâche terminée si votre système peut le calculer de façon fiable.

La loi de Little fournit un moyen de vérifier la cohérence entre le nombre moyen d’éléments dans un système, le taux moyen d’arrivée et le temps moyen qu’une unité y passe : L = λW. Utilisée avec prudence, elle aide à comprendre pourquoi, si le taux d’arrivée reste constant et que le temps de séjour augmente, le nombre moyen de tâches présentes peut lui aussi augmenter. Ce n’est pas une formule permettant à elle seule de prévoir les percentiles, les pics, les coûts ou la limite d’une API ; elle décrit une relation entre des moyennes, dans les conditions pertinentes.

Segmentez les mesures par modèle, endpoint, fournisseur, région ou projet lorsque ces différences comptent dans votre configuration. Ne regroupez pas dans une seule série les tâches courtes et longues si cela masque les problèmes d’une catégorie. Séparez également le trafic de production des essais et consignez les changements de configuration afin de pouvoir relier une variation de latence à une cause plausible.

Mesures et décisions qu’elles éclairent

Utilisez ces indicateurs comme des signaux complémentaires. Aucun ne suffit, à lui seul, à démontrer quelle est la limite sûre.

MesureCe qu’elle aide à observerPrécaution
Requêtes par intervalleRythme d’arrivée et pics de traficNe reflète ni la durée ni la taille de chaque tâche
Concurrence en coursTravail qui mobilise de la capacité à un instant donnéIl faut définir quels états sont considérés comme « en cours »
Jetons d’entrée et de sortieTaille observée des requêtes et des réponsesLa sortie future n’est pas connue au moment de l’admission
Temps en file d’attente et latence de bout en boutAttente locale et expérience complèteN’attribuez pas au fournisseur le temps mesuré avant l’envoi
p95, p99 et expirationsFiles d’attente longues et tâches qui perdent leur utilitéInterprétez les percentiles en tenant compte du nombre d’observations
Refus, erreurs et coût par tâcheConséquences opérationnelles et économiquesDéfinissez de manière cohérente ce qui compte comme une tâche terminée
03

Ne confondez pas débit, concurrence, jetons et capacité propre à l’application

Une limite de débit contrôle le nombre de requêtes ou d’unités comptabilisées qui peuvent être présentées pendant une période donnée. Une limite de concurrence restreint le nombre d’opérations que l’application maintient actives simultanément. Une limite fondée sur les jetons porte sur le volume de texte traité ou demandé selon les règles du service. Une limite propre à l’application constitue un contrôle supplémentaire : par exemple, le nombre de tâches admises dans la file locale ou la durée maximale d’attente.

Ces restrictions répondent à des problèmes différents. Un système peut respecter un débit moyen tout en accumulant un pic bref ; il peut avoir peu de requêtes simultanées, mais de longue durée ; ou recevoir peu de requêtes impliquant de très longues entrées. L’application doit connaître les restrictions publiées pour le canal qu’elle utilise et définir, en complément, des contrôles locaux qui protègent l’expérience utilisateur.

Il ne faut pas transposer les quotas d’un produit à l’autre par analogie. La documentation de Vertex AI décrit des quotas et des limites dont le périmètre peut dépendre du service, du projet et de la région. La référence de l’API OpenAI comprend des en-têtes de réponse liés aux limites de requêtes et de jetons. Ces exemples montrent pourquoi il faut consulter la documentation applicable au compte et à la configuration concernés ; ils n’établissent ni des chiffres communs ni une règle unique pour tous les endpoints.

Une réponse 429 ne désigne pas toujours une cause ou une solution unique. La documentation de Vertex AI distingue des situations liées à la capacité partagée et à la capacité provisionnée. Enregistrez donc le type de réponse et consultez la documentation correspondante avant de l’interpréter. En particulier, ne transformez pas toute réponse 429 en instruction de réessayer immédiatement : cette conduite relève de la gestion après échec et peut accentuer la pression si l’admission reste ouverte.

04

Concevez l’admission : accepter, mettre en attente ou refuser

Une politique d’admission doit prévoir explicitement trois résultats. Accepter signifie que la requête peut démarrer au regard des limites locales et des quotas connus. Mettre en attente signifie qu’elle est conservée temporairement dans une file dont la capacité et le délai sont définis. Refuser signifie que le système ne promet pas de la traiter à ce moment-là et renvoie une réponse permettant à l’application cliente de décider de la suite.

Une file sans limite n’est pas une solution sûre : elle peut transformer une saturation visible en attentes toujours plus longues et en travail stocké qui arrive trop tard pour être utile. Définissez un nombre maximal d’éléments, un budget d’attente et une condition d’expiration. Si la file atteint sa limite, refusez le nouveau travail ou appliquez une règle de remplacement justifiée par le produit ; ne masquez pas le problème en ajoutant du stockage sans limite opérationnelle.

La réponse de refus doit être cohérente avec l’interface de votre service. Expliquez que la tâche n’a pas été admise ou indiquez que la capacité est temporairement occupée, sans prétendre que le modèle l’a traitée. Si l’application peut réessayer plus tard, fournissez un signal clair et documenté permettant au client de prendre cette décision. Évitez de promettre un délai d’attente exact si vos mesures ne permettent pas de le garantir.

L’admission peut combiner plusieurs conditions : capacité de concurrence disponible, file en dessous de son maximum, quota par utilisateur et budget d’attente restant. Vérifiez ces conditions avant de réserver les ressources et libérez la réservation lorsque la tâche est terminée, annulée ou expirée. Si une requête est annulée côté client mais continue d’occuper une place locale, la mesure de concurrence ne représente plus le travail réellement actif.

Définissez explicitement l’ordre des priorités. Vous pouvez, par exemple, réserver une partie de la capacité aux tâches interactives et limiter les tâches par lots, à condition que ces catégories existent dans votre produit et que la règle n’empêche pas indéfiniment les catégories moins prioritaires d’être servies. Le but n’est pas d’inventer une priorité universelle, mais de refléter la valeur et le délai propres à chaque classe de travail.

Décision d’admission pour chaque requête

Flux local recommandé ; les seuils doivent être calibrés pour chaque service et chaque charge.

  1. 01Vérifiez que la tâche est admissible et déterminez sa classe, son utilisateur et son délai d’utilité.
  2. 02Contrôlez la concurrence disponible, le quota local et la capacité restante de la file.
  3. 03Si elle peut démarrer, réservez la capacité et envoyez-la ; mesurez séparément l’attente et le traitement.
  4. 04Si elle ne peut pas démarrer mais qu’il reste de la place et du budget d’attente, mettez-la en file avec une date d’expiration.
  5. 05S’il n’y a plus de place ou si la tâche ne peut plus être terminée à temps, refusez-la explicitement.
  6. 06À la fin, en cas d’annulation ou d’expiration, libérez la réservation et enregistrez le résultat pour ajuster la politique.
05

Pondérez le travail sans prétendre en connaître le coût exact

Compter les requêtes fournit une règle simple, mais traite de la même façon des tâches susceptibles d’être très différentes. Une autre approche consiste à attribuer à chaque requête un poids estimé à partir des signaux disponibles avant l’envoi : estimation du nombre de jetons d’entrée, longueur de sortie prévue, classe de tâche ou durée historique mesurée pour ce type d’opération. Ce poids peut servir à établir des priorités, à limiter des budgets ou à déterminer si la tâche peut entrer dans la file.

Une estimation n’est pas une garantie. La réponse générée peut être plus courte ou plus longue que prévu ; la durée peut varier même lorsque les entrées ont des tailles similaires. Calibrez donc l’estimation en la comparant aux résultats observés, conservez des marges et examinez les erreurs de prédiction. Si la sortie réelle est enregistrée, utilisez-la pour améliorer les politiques futures, sans présenter comme connu au moment de l’admission un élément qui ne l’était pas.

Une possibilité pratique consiste à définir des limites distinctes par classe ou à réserver une quantité de travail prévue pour chaque période. Vous pouvez aussi utiliser un système interne de crédits dans lequel chaque requête consomme un poids estimé et où la capacité est rétablie selon la politique locale. Dans les deux cas, documentez le calcul du poids, sa correction et le comportement prévu lorsqu’une requête dépasse l’estimation. Ne présentez pas une comptabilité locale des jetons comme si elle était identique au quota du fournisseur.

Comparez les politiques sur le même ensemble de requêtes et avec la même charge. Si une politique pondérée réduit les pics d’attente pour les petites tâches, vérifiez aussi ce qu’il advient des grandes : elles pourraient être repoussées sans cesse. Les critères de réussite doivent tenir compte du débit global, de la latence par classe et de la proportion de tâches terminées dans les délais, pas seulement d’un indicateur favorable aux requêtes les plus courtes.

06

Priorités, équité et protection contre les blocages

Une file unique peut suffire à un produit dont les tâches sont équivalentes, mais elle présente des risques lorsqu’elle regroupe des travaux urgents et des tâches longues. Une tâche de longue durée placée en tête peut faire attendre les autres, même lorsqu’elles sont brèves. De plus, si un client génère une part disproportionnée de la demande, il peut consommer la capacité partagée et pénaliser les autres.

Vous pouvez séparer les files par classe de service, définir des quotas par utilisateur ou limiter le nombre de tâches simultanées par client. Vous pouvez également réserver une capacité au trafic interactif et traiter les tâches par lots avec la marge restante. Ce sont des options de conception, pas une garantie d’équité : les priorités, la taille des réserves et la règle de sélection doivent être testées avec les habitudes d’utilisation réelles.

Définissez ce que signifie l’équité dans votre contexte. Il peut s’agir de donner à chaque client une possibilité de progression, de respecter un délai pour les tâches interactives ou d’empêcher un utilisateur de consommer tout le budget local. Un quota très strict par utilisateur peut protéger contre l’accaparement, mais aussi laisser de la capacité inutilisée lorsque les autres utilisateurs sont inactifs. Un quota trop souple peut ne pas protéger les petits clients pendant un pic.

Pour éviter qu’une priorité faible soit reléguée indéfiniment, envisagez des limites maximales d’attente, une augmentation progressive de priorité avec le temps ou des possibilités minimales de traitement. Mesurez le temps en file par classe et par client, et pas seulement la moyenne globale. Si les catégories ont des délais différents, consignez le nombre de tâches terminées à temps et celui des tâches expirées. Une politique qui améliore la latence d’une classe au prix de rendre une autre inutile doit être présentée comme un choix explicite du produit.

Choisir une règle de file d’attente

Ces options illustrent des compromis de conception ; le choix dépend des objectifs du service.

RèglePeut contribuer àRisque à mesurer
File partagée uniqueGarder une mise en œuvre simple lorsque les tâches sont comparablesUne tâche longue ou un volume important provenant d’un client peut retarder les autres
Files séparées par prioritéProtéger les tâches soumises à des délais différentsLa classe la moins prioritaire peut être reléguée
Quota par clientLimiter l’accaparement de la capacité localeGaspiller de la capacité si les autres ne peuvent pas utiliser le quota
Budget pondéréDistinguer les tâches selon un coût prévuMal classer des requêtes ou pénaliser excessivement les tâches volumineuses
07

Budgets d’attente, annulation et expiration

Chaque tâche devrait avoir une échéance utile définie par le produit, même si celle-ci n’est pas directement communiquée à l’utilisateur. Si une requête reste dans la file au-delà du moment où elle peut encore apporter de la valeur, la conserver ne fait qu’accumuler du travail en retard. Attribuez un budget maximal d’attente et vérifiez-le à nouveau avant d’envoyer la tâche au fournisseur.

L’expiration dans la file et l’annulation après l’envoi sont deux choses différentes. Avant l’envoi, retirer une tâche peut éviter de démarrer un travail qui n’est plus nécessaire. Après l’envoi, les effets d’une annulation dépendent des capacités de l’intégration et du comportement documenté de l’endpoint. Ne supposez pas que fermer une connexion arrête le traitement distant ou annule la consommation. Instrumentez ce que le système peut observer et décrivez les limites.

Enregistrez le nombre de requêtes qui expirent avant de démarrer et celui des requêtes annulées en cours de traitement. Si beaucoup de tâches expirent dans la file, examinez sa taille, le taux d’admission et le budget d’attente. Si elles sont annulées après leur envoi, vérifiez si une règle d’expiration plus précoce ou une interface permettant à l’utilisateur de retirer le travail réduirait les tâches inutiles. Ne concluez pas à une économie de coûts sans mesure à l’appui.

L’expiration contribue aussi à la gestion des priorités : une tâche urgente dont l’échéance est dépassée ne devrait pas continuer à occuper la première place simplement parce qu’elle est arrivée avant les autres. Toutefois, supprimer automatiquement du travail peut avoir des conséquences fonctionnelles. Définissez si l’expiration est signalée, si la tâche est conservée pour une exécution ultérieure ou si elle est supprimée ; le comportement doit être prévisible pour les personnes qui intègrent le service.

08

Tests de charge reproductibles et exploitation

Testez la politique avant de la déployer à grande échelle. Constituez un ensemble représentatif de tâches qui comprend différentes longueurs d’entrée et de sortie ainsi que les classes de priorité réellement utilisées par le produit. Exécutez une charge de base, puis augmentez la concurrence par paliers et ajoutez des pics contrôlés. Pour comparer des variantes, conservez le même ensemble de requêtes afin que les écarts ne soient pas dus à des tâches différentes.

Définissez à l’avance les critères d’arrêt et de retour arrière. Vous pouvez, par exemple, interrompre l’augmentation si p99 dépasse l’objectif convenu, si les expirations ou les erreurs augmentent, ou si le temps en file dépasse le budget fixé par le produit. Les valeurs concrètes doivent découler de vos objectifs, de vos mesures et des conditions de l’API, pas d’un chiffre universel. Consignez la configuration, la date, la version du client et les paramètres de test pour pouvoir répéter l’expérience.

Décomposez la latence : temps d’attente local, délai avant la première réponse lorsque cela est pertinent et durée complète. Comparez aussi le nombre de requêtes terminées, les réponses signalant une limite atteinte, les annulations, les percentiles par classe et le coût par tâche terminée. Si vous ne regardez que le débit total, vous pourriez ne pas voir qu’une classe échoue ; si vous ne regardez qu’une réponse d’erreur, vous pourriez manquer le fait que le problème provenait d’une file locale qui s’est mise à grossir avant l’appel au fournisseur.

En exploitation, vérifiez les quotas publiés pour le canal utilisé et surveillez les en-têtes ou champs de réponse documentés par le service. Ces signaux aident à repérer les limites et à alimenter le système d’observabilité, mais leur disponibilité et leur signification dépendent de l’API. Ne présumez pas qu’un en-tête est présent dans toutes les réponses ni qu’il restera inchangé. Notez la date de vérification de la documentation et vérifiez les évolutions avant de mettre à jour les contrôles.

Un déploiement prudent commence par des limites locales conservatrices, une bonne observabilité et un moyen de revenir à la configuration précédente. Augmentez ensuite l’admission progressivement si les résultats le justifient. Si les indicateurs se dégradent, réduisez les admissions, raccourcissez la file ou ajustez les classes de travail. Ne répondez pas automatiquement à une latence croissante en agrandissant la file : vous risqueriez de masquer la saturation et d’allonger les attentes.

Séquence de test et d’ajustement

Une comparaison utile doit pouvoir être répétée et reposer sur des critères de sortie définis.

  1. 01Définissez les objectifs de latence, le temps d’attente maximal, le taux d’achèvement et les conditions de retour arrière.
  2. 02Préparez des tâches de longueurs différentes, des classes de priorité et une charge de base documentée.
  3. 03Augmentez progressivement la concurrence et ajoutez un pic contrôlé sans modifier l’ensemble des tâches.
  4. 04Distinguez le temps en file, la première réponse et la durée complète ; consignez les percentiles et les résultats par classe.
  5. 05Comparez les refus, les expirations, les erreurs et le coût par tâche terminée à la configuration précédente.
  6. 06Conservez ou annulez le changement selon les objectifs ; répétez le test après toute évolution pertinente du modèle, de l’endpoint ou du quota.
09

Limites de cette approche et critères pratiques

Il n’existe pas de niveau de concurrence que l’on puisse transposer sans risque à toutes les intégrations. Les quotas et les conditions peuvent varier selon le service, le modèle, le projet, la région et le canal. Les quotas peuvent aussi évoluer, et une réponse observée pendant un test ne prouve pas que la même capacité sera disponible dans une autre configuration ou à un autre moment. Consultez les sources officielles applicables et vérifiez les limites avant d’en faire des règles permanentes.

Il n’existe pas non plus de formule unique permettant de convertir des jetons ou des requêtes par seconde en une latence garantie. La relation entre arrivée, temps de séjour et population moyenne aide à raisonner sur la croissance d’une file, mais ne remplace pas un test représentatif et ne permet pas de prévoir chaque réponse. Les tailles de sortie et durées observées apportent des informations ; les estimations préalables servent à admettre le travail avec prudence, pas à garantir un résultat exact.

Avant d’approuver une politique, vérifiez que vous savez combien de requêtes sont en cours et en attente ; que la file a une capacité maximale et une expiration ; que l’admission tient compte des tailles de tâche pertinentes ; et qu’une réponse claire est prévue lorsqu’une tâche n’est pas acceptée. Assurez-vous également que les priorités ne privent aucune classe de service, que les annulations sont mesurées dans le bon état et que les indicateurs distinguent l’attente locale du traitement distant.

Enfin, maintenez la distinction entre contrôle de charge et reprise après erreur. L’admission détermine le volume de demande qui entre et la quantité de travail mise en attente. Les nouvelles tentatives définissent la réaction à un échec ou à un résultat incertain. Un système robuste a besoin de politiques compatibles pour ces deux phases, mais l’une ne remplace pas l’autre : commencez par éviter d’accepter plus de travail que vous ne pouvez en gérer, puis définissez séparément la conduite à tenir en cas d’échec.

Questions ouvertes

  • Les sources fournies ne donnent pas de chiffres précis de quotas, de concurrence ou de jetons pour les services cités ; ces valeurs doivent être vérifiées pour chaque compte, modèle, endpoint et région.
  • La disponibilité et la signification des en-têtes ou champs relatifs aux limites peuvent varier selon les réponses et évoluer avec le temps.
  • L’effet de l’annulation d’une requête déjà envoyée dépend de l’API et ne peut pas être établi à partir des sources fournies.
  • La charge, les durées et les objectifs de latence de chaque application ne sont pas précisés ; les seuils doivent être déterminés par des tests propres à chaque application.
  • Les recommandations relatives aux files, aux priorités, aux poids estimés et aux tests sont des principes de conception, pas des garanties de performance.
10

Poursuivre l’exploration

10

Sources consultées

03

Corrections et transparence

Si vous repérez une information incorrecte ou obsolète, envoyez-nous la page et la source à vérifier.

Proposer une correction