10 juil. 2025·8 min de lecture

Gestion des 429 : file d'attente, backoff et états utilisateurs clairs

Gestion des erreurs 429 pour apps LLM et API : filez les requêtes, appliquez un backoff sécurisé et montrez des états utilisateurs clairs pour garder le produit prévisible.

Gestion des 429 : file d'attente, backoff et états utilisateurs clairs

Ce que signifie vraiment un 429 (et pourquoi les utilisateurs le remarquent)

Un 429, c'est le fournisseur qui dit : ralentissez. Vous envoyez trop de requêtes trop vite. Cela ne signifie généralement pas que votre code est "erroné". Cela signifie que vous avez atteint une limite mise en place pour protéger leurs systèmes (et parfois votre propre budget).

Les utilisateurs trouvent la gestion des 429 frustrante même lorsque l'app fonctionne globalement. L'expérience devient chaotique : un spinner qui ne s'arrête jamais, une erreur après une longue attente, ou des réponses qui apparaissent parfois et échouent d'autres fois. Le pire, c'est l'incohérence. Les gens ne peuvent pas prévoir ce qui va se passer ensuite.

Les retries peuvent aider, mais des retries imprudents empirent souvent la situation. Si chaque requête échouée retente immédiatement, vous créez un pic de trafic justement au moment où le fournisseur vous demande de réduire la charge. Cela peut transformer une petite alerte en une panne plus longue et épuiser rapidement les quotas.

L'objectif n'est pas la vitesse parfaite. C'est un comportement prévisible sous charge. L'app devrait se comporter de la même façon à chaque fois, même si la réponse arrive plus tard.

Un modèle mental simple comporte trois éléments qui fonctionnent ensemble :

  • Une file d'attente pour lisser les pics au lieu de tout lancer d'un coup
  • Un backoff (souvent exponentiel avec jitter) pour étaler les retries
  • Des états utilisateur clairs pour indiquer si la requête attend, retente ou nécessite une action

Exemple : une appli de chat subit un pic le matin. Sans contrôle, la moitié des messages échoue de façon aléatoire. Avec une file d'attente et du backoff, les messages mettent peut-être plus de temps, mais les utilisateurs voient « En file » puis « Nouvelle tentative dans 4s ». L'app paraît calme et fiable au lieu d'être cassée.

D'où viennent généralement les limites dans les vraies apps

La plupart des 429 ne sont pas des pannes aléatoires. Ce sont le signe que trop de requêtes ont atteint une limite en même temps, et que votre appli n'a pas étalé la charge.

Le déclencheur le plus courant est un pic : un lancement, un post sur les réseaux, ou un gros client invitant son équipe. Les jobs batch provoquent aussi ça, comme le réindexage de contenu, l'import de CSV, ou le backfill d'embeddings la nuit.

