
Timeout en APIs de IA: causas, patrones de reintento y diseño de fallback

Tu solicitud a la API de IA ha dado timeout. Pero "timeout" no es un solo problema — son al menos cuatro problemas distintos disfrazados con el mismo mensaje de error.
Un modelo de texto que da timeout a los 30 segundos es un problema diferente a un trabajo de generación de video que da timeout a los 5 minutos. Corregir el tipo equivocado desperdicia tiempo de ingeniería y puede empeorar el problema.
Esta guía te ayuda a diagnosticar qué tipo de timeout enfrentas y a elegir el patrón de respuesta adecuado.
Resumen
- Los timeouts en APIs de IA tienen diferentes causas raíz: latencia del modelo, cola del proveedor, entrada grande o problemas de red.
- Los timeouts de modelos de texto y los de generación de video/imagen requieren estrategias de manejo distintas.
- No reintentar a ciegas — algunos timeouts significan que la solicitud aún se está procesando.
- Para tareas de larga duración (video, imagen), usa patrones asíncronos en vez de esperar respuestas síncronas.
- Diseña el fallback antes de necesitarlo: un timeout más corto con modelo de respaldo suele ser mejor que un timeout largo sin fallback.
Tabla de diagnóstico de timeouts
Usa esta tabla para identificar tu tipo de timeout antes de elegir una solución:
| Tipo de timeout | Duración típica | Causa raíz | Cómo verificar | Respuesta correcta |
|---|---|---|---|---|
| Modelo de texto — respuesta lenta | 15–60 s | Entrada grande, razonamiento complejo o muchos tokens de salida | Verificar tamaño de entrada y max_tokens | Reducir entrada, bajar max_tokens o cambiar a un modelo más rápido |
| Modelo de texto — proveedor sobrecargado | 30–120 s | Proveedor bajo carga alta; solicitudes en cola | Probar la misma solicitud en horario de baja demanda | Reintentar con backoff o enrutar a otro proveedor |
| Generación de video/imagen — procesamiento normal | 60–300 s+ | La generación requiere tiempo por diseño (especialmente video) | Consultar la documentación del proveedor para tiempos esperados | Usar polling asíncrono, no espera síncrona |
| Generación de video/imagen — acumulación en cola | 300 s+ | Demasiados trabajos en la cola del proveedor | Verificar estado o posición en la cola del proveedor | Implementar gestión de cola, establecer expectativas del usuario o usar otro proveedor |
| Timeout de red | Variable | DNS, firewall, proxy o problemas de conectividad | Probar con una solicitud simple de health-check | Corregir la configuración de red, no la llamada a la API |
| Timeout del cliente demasiado corto | Fijo por configuración | El timeout de tu cliente HTTP es menor al que necesita el modelo | Aumentar la configuración de timeout y probar de nuevo | Ajustar el timeout del cliente al tiempo de respuesta esperado |
Patrón 1: Manejo de timeouts en modelos de texto
Los timeouts en modelos de texto generalmente son causados por una de tres cosas:
1.1 Entrada grande o max_tokens alto
max_tokens permiten una generación más larga, lo que requiere más tiempo.# Problema: entrada grande + max_tokens alto = respuesta lenta
response = client.chat.completions.create(
model="gpt-4o",
messages=very_long_messages, # 100K+ tokens
max_tokens=4096 # Solicitando salida larga
)
# Solución: reducir entrada o limitar salida
response = client.chat.completions.create(
model="gpt-4o",
messages=trimmed_messages, # Reducido a 50K tokens
max_tokens=1024 # Salida más corta
)1.2 Proveedor bajo carga
Durante picos de uso, los proveedores pueden poner tu solicitud en cola. Esto se manifiesta como un timeout en lugar de un mensaje explícito de cola.
- La misma solicitud funciona bien en horarios de baja demanda
- El error es intermitente, no consistente
- Otros usuarios reportan problemas similares al mismo tiempo
- Reintentar con backoff aleatorio (jitter)
- Enrutar a un proveedor o modelo alternativo
- Usar streaming para obtener resultados parciales más rápido
1.3 Streaming como mitigación de timeouts
El streaming no acelera la generación, pero empieza a devolver tokens antes. Esto puede evitar que se disparen los timeouts del lado del cliente:
# Síncrono — el cliente puede dar timeout esperando la respuesta completa
response = client.chat.completions.create(
model="gpt-4o",
messages=messages,
max_tokens=2048
)
# Streaming — el primer token llega más rápido, mantiene la conexión activa
stream = client.chat.completions.create(
model="gpt-4o",
messages=messages,
max_tokens=2048,
stream=True
)
for chunk in stream:
if chunk.choices[0].delta.content:
print(chunk.choices[0].delta.content, end="")Patrón 2: Manejo de timeouts en generación de video/imagen
La generación de video e imagen es fundamentalmente diferente al texto. Tiempos de generación de 30 segundos a varios minutos son normales, no errores.
2.1 Generación síncrona vs asíncrona
| Enfoque | Cómo funciona | Cuándo usarlo |
|---|---|---|
| Síncrono | Esperar la respuesta completa en una sola llamada HTTP | Generaciones rápidas (< 30 s), integraciones simples |
| Polling asíncrono | Enviar trabajo → obtener ID → consultar estado → obtener resultado | Generación de video, procesamiento por lotes, cualquier tarea > 30 s |
| Webhooks | Enviar trabajo → el proveedor llama a tu endpoint cuando termina | Pipelines de alto volumen, arquitecturas dirigidas por eventos |
2.2 Patrón de polling asíncrono
import asyncio
import httpx
async def generate_video_async(client, prompt: str, timeout: int = 600):
"""Enviar un trabajo de generación de video y consultar hasta completarse."""
# Paso 1: Enviar el trabajo
submit_response = await client.post(
"/v1/video/generations",
json={"model": "veo-3-fast", "prompt": prompt}
)
job_id = submit_response.json()["id"]
# Paso 2: Consultar hasta completarse
for _ in range(timeout // 5): # Verificar cada 5 segundos
status_response = await client.get(f"/v1/video/generations/{job_id}")
status = status_response.json()
if status["status"] == "completed":
return status["result"]
elif status["status"] == "failed":
raise RuntimeError(f"Generation failed: {status.get('error')}")
await asyncio.sleep(5)
raise TimeoutError(f"Video generation did not complete within {timeout}s")2.3 Conciencia de posición en cola
Cuando un proveedor de generación de video tiene acumulación, tu trabajo espera en cola antes de que comience el procesamiento. Algunos proveedores exponen la posición en la cola:
Status: queued → position 42
Status: queued → position 15
Status: processing → estimated 90s remaining
Status: completed → download URL availableSi el proveedor no expone la posición en la cola, estima basándote en tiempos de espera históricos y establece las expectativas del usuario en consecuencia.
Patrón 3: Lógica de reintento inteligente para timeouts
No todos los timeouts deben reintentarse de la misma manera:
import asyncio
import random
async def retry_with_timeout_awareness(
make_request,
max_retries: int = 3,
base_timeout: float = 30.0
):
"""Reintento con conciencia del tipo de timeout."""
for attempt in range(max_retries):
try:
return await asyncio.wait_for(
make_request(),
timeout=base_timeout * (1.5 ** attempt) # Aumentar timeout en cada reintento
)
except asyncio.TimeoutError:
if attempt == max_retries - 1:
raise
# Agregar jitter para evitar efecto thundering herd
delay = min(30, (2 ** attempt) + random.uniform(0, 1))
await asyncio.sleep(delay)
except Exception as e:
# Errores que no son timeout: no reintentar automáticamente
if "429" in str(e):
delay = min(60, (2 ** attempt) + random.uniform(0, 2))
await asyncio.sleep(delay)
else:
raiseReglas de reintento para diferentes tipos de timeout
| Tipo de timeout | ¿Reintentar? | Cómo |
|---|---|---|
| Modelo de texto lento | Sí | Reintentar con backoff; considerar un modelo más rápido en el reintento |
| Proveedor sobrecargado | Sí, con precaución | Reintentar con backoff más largo; considerar otro proveedor |
| Generación de video aún procesando | No — el trabajo puede seguir ejecutándose | Consultar estado en vez de reenviar |
| Timeout de red | Sí | Corregir red primero; reintentar tras confirmar conectividad |
| Timeout del cliente demasiado corto | No — aumentar el timeout en su lugar | Ajustar configuración, no reintentar |
El error más peligroso es reintentar un trabajo de generación de video que aún se está procesando. Esto crea trabajos duplicados, desperdicia dinero y puede sobrecargar la cola del proveedor.
Patrón 4: Diseño de fallback para producción
Fallback de modelo activado por timeout
async def call_with_fallback(messages, client, primary_model, fallback_model):
"""Intentar modelo primario; en caso de timeout, recurrir a un modelo más rápido."""
try:
return await asyncio.wait_for(
client.chat.completions.create(
model=primary_model,
messages=messages
),
timeout=30.0
)
except asyncio.TimeoutError:
# Recurrir a un modelo más rápido, posiblemente más pequeño
return await client.chat.completions.create(
model=fallback_model,
messages=messages
)Uso de un gateway de enrutamiento para resiliencia ante timeouts
En lugar de implementar lógica de fallback en cada servicio, un gateway de enrutamiento puede manejar los timeouts a nivel de infraestructura:
- Enrutar a proveedores más rápidos cuando las rutas primarias están lentas
- Reintentar automáticamente por una ruta upstream diferente
- Devolver el modelo realmente utilizado para que tu aplicación sepa qué ocurrió
from openai import OpenAI
client = OpenAI(
api_key="your-evolink-key",
base_url="https://api.evolink.ai/v1"
)
# Smart Router maneja la selección de proveedor y el fallback
response = client.chat.completions.create(
model="evolink/auto",
messages=messages
)Referencia de configuración de timeouts
| Configuración | Valor recomendado | Por qué |
|---|---|---|
| Timeout de cliente HTTP (texto) | 60–120 s | Permitir entradas grandes y razonamiento complejo |
| Timeout de cliente HTTP (imagen) | 120–300 s | La generación de imagen varía según modelo y resolución |
| Timeout de cliente HTTP (video) | Usar polling asíncrono | El timeout síncrono no es apropiado para video |
| Intentos de reintento | 2–3 para texto, 0 para video en progreso | Evitar trabajos duplicados de video/imagen |
| Retardo base de backoff | 2 s con jitter | Prevenir thundering herd en la recuperación del proveedor |
| Timeout de cambio a modelo fallback | 15–30 s | Cambiar a modelo más rápido antes de que el usuario se frustre |
Artículos relacionados
- Fix OpenRouter 429 "Provider Returned Error" — cuando el error es rate limiting, no timeout
- Context Length Exceeded in LLM API Calls — cuando una entrada grande causa rechazo en vez de timeout
- How to Reduce 429 Errors in Agent Workloads — gestión de tráfico en ráfaga que genera timeouts
- Best AI API Platform for Production Reliability — elegir una plataforma con failover integrado
FAQ
¿Por qué mi solicitud a la API de IA da timeout aunque el modelo funciona?
Los timeouts generalmente son causados por una de estas razones: (1) una entrada grande que tarda más en procesarse, (2) proveedor bajo carga alta, (3) timeout del cliente configurado demasiado corto, o (4) problemas de red. El modelo en sí puede estar funcionando correctamente.
¿Debería aumentar mi timeout o usar un enfoque diferente?
Depende. Para modelos de texto, aumentar el timeout ayuda con respuestas ocasionalmente lentas. Para generación de video/imagen, cambia a polling asíncrono en vez de aumentar el timeout síncrono. Para timeouts persistentes, investiga la causa raíz antes de aumentar los límites.
¿Un timeout es lo mismo que un error de rate limit?
No. Un timeout significa que el servidor no respondió dentro de tu límite de tiempo. Un rate limit (429) significa que el servidor rechazó activamente tu solicitud. Los timeouts suelen indicar procesamiento lento; los 429 indican demasiadas solicitudes.
¿Cómo manejo los timeouts en la generación de video?
Nunca esperes sincrónicamente la generación de video. Usa envío asíncrono de trabajos con polling o webhooks. Si un trabajo de video da timeout durante el polling, verifica el estado antes de reenviarlo — el trabajo podría seguir procesándose.
¿Puede el streaming prevenir timeouts?
El streaming previene timeouts del lado del cliente porque el primer token llega rápidamente, manteniendo la conexión activa. Sin embargo, el streaming no hace que la generación total sea más rápida — solo cambia el patrón de entrega.
¿Cuándo debería cambiar a un modelo de fallback por timeout?
Establece un umbral (por ejemplo, 15–30 segundos para texto) y cambia a un modelo más rápido cuando el primario dé timeout. Esto da a los usuarios una respuesta en vez de un error. El modelo de respaldo puede ser menos capaz, pero una respuesta algo inferior es mejor que ninguna respuesta.

