API Timeout : diagnostiquer les coupures et décider d'un retry sûr
Guide pratique pour localiser un timeout d'API LLM, modifier uniquement la limite responsable et valider la reprise avec un retry sûr.
Sommaire
API Timeout : diagnostiquer les coupures et décider d’un retry sûr
Un API Timeout signifie qu’un participant de la chaîne a cessé d’attendre. Le client a pu échouer à se connecter, un proxy fermer un flux inactif, le délai global de l’application expirer ou la gateway ne pas recevoir la réponse upstream à temps. Le message seul ne prouve pas que le modèle est indisponible.
Avant tout retry, conservez la classe d’exception, le statut HTTP et le body, le temps écoulé, le request ID et la réception éventuelle d’un chunk. Modifiez seulement la limite de la couche confirmée : augmenter tous les délais masque la cause et peut répéter une opération au résultat inconnu.
Si la requête passait par BetterToken, ouvrez le Dashboard avant le retry et rapprochez heure, modèle, statut et usage de Tokens. Vous séparez immédiatement une requête arrivée à l’API d’un échec antérieur à la gateway.
Pourquoi un timeout n’a pas une cause unique
Application / SDK
→ DNS et TCP/TLS
→ proxy d'entreprise ou reverse proxy
→ API gateway
→ modèle upstream
→ réponse streaming vers le client
Le connect timeout couvre DNS, TCP et TLS. Le read ou stream-idle timeout signifie qu’aucun chunk suivant n’est arrivé dans le délai client. Le pool timeout survient en attendant une connexion libre. La deadline globale limite toute l’opération métier, tandis que l’upstream timeout appartient séparément à la gateway ou au fournisseur. Modifier l’un ne prolonge pas les autres.
Localiser la couche de coupure
| Signal | Couche probable | Vérification suivante |
|---|---|---|
httpx.ConnectTimeout, aucune réponse HTTP | DNS, TCP ou TLS | Reproduire depuis le même environnement ; comparer DNS, CA, proxy et pare-feu |
httpx.ReadTimeout avant ou entre chunks | Read/idle client ou proxy intermédiaire | Mesurer premier octet et intervalles ; vérifier les limites idle du proxy |
| Statut HTTP et body présents | Gateway ou upstream | Conserver statut, body et request ID ; suivre le contrat d’erreur du fournisseur |
httpx.PoolTimeout | Pool client | Mesurer concurrence et occupation ; changer les limites seulement si la saturation est confirmée |
| Annulation après une durée totale fixe | Application, job runner ou reverse proxy | Identifier le propriétaire de la deadline et comparer les timers inférieurs |
Procédez dans cet ordre : conservez le signal, reproduisez depuis le même hôte ou conteneur, inspectez chaque proxy intermédiaire, puis évaluez gateway ou upstream. Gardez modèle, prompt, réseau, endpoint et proxy constants ; ne changez qu’une variable par test.
HTTPX documente des timeouts connect, read, write et pool distincts. Les valeurs concrètes ne sont pas universelles : elles doivent venir des mesures, des pauses attendues entre chunks et de la deadline globale.
Quand modifier timeout, sortie ou retry
- Modifier connect timeout seulement si DNS/TCP/TLS est confirmé trop lent.
- Modifier read ou idle timeout si la connexion existe et qu’une limite intermédiaire confirmée expire entre chunks.
- Allonger la deadline globale seulement si l’opération peut durer plus et que les couches inférieures fonctionnent.
- Réduire ou découper la sortie lorsque seul le test long contrôlé échoue ; ne pas l’affirmer sans mesure.
- Traiter
429et le dépassement de contexte séparément : ce ne sont pas des connect timeout.
Retry sûr sans dupliquer une opération inconnue
Après l’envoi, un timeout est d’abord un résultat inconnu. Un task ID local aide à corréler les logs mais n’empêche pas une seconde opération serveur. Retentez automatiquement seulement si une idempotence ou une consultation de statut est documentée et si une preuve externe montre que la première requête n’a pas été acceptée.
Checklist minimale :
- Conserver request ID, statut/body, timestamps et chunks reçus.
- Avant de répéter une action non idempotente, vérifier son résultat réel.
- Ne pas rejouer automatiquement un flux partiel : cela peut créer une seconde génération et un usage supplémentaire.
- Limiter tentatives et deadline globale ; additionner les retries du SDK, du proxy et de l’application.
- Capturer aussi les erreurs pendant l’itération SSE, pas seulement lors de la création de la réponse.
Deux tests confirment la correction
- Requête courte : demander une petite réponse et noter statut, premier octet, durée, request ID et fin du flux. En cas d’échec, vérifier connexion, authentification et endpoint.
- Requête longue contrôlée : après succès, augmenter uniquement la sortie attendue ou restaurer la charge initiale. Garder modèle, endpoint, réseau et proxy. Si elle seule échoue, comparer read/idle timeout, deadline et limites intermédiaires.
La correction est confirmée quand le test court et une répétition du scénario initial finissent avec le résultat attendu et sans doublon inexpliqué. Si la requête a atteint BetterToken, rapprochez dans le Dashboard l’heure, le modèle, le statut et l’usage de Tokens, puis vérifiez le contrat de l’endpoint.