Il importe aussi de savoir quelle limite vous avez atteinte. Les fournisseurs appliquent souvent des plafonds par clé API, par compte ou par région. Votre appli peut aussi créer des limites, volontairement ou par accident : par utilisateur, par workspace, ou par IP (surtout si de nombreux utilisateurs sont derrière un NAT d'entreprise).

Les apps LLM ont quelques motifs qui atteignent les limites plus vite que prévu :

  • Les réponses en streaming maintiennent des connexions ouvertes plus longtemps, donc la concurrence augmente même si le QPS semble normal.
  • Les appels d'outils multiplient le travail, car une seule "réponse" peut déclencher des appels supplémentaires pour récupérer des données, exécuter des fonctions, puis interroger à nouveau le modèle.
  • Les embeddings en masse sont classiques : une action « importer des documents » peut lancer des centaines de requêtes en boucle serrée.

Les multiplicateurs cachés sont la cause habituelle. Un clic peut créer beaucoup d'appels en aval :

  • L'envoi d'un chat déclenche la modération, la completion principale et un appel de logging
  • Un message utilisateur peut lancer 3–10 appels d'outils avant la réponse finale
  • Un bouton « retry » lance immédiatement plus de pression
  • Un chargement de page déclenche plusieurs requêtes parallèles sur différents onglets
  • Un worker en arrière-plan répète le même job en échec sur plusieurs comptes

Le staging semble souvent correct parce qu'il y a un seul utilisateur, des données propres et pas de cron jobs. La production a de la concurrence, des pics d'utilisation réels, des sessions streaming longue durée, et des tempêtes accidentelles comme plusieurs workers démarrant le même backfill.

Choisir une politique claire : retenter, retarder ou arrêter

Quand vous recevez un 429, la pire réaction est « réessayer immédiatement » sans règle. Cela pousse le fournisseur à vous repousser davantage et rend l'app aléatoire. Une bonne gestion des 429 commence par une politique simple que toute l'équipe peut suivre.

Séparez les requêtes en deux catégories :

  • Actions interactives (l'utilisateur a cliqué)
  • Travail en arrière-plan (syncs, webhooks, jobs batch)

Les actions interactives demandent une courte fenêtre de patience et un retour clair. Le travail en arrière-plan peut attendre plus longtemps, tant que cela n'empile pas indéfiniment.

Une politique pratique à adopter et ajuster ensuite :

  • Retry uniquement quand la requête est sûre à répéter (appels en lecture, ou écritures avec idempotence).
  • Fixez une fenêtre maximale de retry (par exemple 10–20 secondes pour l'interactif, 5–30 minutes pour le background).
  • Arrêtez et échouez vite quand l'utilisateur peut corriger le comportement (comme spammer « Régénérer ») ou quand une donnée requise manque.
  • Utilisez des priorités séparées : les requêtes interactives passent devant, le background cède quand les limites se resserrent.
  • Loggez le contexte à chaque 429 pour pouvoir diagnostiquer des motifs, pas des suppositions.

L'idempotence rend les retries sûrs. Si une opération crée quelque chose (prélever une carte, créer un enregistrement, envoyer un email), joignez une clé d'idempotence pour qu'un retry n'engendre pas d'effets dupliqués. Si vous ne pouvez pas rendre l'opération idempotente, préférez « arrêter et demander » plutôt que des retries aveugles.

Définissez le « terminé » pour chaque requête. Une requête doit soit réussir, soit retourner une erreur claire, soit expirer après votre fenêtre de retry maximale. Rester pendu pour toujours est le résultat le plus frustrant.

Loggez assez pour répondre aux bases : quel endpoint a été frappé, quel utilisateur l'a déclenché, quel type de requête (interactif vs background), quand elle a commencé et combien de temps elle a attendu.

Pas à pas : ajouter une file d'attente qui lisse les pics

La manière la plus rapide d'améliorer la gestion des 429 est d'arrêter d'envoyer les requêtes dès que l'UI les déclenche. Mettez chaque appel API dans une file d'attente. Cela transforme un pic de 50 clics en un flux contrôlé que le fournisseur peut accepter.

1) Commencez par une petite file entre votre UI et le fournisseur

Gardez la première version simple. Quand l'app veut appeler le LLM ou une API, elle crée un job avec le payload et quelques étiquettes (qui l'a demandé, pour quel écran, quand il a été créé). L'UI envoie des jobs à la file, pas directement au fournisseur.

Une forme de job pratique inclut : endpoint/model, prompt ou hash des paramètres, ID utilisateur, priorité et compteur de retry.

2) Ajoutez un worker avec limite de concurrence

Un worker retire les jobs de la file et les exécute. Le paramètre clé est la concurrence : combien de jobs peuvent tourner en même temps. Commencez bas (1 à 3 par exemple), puis augmentez seulement si les résultats sont stables.

Une approche simple qui marche dans la plupart des apps :

  • Traitez seulement N jobs en parallèle (votre limite de concurrence)
  • Quand un job finit, lancez immédiatement le suivant
  • Si un job reçoit un 429, remettez-le dans la file avec un délai (le backoff est couvert plus bas)
  • Suivez les jobs actifs pour ne jamais dépasser N

3) Priorités : garder l'app réactive

Toutes les requêtes ne se valent pas. Un bouton cliqué par l'utilisateur doit passer devant un travail en arrière-plan comme « résumer tout » ou « générer le rapport hebdo ». Commencez par deux priorités (haute et basse). Si votre file le permet, traitez la haute priorité comme une voie séparée.

4) Dédupliquer les requêtes répétées

Les utilisateurs double-cliquent. Les frontends re-rendent. Si vous envoyez des prompts identiques dans une courte fenêtre (2 à 10 secondes), fusionnez-les. Retournez le même résultat en vol à tous les appelants. Cela peut réduire fortement le volume de requêtes.

5) Persistez l'état de la file pour que les redémarrages ne perdent pas le travail

