429 Trop de demandes : ce que cela signifie et comment le gérer

Une API renvoie 429 Too Many Requests lorsque votre application envoie plus de requêtes que l'API n'en autorise sur une période donnée. La demande elle-même est correcte. Vous avez envoyé trop de requêtes, l'API les a donc refusées. Si vous attendez et l’envoyez à nouveau, cela fonctionne généralement. La réponse comprend souvent un en-tête Retry-After qui indique combien de temps attendre. Pour plus d’informations, consultez RFC 6585, section 4.

Chaque API implémente des limites de débit différemment. Le code d'état, les en-têtes et le corps de l'erreur varient. Ainsi, un code qui gère correctement une API peut mal gérer la suivante.

API Status Comment savoir combien de temps attendre Attention à
GitHub 403 ou 429 retry-after s’il est présent, sinon x-ratelimit-reset (secondes depuis l’époque Unix (UTC)) lorsque x-ratelimit-remaining est 0, sinon au moins 1 minute Un 403 peut indiquer une limite de débit ou une autorisation manquante. Lisez les en-têtes pour faire la distinction.
OpenAI 429 retry-after Certaines erreurs 429, comme credit_balance_exhausted, signifient qu'une nouvelle tentative ne servira à rien. Vérifiez error.code.
Anthropic 429 retry-after Une erreur 429 liée à un plafond de dépenses ne comporte pas d'en-tête retry-after et continue de se produire jusqu'à ce que l'accès soit rétabli. Une API surchargée retourne 529, et non 429.
Microsoft Graph 429 Retry-After (secondes) Les limites diffèrent par service, par exemple SharePoint et Outlook.

Comment gérer un 429

  1. Déterminez s’il faut réessayer ou non. Si le message d'erreur indique que votre quota, vos crédits ou votre limite de dépenses sont épuisés, réessayer ne servira à rien. Informez l'utilisateur et configurez une alerte pour vous-même.
  2. Attendez aussi longtemps que l'API le demande. Si la réponse contient Retry-After, attendez la durée indiquée. Il s’agit d’un nombre de secondes ou d’une date HTTP. Si l'API utilise des en-têtes de limite de débit à la place, comme ceux de GitHub x-ratelimit-reset, attendez jusqu'à l'heure de réinitialisation.
  3. Sinon, reculez. Sans indication de l’API, réessayez avec un backoff exponentiel et une gigue aléatoire, puis arrêtez après quelques tentatives.
  4. Indiquez à l’utilisateur ce qui se passe. « Occupé, réessayer en 5 secondes » vaut mieux qu’un spinner interminable.
  5. Ralentissez avant la prochaine erreur 429. Si l’API envoie des en-têtes de limite de débit, utilisez le nombre restant pour adapter le rythme de vos requêtes.
async function fetchWithRetry(url, options, attempts = 3) {
  for (let attempt = 1; ; attempt++) {
    const response = await fetch(url, options);
    if (response.status !== 429 || attempt === attempts) {
      return response;
    }
    const retryAfter = response.headers.get('retry-after');
    const waitMs = retryAfter
      ? (isNaN(retryAfter) ? new Date(retryAfter) - Date.now() : retryAfter * 1000)
      : 2 ** attempt * 1000 + Math.random() * 1000;
    await new Promise(resolve => setTimeout(resolve, Math.max(waitMs, 0)));
  }
}

De nombreux SDK effectuent automatiquement de nouvelles tentatives en cas d'erreur 429. Par exemple, le SDK Python OpenAI effectue par défaut deux nouvelles tentatives, et le gestionnaire de résilience standard de .NET en effectue trois et respecte Retry-After. Lorsque le kit de développement logiciel (SDK) a épuisé toutes ses tentatives, votre code reçoit l’erreur, il faut donc toujours prévoir une solution de repli.

Comment tester que votre application gère 429

Vous voyez rarement un 429 pendant que vous développez. L’API est rapide, vous êtes le seul utilisateur et vos données de test sont petites. Ainsi, la façon dont vous testez la gestion 429 détermine si vous trouvez les bogues avant que vos utilisateurs ne le fassent.

Approach Ce que vous trouvez Ce qui vous manque
Attendre la mise en production Échecs réels Tout, jusqu'à ce qu'un utilisateur y soit confronté
Simuler l’API dans vos tests ou laisser votre agent de codage écrire la simulation Si votre branche de nouvelle tentative s’exécute Les codes d’état réels, les en-têtes et les corps d’erreurs de l’API et la stratégie de nouvelle tentative de votre SDK. Votre application a également besoin d’un commutateur uniquement pour les tests afin d’accéder au mock.
Appelez l’API réelle jusqu’à ce qu’elle vous limite Comportement réel Vous ne pouvez pas déclencher une erreur 429 à la demande et vous épuisez votre quota réel.
Interceptez le trafic réel de votre application et retournez des 429 à la demande Des URL réelles, votre véritable SDK et votre stratégie de nouvelle tentative, ainsi que le format 429 propre à l'API. Rien ne change dans votre application ; ce test ne permet donc pas de tester votre code isolément. Conservez vos tests unitaires pour cela.

Essayez-le sur votre application

Dev Proxy intercepte les demandes de votre application aux API que vous choisissez et retourne 429s, avec les propres en-têtes et le format d’erreur de l’API, tandis que votre application continue d’appeler les URL réelles. Il vous indique également lorsque votre application effectue une nouvelle tentative avant la fin du délai Retry-After.

Téléchargez le préréglage correspondant à l'API appelée par votre application, puis démarrez Dev Proxy avec ce préréglage :

devproxy config get github-rate-limiting
devproxy --config-file "~dataFolder/configs/github-rate-limiting/.devproxy/devproxyrc.json"
API Preset
GitHub github-rate-limiting
OpenAI openai-throttling
Anthropic anthropic-throttling
Microsoft Graph (OneDrive et SharePoint : /drive, /shares, /sites) microsoft-graph-rate-limiting

Exécutez ensuite votre application comme d’habitude et regardez ce qu’elle fait. Pour installer Dev Proxy, consultez Configurer Dev Proxy.

Étapes suivantes

Voir aussi