Rate limits des API LLM : 13 acteurs, 2 SDK sans retry 429
Sommaire
Sur les treize API LLM étudiées ici, soit dix fournisseurs plus Bedrock, Vertex AI et Azure OpenAI, quatre indiquent le budget restant dans chaque réponse. Mistral ne renvoie qu’un seul compteur restant, et huit ne donnent aucune information avant l’échec de la requête. Un « 429 » recouvre quatre situations différentes : une limitation de débit qu’il faut retenter, une limite d’accélération qui impose de ralentir, un quota ou plafond de dépenses qu’il ne faut pas retenter, et une surcharge signalée par un 429, un 503 ou un 529 selon le fournisseur. Le client pèse aussi lourd que le fournisseur : les SDK OpenAI, Anthropic et Groq retentent deux fois un 429, mais abandonnent lorsque Retry-After dépasse 60 ou 120 secondes. Les SDK Google GenAI et Mistral, eux, désactivent les retries par défaut. Voici une référence transverse : dimensions, tokens comptabilisés, headers, sémantique des 429 et comportement de chaque SDK officiel, vérifié directement dans son code source.
TL;DR
- Les API LLM limitent les requêtes et les tokens par minute. Anthropic sépare entrée et sortie, tandis que DeepSeek limite uniquement la concurrence.
- OpenAI, Azure et Bedrock débitent
max_tokensdès le départ. Anthropic exclut les lectures du cache, xAI compte les tokens de raisonnement, et Bedrock consomme 10 tokens de quota par token de sortie Claude 5. - OpenAI, Anthropic, Groq et Azure renvoient les headers de limite, de solde et de réinitialisation avec chaque 200. Huit API n’en documentent aucun.
- Les SDK google-genai et Mistral ne retentent pas un 429 par défaut. OpenAI, Anthropic et Groq font deux retries et plafonnent Retry-After à 60 ou 120 secondes.
Que signifient RPM, TPM et les autres limites ?
Toutes fixent un plafond d’utilisation sur une fenêtre donnée, mais chaque fournisseur choisit ses propres métriques :
| Groupe | Termes | Signification et fournisseurs concernés |
|---|---|---|
| Compteurs de requêtes | RPM, RPD, RPS, concurrence | Requêtes par minute ou par jour, à raison d’une unité par appel quelle que soit sa taille. Le RPS correspond généralement au RPM divisé par 60 et sert de protection contre les pics (xAI, Alibaba, Mistral, Azure). La concurrence compte les requêtes en cours plutôt que celles envoyées pendant une fenêtre. C’est la seule limite de DeepSeek |
| Compteurs de tokens | TPM, TPD, ITPM, OTPM, burndown rate | Tokens par minute ou par jour. Certains fournisseurs séparent l’entrée (ITPM) et la sortie (OTPM). Un burndown rate multiplie les tokens de sortie avant de les imputer au quota (Bedrock). Chaque fournisseur décide quels tokens sont comptés, comme détaillé plus bas |
| Compteurs d’autres unités | IPM, secondes audio, pages OCR | Images par minute pour les modèles d’image (OpenAI, Gemini), secondes audio par heure ou par jour (Groq, Mistral), pages par minute pour l’OCR de documents (Mistral) |
| Application de la fenêtre | Token bucket, limite d’accélération | Un token bucket se remplit en continu au lieu d’être réinitialisé chaque minute. Un pic peut donc le vider même si le total reste sous la limite par minute (Anthropic ; Alibaba et Azure décrivent le même mécanisme). Une limite d’accélération contrôle séparément la vitesse de croissance du trafic. Une montée soudaine peut la déclencher même sous la limite (Anthropic, slow_down chez OpenAI) |
| Détermination des limites | Tier, plafond de dépenses ou quota, capacité provisionnée | Le tier détermine les compteurs ci-dessus. Il augmente avec l’usage payant ou l’historique, pas avec les rechargements de crédit. Un plafond de dépenses ou un quota quotidien limite un montant ou un volume, pas un débit. Attendre une minute ne change donc rien. La capacité provisionnée réserve un débit facturé par unité et par heure (Bedrock et Vertex AI Provisioned Throughput, Azure PTU). Un 429 indique alors que la réservation est saturée, pas qu’un quota est épuisé |
La valeur affichée est un plafond sur la fenêtre, pas un crédit à consommer librement. Anthropic précise que 60 RPM « might be enforced as 1 request per second ». Azure indique qu’« a burst within a 1-second or 10-second window can trigger a 429 even if the per-minute total is within limits ».
Quelles limites les API LLM appliquent-elles ?
Presque toutes limitent les requêtes et les tokens par minute. Les trois clouds ne se contentent pas de relayer les règles de leurs fournisseurs. Les définitions ci-dessous sont celles des fournisseurs, telles qu’elles figuraient sur les pages liées les 2026-09-03 et 2026-09-04.
| Fournisseur | Dimensions | Évolution des limites | Source |
|---|---|---|---|
| OpenAI | RPM, RPD, TPM, TPD, IPM, minutes audio par minute ; file d’attente Batch API mesurée en tokens d’entrée en attente | Tiers 1 à 5 selon le cumul des paiements | limites de débit |
| Anthropic | RPM, ITPM, OTPM par classe de modèles ; token bucket ; limites d’accélération | Tiers Start, Build et Scale selon l’historique d’utilisation | limites de débit |
| Google Gemini | RPM, TPM (entrée), RPD ; IPM pour les modèles d’image | Gratuit, puis Tiers 1 à 3 avec limites de dépenses par tranche de 10 minutes | limites de débit |
| xAI | RPS (RPM / 60) et TPM par modèle | Tiers 0 à 4 plus Enterprise | limites de débit |
| Alibaba Model Studio | RPM et TPM par modèle, avec RPS = RPM / 60 et TPS = TPM / 60 comme protections contre les pics | Par modèle ; batch exempté pour certains modèles | limites de débit |
| DeepSeek | Concurrence uniquement : 500 connexions sur V4 Pro, 2,500 sur V4 Flash | Fixe par modèle | limite de débit |
| Mistral | RPS, tokens par minute, tokens par mois, par modèle et workspace | Tiers 1 à 4 selon le cumul de facturation ; « Adding credits does not raise your rate limits » | utilisation et limites, centre d’aide |
| MiniMax | RPM et TPM par modèle ; MiniMax M3 à 200 RPM et 10M TPM | Contacter le service commercial | limites de débit |
| Moonshot Kimi | Concurrence, RPM, TPM, TPD ; le Tier 0 autorise 1 requête concurrente et 3 RPM, le Tier 5 en autorise 100 et 300 | Six tiers selon le cumul des rechargements, de $1 à $3,000 | limites |
| Groq | RPM, RPD, TPM, TPD, ITPM, OTPM, secondes audio par heure et par jour | Par modèle | limites de débit |
| Amazon Bedrock | RPM, TPM, TPD par modèle et par région ; TPD vaut TPM x 1,440 par défaut | Service Quotas, relevés sur demande ; les nouveaux comptes démarrent avec des limites réduites | quotas |
| Google Vertex AI | Aucun chiffre par projet en pay-as-you-go : pool partagé où « your organization’s historical spend determines your Usage Tier and baseline throughput (TPM) », avec gestion des pics en best effort | Tier d’utilisation selon les dépenses ; Provisioned Throughput « provides isolation from the shared PayGo pool » | blog Google Cloud |
| Azure OpenAI | TPM attribué par déploiement, RPM dérivé de cette valeur (6 RPM pour 1,000 TPM sur les anciens modèles, 1 RPM pour 1,000 TPM sur les modèles actuels) ; déploiements PTU limités par leur taux d’utilisation | Tiers de quota 0 à 6, avec montée automatique | quotas et limites, gestion des quotas |
Deux lignes ne correspondent pas du tout à des fenêtres d’une minute. DeepSeek limite les connexions ouvertes. En cas de charge, il conserve la requête ouverte en envoyant des lignes vides, ou des commentaires : keep-alive sur un stream, pendant 10 minutes au maximum au lieu de la rejeter. Vertex AI en pay-as-you-go ne publie aucun quota consultable : un 429 signifie simplement que le pool partagé manquait de capacité à cet instant.
Quels tokens sont imputés à la limite ?
Ce ne sont pas toujours les mêmes que ceux facturés. Selon la règle retenue, la capacité réelle peut représenter une fraction ou un multiple du chiffre affiché :
| Fournisseur | Tokens imputés à la limite | Conséquence |
|---|---|---|
| OpenAI | La valeur la plus élevée entre max_tokens et une estimation calculée à partir du prompt, débitée à l’arrivée : « If you set max_tokens too high, your usage can be overestimated, even if the actual response is much shorter » (cookbook) | Un max_tokens de 4,000 pour une réponse de 50 tokens consomme 4,000 TPM |
| Azure OpenAI | Estimation basée sur « prompt text and count, the max_tokens parameter setting, the best_of parameter setting », en partie à partir du nombre de caractères ; sur les déploiements PTU, « cached tokens receive a 100% discount » (guide des quotas) | « A rate limit can be triggered prior to what might be expected » ; si max_tokens n’est pas défini, Azure l’estime |
| Amazon Bedrock | « Total input tokens + max_tokens » est déduit au départ, puis corrigé à la fin selon InputTokenCount + CacheWriteInputTokens + (OutputTokenCount x burndown rate). Les lectures du cache sont exclues. Le burndown est de 5x sur Claude 4.7 et les versions antérieures, de 10x sur Sonnet 5, Opus 5, Fable 5.1 et les modèles GPT-5.6, et de 15x sur Claude 4.8 (comptage des tokens) | Dans l’exemple documenté, 1,000 tokens d’entrée et 100 tokens de sortie sur un modèle à 5x consomment 1,500 tokens de quota, mais 1,100 sont facturés |
| Anthropic | L’ITPM compte input_tokens et cache_creation_input_tokens. Les cache_read_input_tokens « do NOT count toward ITPM ». L’OTPM compte la sortie réelle ; « max_tokens does not factor into OTPM » (documentation) | Dans l’exemple documenté, 2M ITPM avec un taux de cache hit de 80 % permettent de traiter 10M tokens d’entrée par minute |
| xAI | « All tokens consumed by a request count toward the TPM limit: prompt tokens (text, image, and audio), completion tokens, reasoning tokens (on reasoning models), cached prompt tokens » | Le raisonnement consomme du TPM pour des tokens invisibles au client. Le cache n’augmente pas le débit |
| Google Gemini | Tokens d’entrée | La longueur de la sortie ne réduit pas la limite |
| Alibaba, Mistral, MiniMax | Entrée plus sortie | |
| Kimi, Groq, DeepSeek, Vertex AI | Non précisé | Groq mesure séparément l’ITPM et l’OTPM. DeepSeek n’applique pas de limite de tokens. Vertex AI ne publie qu’une base liée au tier d’utilisation |
Dans l’exemple ci-dessus, la même requête pèse entre 800 et 6,000 tokens selon le fournisseur. Un routeur qui répartit une charge entre plusieurs fournisseurs doit donc maintenir un compteur propre à chacun.
Quels headers chaque fournisseur renvoie-t-il ?
Quatre API exposent l’état des limites dans chaque réponse. Mistral renvoie un seul champ. Les huit autres vous obligent à compter vous-même.
| Fournisseur | Headers d’une réponse normale | Remarques sur le format |
|---|---|---|
| OpenAI | x-ratelimit-limit-requests, x-ratelimit-limit-tokens, x-ratelimit-remaining-requests, x-ratelimit-remaining-tokens, x-ratelimit-reset-requests, x-ratelimit-reset-tokens, plus le trio -project-tokens | Reset correspond à « the time until the rate limit resets » ; Retry-After sur les 429 |
| Azure OpenAI | Les six mêmes noms x-ratelimit-* à chaque appel ; retry-after-ms et retry-after sur les 429 | Un x-ratelimit-limit-tokens inférieur au TPM configuré indique qu’un « temporary rate limit adjustment » est actif |
| Anthropic | anthropic-ratelimit-requests-{limit,remaining,reset}, le même trio pour tokens, input-tokens et output-tokens, plus anthropic-priority-* et anthropic-fast-* lorsque ces tiers s’appliquent | Reset au format RFC 3339 ; solde arrondi au millier le plus proche ; le trio tokens-* indique « the most restrictive limit currently in effect » |
| Groq | x-ratelimit-limit-requests (quotidien), x-ratelimit-limit-tokens (par minute), x-ratelimit-remaining-*, x-ratelimit-reset-* ; « always included » | Reset sous forme de durées, "2m59.56s", "7.66s" ; retry-after en secondes, uniquement sur les 429 |
| Mistral | X-RateLimit-Remaining | |
| Gemini, xAI, Alibaba, DeepSeek, MiniMax, Kimi, Bedrock, Vertex AI | Aucun documenté | Gemini, Alibaba et Bedrock indiquent la cause dans le corps de l’erreur. Kimi documente Retry-After en cas de surcharge. Les SDK AWS lisent x-amz-retry-after en millisecondes lorsqu’un service l’envoie |
Le vrai problème vient des trois formats utilisés pour un même champ : durée chez OpenAI, timestamp chez Anthropic et valeur comme 2m59.56s chez Groq. Il faut trois parseurs. C’est notamment pour cela que les SDK ne lisent que retry-after. Deux intermédiaires ont été testés le 2026-09-03, avec une requête chacun. Un grand agrégateur multi-fournisseurs n’a renvoyé aucun header de rate limit sur une réponse 200 et les réserve aux 429. La gateway Synthorai a renvoyé x-ratelimit-remaining-requests et x-ratelimit-reset-requests avec le coût de la requête.
Que signifie un 429, et faut-il retenter ?
Un 429 peut correspondre à quatre situations. Seules deux justifient un retry :
| Signification | Retry ? | Formulation de chaque fournisseur |
|---|---|---|
| Throttling : vous avez dépassé une limite | Oui, après Retry-After ou un backoff | OpenAI et Anthropic : 429 rate_limit_error, avec retry-after chez Anthropic ; Gemini et Vertex AI : 429 RESOURCE_EXHAUSTED, qui signifie sur Vertex AI que le pool partagé manquait de capacité ; Kimi : rate_limit_reached_error ; Bedrock : ThrottlingException, plus ModelNotReadyException retenté jusqu’à 5 fois par le SDK ; Azure : « Rate limit is exceeded » ; xAI : RateLimitError ; Alibaba : « Requests rate limit exceeded » ; DeepSeek et Mistral : 429 |
| Accélération : le trafic a augmenté trop vite | Ralentir la montée, puis retenter | OpenAI : slow_down ; Anthropic : « acceleration limits » ; Alibaba : « Request rate increased too quickly » ; Azure : pic dans une fenêtre de 1 seconde ou 10 secondes |
| Quota ou plafond de dépenses : attendre ne libérera rien | Non ; corriger la facturation ou attendre la date de réinitialisation | OpenAI : insufficient_quota, credit_balance_exhausted, organization_spend_limit_exceeded ; Anthropic : enforced_spend_limit_reached sans retry-after, tandis que votre propre plafond de dépenses produit un 400 ; Gemini : quota_exceeded (quotidien) ; Kimi : exceeded_current_quota_error ; Bedrock : 400 ServiceQuotaExceededException ; agrégateur et DeepSeek : 402. Sur Azure, le quota est attribué au déploiement, donc son épuisement ne produit pas un 429 |
| Surcharge : la capacité du fournisseur, pas la vôtre | Oui, avec backoff | OpenAI : 503 server_is_overloaded ; Anthropic : 529 overloaded_error ; Gemini : 503 UNAVAILABLE ; Kimi : 429 engine_overloaded_error avec Retry-After ; Bedrock : 503 ServiceUnavailableException et 529 overloaded_error ; Azure : « System is experiencing high demand », « temporary rate limit adjustment » du pool partagé, ou PTU à 100 % d’utilisation avec retry-after-ms ; DeepSeek : 503 |
Le piège se trouve sur la troisième ligne. Chez Anthropic, un 429 lié au plafond de dépenses porte le même type rate_limit_error qu’un throttling, et la documentation précise : « Retrying, including the SDKs’ automatic retries, fails until access resumes. » Chez OpenAI, insufficient_quota est également un 429. Un client qui ne regarde que le code HTTP retente les deux, comme le font tous les SDK officiels décrits dans la section suivante. Il faut décider selon le code d’erreur et considérer qu’un 429 sans Retry-After peut indiquer qu’attendre ne servira à rien.
Les clouds se distinguent sur la quatrième ligne. Le guide de diagnostic Azure est explicite : « Many customers misinterpret capacity-related 429s as quota problems, leading to incorrect remediation. » Sur Azure, un 429 accompagné d’un x-ratelimit-limit-tokens inférieur à la limite configurée vient du mécanisme de protection du pool partagé. Sur Vertex AI, tous les 429 en pay-as-you-go ont cette signification. Sur Bedrock, la même situation produit un 503 ou un 529, jamais un ThrottlingException. Via un agrégateur, l’information apparaît dans le corps. Lors de la mesure des headers, un 429 a été encapsulé avec provider_error_code: insufficient_quota, limit_source: upstream_provider_shared_pool. Le statut indiquait un throttling, mais le corps signalait le quota d’un tiers.
Comment votre SDK traite-t-il un 429 ?
Cela dépend du SDK, et deux des plus utilisés ne font rien. Les comportements ci-dessous ont été vérifiés le 2026-09-04 directement dans le code source de chaque client officiel, pas dans sa documentation :
| SDK | Retries par défaut | Statuts retentés | Backoff | Traitement de Retry-After |
|---|---|---|---|---|
| openai-python (Azure OpenAI compris) | 2 | 408, 409, 429, 5xx, ou toute valeur indiquée par x-should-retry | min(0.5 × 2^n, 8) s avec jitter | Lit retry-after-ms, puis retry-after comme durée en secondes ou date ; au-delà de 120 s, aucun retry |
| anthropic-sdk-python, groq-python | 2 | identiques | identique | Même parsing ; au-delà de 60 s, le header est ignoré et la formule de backoff s’applique |
| openai-node, anthropic-sdk-typescript | 2 | identiques | identique | Identique ; au-delà de 60 s, retour au backoff par défaut |
| google-genai (Python, Gemini API et Vertex AI) | 0 : retry_options vaut None par défaut, ce qui produit une seule tentative | Si activé : 408, 429, 500, 502, 503, 504 | Si activé : 5 tentatives, de 1 s à 60 s par doublement, avec jitter | Ne lit pas Retry-After |
| mistralai (Python) | 0 : retry_config n’est pas défini par défaut | Si configuré : 429, 500, 502, 503, 504 | Si configuré : 500 ms × 1.5^n jusqu’à 60 s, avec un total maximal de 1 h | Respecte tout Retry-After, sous forme de secondes ou de date |
| boto3 (Bedrock) | Mode legacy : 5 tentatives, première comprise ; mode standard : 3 | ThrottlingException et erreurs apparentées, 429, 5xx | Facteur de base 2, plafond de 20 s en mode standard. Le comportement 2026, activé avec AWS_NEW_RETRIES_2026=true, utilise un full jitter, une base de 1,000 ms pour le throttling et un token bucket de retry | Aucun Retry-After ; le comportement 2026 lit x-amz-retry-after en millisecondes, plafonné au backoff plus 5 s |
| xai-sdk (Python, gRPC) | 5 tentatives, uniquement pour UNAVAILABLE | RESOURCE_EXHAUSTED, l’équivalent gRPC du 429, n’est pas retenté | De 0.1 s à 1 s par doublement | n/a |
| dashscope (Alibaba) | 0 selon le statut HTTP ; un seul renvoi si une connexion du pool tombe avant l’arrivée du moindre octet | |||
| DeepSeek, Kimi, MiniMax | Aucun SDK de chat propriétaire ; la documentation DeepSeek recommande « use the OpenAI/Anthropic SDK » avec une autre URL de base |
Trois conclusions s’imposent. D’abord, un 429 de Gemini, Vertex AI ou Mistral remonte à votre code dès la première occurrence si vous n’avez pas fourni d’options de retry. Dans le code source de google-genai, le commentaire indiquant que le client « will retry 4 times » décrit la configuration activée, pas le comportement par défaut. Ensuite, les plafonds appliqués à Retry-After vont à l’encontre des longues attentes réellement demandées par les fournisseurs. Si Anthropic demande d’attendre 90 secondes, son SDK ignore le header et revient en moins de 8 secondes. Si OpenAI en demande 150, son SDK arrête complètement les retries. Enfin, les SDK générés par Stainless, le générateur de code utilisé par les clients OpenAI, Anthropic et Groq, appliquent d’abord le header non documenté x-should-retry, avant même d’examiner le statut HTTP. Ils lisent aussi retry-after-ms avant retry-after. Un fournisseur ou une gateway peut donc piloter les retries sans modifier le code de statut.
Aucun de ces SDK ne distingue un 429 lié au plafond de dépenses d’un throttling. Deux retries sur une réponse insufficient_quota ne coûtent que quelques secondes chacun. À l’échelle d’une flotte, ils créent pourtant un pic de trafic entièrement évitable.
Que change une gateway ?
Une gateway centralise ce traitement. Côté upstream, elle lit les headers propres à chaque fournisseur. Les trois formats de reset et les quatre significations d’un 429 deviennent son problème, plutôt que celui de chaque client. Côté downstream, elle expose un jeu de headers et un format d’erreur uniques, comme les headers Synthorai mesurés plus haut. Elle ne peut toutefois pas modifier la comptabilité du fournisseur : derrière OpenAI, le max_tokens du client est toujours débité du TPM dès le départ ; derrière Bedrock, un token de sortie Claude en consomme toujours dix. Si une gateway mutualise plusieurs clients sur une même clé fournisseur, elle atteint aussi la limite d’accélération de ce fournisseur plus vite que ne le ferait un client isolé. Il faut donc des buckets par clé, pas un compteur partagé unique.
FAQ
max_tokens compte-t-il dans la limite de débit ?
Oui sur OpenAI, Azure OpenAI et Bedrock : max_tokens est débité à l’arrivée de la requête. Une valeur surdimensionnée gaspille donc du TPM, même si la réponse est courte. Bedrock corrige la déduction à la fin de la réponse. Non sur Anthropic : l’OTPM compte les tokens réellement générés et max_tokens « does not factor » dans ce calcul.
Les tokens en cache comptent-ils dans la limite de débit ?
Pas sur Anthropic, Bedrock ni les déploiements Azure PTU, où les lectures du cache sont exclues. Sur xAI, ils comptent intégralement. OpenAI et Gemini ne le précisent pas.
Retry-After est-il toujours envoyé avec un 429 ?
Non. OpenAI, Azure sous la forme retry-after-ms, et Groq l’envoient en cas de throttling. Anthropic l’envoie aussi pour le throttling, mais pas pour un plafond de dépenses. Kimi et Bedrock ne l’envoient qu’en cas de surcharge. Gemini, Vertex AI, xAI, Alibaba, DeepSeek et MiniMax n’en documentent aucun. Le client doit donc gérer son propre backoff pour ces fournisseurs.
Pourquoi mon SDK n’a-t-il pas retenté un 429 ?
Avec le SDK Python Google GenAI ou Mistral, les retries sont désactivés par défaut. Il faut fournir retry_options ou un RetryConfig. Avec le SDK Python OpenAI, si le serveur demande plus de 120 secondes d’attente, le SDK choisit de ne pas retenter. Si le 429 correspond à un quota ou à un plafond de dépenses plutôt qu’à un throttling, l’absence de retry est le bon comportement.
À lire aussi : guide des unités de facturation, tarifs des longues fenêtres de contexte, anatomie de l’utilisation des tokens, audit du cache d’une gateway.