Si le serveur redémarre, vous ne voulez pas que les jobs en attente disparaissent ou se répètent de façon imprévisible. Stockez les jobs en file et leur statut dans un stockage durable (base de données ou système de queue approprié). C'est aussi là où beaucoup de prototypes échouent : les requêtes sont fire-and-forget, et les utilisateurs voient des réponses manquantes, des duplications ou des spinners infinis quand les limites sont atteintes.

Pas à pas : un backoff qui réduit la pression au lieu de l'ajouter

Auditez votre politique de retry
Confirmez idempotence, budgets temporels et gestion de Retry After dans toute votre appli.

Une bonne gestion des 429 consiste surtout à faire moins, pas à essayer plus fort. Si vous retentez trop vite, vous transformez un petit ralentissement en un pic de trafic et laissez les utilisateurs coincés dans une boucle.

Commencez par un backoff exponentiel : après le premier 429, attendez un peu, puis attendez plus longtemps après chaque 429 suivant. Une règle simple est de doubler le délai à chaque fois. Cela laisse le fournisseur récupérer et empêche votre appli de marteler l'API.

Ajoutez du jitter (un petit aléa) à chaque attente. Sans jitter, des milliers de clients qui atteignent la limite en même temps retenteront au même moment et retomberont sur la limite. Le jitter étale les retries et donne une chance à votre appli de réussir.

Si le fournisseur vous donne une indication comme une valeur Retry-After, traitez-la comme source de vérité. Utilisez-la comme base du délai, puis appliquez un petit jitter autour.

Fixez des plafonds clairs pour que les retries ne durent pas éternellement :

  • Nombre maximum de tentatives (par exemple 3–6 essais)
  • Délai maximum (par exemple plafonner les attentes à 30–60 secondes)
  • Budget de temps total (arrêter après, disons, 2 minutes)
  • Une voie de secours (sauver la tâche, demander à l'utilisateur de réessayer plus tard)

Arrêtez de retenter sur des erreurs qui ne se corrigeront pas seules. Un 400 échouera à chaque fois. Un 401/403 signifie que l'auth est cassée. Retentez seulement quand c'est susceptible de réussir (429, plusieurs 5xx et certains timeouts réseau).

Exemple : une fonctionnalité de chat reçoit des 429 lors d'un lancement. Tentative 1 attend 1–2s, tentative 2 attend 2–4s, tentative 3 attend 4–8s, puis vous arrêtez et affichez un message clair que le système est occupé et que le message sera envoyé quand possible.

États visibles par l'utilisateur qui rendent l'app prévisible

Quand vous subissez une limite, le pire n'est pas le délai. C'est la confusion. Si l'UI a l'air gelée ou bascule sans cesse entre erreurs et spinners, les utilisateurs vont cliquer à nouveau, rafraîchir ou ouvrir un autre onglet. Cela crée plus de requêtes et prolonge le problème.

Une bonne gestion des 429 commence par nommer ce qui se passe en langage simple et donner une seule action claire.

Utilisez un petit ensemble d'états clairs

Gardez les états cohérents dans toute l'app. La plupart des équipes n'ont besoin que de trois états :

  • En file : « Nous sommes en file pour envoyer votre requête. »
  • Nouvelle tentative : « Le fournisseur est occupé. Nouvelle tentative dans 10–20 secondes. »
  • Réessayer : « Nous n'avons pas pu l'envoyer pour l'instant. Veuillez réessayer maintenant. »

Ajoutez une estimation de durée quand vous le pouvez, même si ce n'est qu'une fourchette. Vous pouvez la baser sur la position dans la file (par exemple 3 requêtes devant) ou sur votre timer de backoff. Un petit compte à rebours aide les gens à attendre sans cliquer.

Proposez un bouton Annuler sûr pour les longues attentes. Expliquez en une phrase ce que signifie annuler : « Annuler coupe les retries. Votre brouillon reste ici et rien n'est envoyé. » Si annuler fait perdre du travail, dites-le clairement et proposez « Enregistrer le brouillon » à la place.

Évitez les erreurs brutes comme « 429 » ou « Too Many Requests. » Traduisez-le en ce qui intéresse l'utilisateur : « Le fournisseur d'IA nous demande de ralentir. » Puis proposez une action : continuer d'attendre (par défaut) ou réessayer.

Pour des attentes supérieures à quelques secondes, affichez une notification légère quand c'est prêt, comme une bannière in-app « Votre réponse est prête » ou un changement d'état sur le message. C'est particulièrement important dans le chat.

Protéger le reste de l'app pendant que le fournisseur vous ralentit

Quand un fournisseur commence à renvoyer des 429, le plus grand risque n'est pas l'appel raté. C'est l'effet domino : des threads bloqués, des files qui gonflent sans limite, et des parties non liées de l'app qui semblent lentes. Une bonne gestion des 429 vise surtout la contention.

Commencez par des timeouts partout où un appel fournisseur peut rester bloqué. Un retry qui attend pour toujours n'est pas patient, c'est un bloqueur. Gardez un temps max clair par tentative et un temps max total pour les retries, afin qu'une requête ne puisse pas tenir en otage le reste du système.

Un circuit breaker aide quand les 429 montent en flèche. Au lieu de laisser chaque requête frapper le fournisseur, suspendez les appels pour une courte fenêtre, puis testez avec une petite requête. Cela rend le ralentissement prévisible et empêche d'ajouter de la pression.

Séparez la réactivité de l'UI de la vitesse du fournisseur. L'UI doit réagir instantanément : accepter l'action utilisateur, montrer un état clair et traiter le travail en arrière-plan. Si vous liez les clics de bouton au temps de réponse du fournisseur, l'app entière paraît cassée même quand une seule dépendance est lente.

Des budgets par utilisateur empêchent un utilisateur lourd (ou un bug) d'affamer tout le monde. Gardez-le simple : combien de jobs en file et combien de temps de retry un utilisateur peut consommer avant que vous commenciez à retarder ou rejeter.

Signaux utiles à surveiller :

  • Taux de 429 dans le temps (pics vs continu)
  • Profondeur de la file (combien de jobs attendent)
  • Temps moyen d'attente avant qu'un job démarre
  • Taux de timeout (trop strict vs trop laxiste)
  • Temps d'ouverture du circuit breaker (à quelle fréquence vous suspendez les appels)

Erreurs courantes qui aggravent les 429

Préparez-vous pour le déploiement
Préparez le lancement avec refactorings, contrôles de sécurité et readiness pour le déploiement.

La plupart des douleurs liées aux 429 viennent de quelques erreurs prévisibles. Évitez-les et la gestion des 429 devient ennuyeuse (dans le bon sens).

Retenter d'une façon qui crée une tempête de retries

Les retries instantanés, ou avec le même délai fixe, peuvent transformer un petit ralentissement en panne. Si 200 utilisateurs appuient sur « Réessayer » et que chaque client retente à la même seconde, vous obtiendrez une vague synchronisée qui déclenche encore des 429.

Utilisez un délai qui croît dans le temps, plus du jitter, pour étaler les retries.

Retries sans fin et coûts cachés

Sans un nombre max de tentatives et un temps total max, une seule action utilisateur peut déclencher une boucle non bornée. Cela peut consommer des tokens ou des crédits API, maintenir des workers occupés à faire rien d'utile et créer des écrans « chargement pour toujours ».

Limitez les retries et arrêtez-vous avec un message clair quand la limite est atteinte.

Une limite globale sans priorités

Si vous traitez tous les appels de la même façon, le travail en arrière-plan (embeddings, imports) peut affamer des flux critiques comme login, checkout ou « Envoyer message ». Utilisez des files séparées ou des priorités pour que les actions cœur gagnent toujours.

Ignorer le succès partiel

Cas fréquent : une requête réussit (vous avez créé un message), mais la requête suivante reçoit un 429 (vous n'avez pas réussi à récupérer l'historique). Si vous traitez toute l'opération comme échouée, vous risquez des doublons, des mises à jour UI manquantes ou un état incohérent.

Traitez chaque appel comme une étape indépendante. Sauvez ce qui a réussi, retentez seulement ce qui a échoué.

Erreurs génériques qui apprennent aux utilisateurs à cliquer plus

« Quelque chose s'est mal passé » pousse les gens à taper encore sur le bouton, ce qui crée plus de charge. Affichez un état spécifique comme : « Nous attendons le fournisseur. Nouvelle tentative dans 8 secondes. »

Checklist rapide avant le déploiement

Avant la mise en production, considérez la gestion des 429 comme une feature produit, pas juste une boucle de retry. Un bon dispositif contrôle les coûts, évite les pannes surprises et fait que l'app paraît calme même quand le fournisseur dit « ralentissez ».

Une checklist pratique avant release :

  • La concurrence est limitée à deux niveaux : par fonctionnalité (par exemple, chat) et par utilisateur (pour qu'un utilisateur occupé ne prive pas les autres).
  • Les retries ont des limites claires : nombre max de tentatives et temps total max passé en retry (pour que les requêtes ne restent pas pendantes pour toujours).
  • Le backoff réduit la pression : vous ajoutez du jitter, vous respectez les indices serveur comme Retry-After, et vous évitez des retries synchronisés entre de nombreux utilisateurs.
  • L'UI reste prévisible : les utilisateurs voient ce qui se passe ("En attente de retry"), combien de temps cela pourrait prendre et une action sûre (Annuler, Réessayer ou Continuer sans ce résultat).
  • Les logs suffisent pour un debug rapide : incluez le nom du fournisseur, endpoint/model, request ID, user ID (ou token anonyme), numéro de tentative, temps d'attente choisi et la payload d'erreur exacte.

Faites un test de tempête avant de livrer. Ouvrez l'app dans deux navigateurs, déclenchez 10–20 actions rapidement et confirmez que vous voyez un enchaînement ordonné, des délais croissants et un arrêt propre quand les limites sont atteintes.

Exemple : une fonctionnalité de chat touchée par un pic soudain

Arrêtez les 429 en production
Obtenez un audit gratuit de votre code généré par l'IA et un plan de correction clair.

Imaginez une démo d'équipe : quelqu'un partage un lien et, en une minute, 50 personnes ouvrent le chat et envoient le même prompt. Votre appli envoie 50 appels presque identiques à un fournisseur LLM. Quelques secondes plus tard, vous commencez à recevoir des 429.

Sans contrôles, tout paraît aléatoire. Certaines requêtes expirent, d'autres retentent immédiatement et sont à nouveau bloquées, et les utilisateurs cliquent Send encore et encore. Vous obtenez des duplications, des coûts plus élevés et des sorties incohérentes (une personne voit une réponse, une autre une erreur, une troisième deux réponses).

Une file d'attente change la forme du trafic. Au lieu de surcharger le fournisseur, vous alignez les requêtes et les libérez à un rythme régulier. Ajoutez des priorités pour que l'app reste réactive : actions critiques UI comme annuler un message, charger l'historique ou récupérer le profil passent avant la génération.

Le backoff vous empêche d'aggraver la situation quand le fournisseur repousse déjà. Quand vous obtenez un 429, vous retentez après un délai croissant (backoff exponentiel) plus un petit aléa (jitter). Cela empêche les 50 clients de retenter exactement au même instant et de se heurter à nouveau.

Ce que voient les utilisateurs compte autant que le code. Pendant le pic, une UI prévisible pourrait afficher :

  • « En file » avec une estimation (par ex. 20–40s)
  • Un bouton Annuler clair qui arrête réellement le job en file
  • Une option Réessayer seulement après un échec, pas pendant l'attente normale
  • Un message unique par prompt (pas de duplications), passant de En file à Envoi à Terminé

Prochaines étapes : implémentez le minimum, puis rendez-le fiable

Commencez par une page qui décrit vos règles : quand vous retentez, combien de temps vous attendez, quand vous arrêtez, et ce que voit l'utilisateur à chaque étape. Cela évite le désordre courant où le backend retrye indéfiniment tandis que l'UI semble figée.

Si vous ne faites que deux tâches d'ingénierie cette semaine, faites-les dans l'endroit le plus petit qui arrête la douleur : le client partagé unique qui parle à votre fournisseur. Centraliser la gestion des 429 profite à toutes les fonctionnalités et évite d'avoir cinq comportements de retry différents dans l'app.

Un ordre pratique qui fonctionne souvent :

  • Définir une politique de retry (nombre max, temps max, et quelles erreurs sont retryables)
  • Ajouter une file de requêtes pour lisser les pics des clics utilisateurs et des jobs en arrière-plan
  • Ajouter un backoff exponentiel avec jitter pour que les retries réduisent la pression au lieu de l'augmenter
  • Ajouter des états utilisateurs clairs : en attente, retrying, et une solution de secours sûre quand vous abandonnez
  • Logger chaque 429 avec le délai choisi pour identifier les motifs plus tard

Ensuite, lancez un petit test de charge. Simulez 20–50 actions rapides (envoyer message, régénérer, rafraîchir des données) et forcez quelques 429. Le but n'est pas la vitesse parfaite. C'est que l'UI reste compréhensible : les utilisateurs doivent voir que l'app attend, pas qu'elle est cassée, et savoir ce qui se passe ensuite.

Si vous héritez d'une base de code générée par l'IA, faites attention à ne pas empiler des patchs. C'est comme ça qu'on obtient des tempêtes de retry et des requêtes fantômes qui tournent après que l'utilisateur ait navigué ailleurs.

Si vous voulez une seconde paire d'yeux, FixMyMess (fixmymess.ai) se concentre sur le diagnostic et la réparation d'apps générées par l'IA qui s'effondrent sous trafic réel, y compris les retries hors de contrôle, les caps manquants et le fan-out désordonné des requêtes. Un audit rapide peut vous aider à retrouver un comportement prévisible rapidement.

Questions Fréquentes

Que signifie vraiment une erreur 429 ?

Un 429 signifie que le fournisseur vous limite parce que trop de requêtes sont arrivées en peu de temps. Votre code peut être correct, mais votre modèle de trafic (pics, forte concurrence ou appels supplémentaires cachés) dépasse une quota ou une capacité.

Que doit faire mon appli quand elle reçoit un 429 ?

Par défaut, attendez et retentez avec un délai — n'essayez pas immédiatement. Donnez une courte fenêtre pour les actions déclenchées par l'utilisateur et une fenêtre plus longue pour les tâches en arrière-plan, et arrêtez les retries une fois le budget atteint pour que l'application ne tourne jamais indéfiniment.

Pourquoi recommander le backoff exponentiel et le jitter ?

Le backoff exponentiel augmente le délai entre chaque tentative, ce qui réduit la pression quand le fournisseur est surchargé. Le jitter ajoute un petit aléa pour éviter que beaucoup de clients retentent exactement au même moment et causent une nouvelle vague de 429.

Dois-je suivre l'en-tête Retry-After ?

Traitez Retry-After comme l'instruction principale sur la durée d'attente. Si vous ajoutez du jitter, gardez-le faible autour de cette valeur pour respecter le timing du fournisseur tout en évitant des retries synchronisés.

Ai-je vraiment besoin d'une file d'attente, ou puis-je juste retenter ?

Une file d'attente lisse les pics en transformant « 50 requêtes maintenant » en un flux contrôlé que le fournisseur peut absorber. Elle donne aussi un endroit pour gérer priorités, délais et persistance afin que les requêtes ne disparaissent pas ou ne se dupliquent pas au redémarrage.

Comment choisir une limite de concurrence sûre ?

Commencez par une limite de concurrence basse (souvent 1–3 par worker ou par fonctionnalité) et augmentez seulement après avoir observé des résultats stables en conditions proches de la production. Le bon chiffre est le maximum qui n'entraîne pas de 429 fréquents lors des pics normaux.

Quand les retries sont-ils dangereux et comment les rendre sûrs ?

Les retries sont sûrs seulement pour les requêtes idempotentes, comme les lectures ou les écritures protégées par une clé d'idempotence. Si une répétition peut créer des doublons (paiements, emails, enregistrements), rendez l'opération idempotente d'abord ou échouez rapidement et demandez la confirmation utilisateur.

Dois-je dédupliquer des prompts ou appels API identiques ?

Oui : si vous observez des requêtes identiques envoyées très proches dans le temps, renvoyez le résultat en cours à tous les appelants au lieu de lancer de nouveaux appels. Cela réduit le trafic causé par les double-clics ou les rerenders frontend et évite souvent des 429 lors des pics.

Que doivent voir les utilisateurs pendant qu'une requête attend ou retente ?

Affichez des états clairs et simples comme « En file », « Nouvelle tentative dans X secondes » et un « Réessayer » explicite quand vous abandonnez. L'important est que l'interface reconnaisse l'action immédiatement et explique ce qui se passe pour que les utilisateurs n'appuient pas de nouveau et n'ajoutent de charge.

Que dois-je logger et mesurer pour corriger durablement les 429 ?

Consignez assez de contexte pour repérer les motifs : quel endpoint/model, quel utilisateur ou workspace, interactif vs background, nombre de tentatives, délai choisi et temps total passé. Si vous héritez d'une base de code générée par l'IA avec des retries sans fin, fan-out d'appels d'outils ou des limites manquantes, FixMyMess peut auditer et corriger ces modes de défaillance rapidement pour que le comportement reste prévisible sous trafic réel.