Geonode logo
Geonode Team

Geonode Team

Actualizado: 7 de octubre de 2026

Publicado: 2 de septiembre de 2026

Cómo configurar un tiempo de espera con curl (+ejemplos)

Por defecto, curl esperará indefinidamente. No hay un límite de tiempo global integrado, por lo que una solicitud a un servidor que no responde puede quedarse colgada hasta que algo la interrumpa. Hay dos opciones que solucionan esto, y una tercera que cubre el caso que ambas pasan por alto. Esta guía aborda las tres con comandos que funcionan. También aborda la interacción entre los tiempos de espera y los reintentos, algo que sorprende a casi todo el mundo la primera vez que un script tarda diez minutos en fallar.

Una aclaración rápida antes de pasar a los comandos: somos Geonode y vendemos proxies, lo que significa que lo más honesto es decir desde el principio que un tiempo de espera de curl casi nunca se debe a un problema del proxy. Si tus solicitudes agotan el tiempo de espera con un servidor que simplemente es lento, un servidor que está caído o un cortafuegos que descarta paquetes sin avisar, redirigirlas a través de nosotros no cambia nada, salvo la factura. Los proxies ayudan cuando el problema radica en de dónde parece provenir tu solicitud: contenido con restricciones geográficas, límites de velocidad vinculados a tu dirección o una IP que ha sido bloqueada. No hacen que un servidor lento se vuelva rápido. Configura primero tus tiempos de espera correctamente; puede que descubras que nunca has necesitado nada más.

Exacto. Esto es lo que la mayoría de la gente descubre por las malas: curl no tiene un tiempo de espera global por defecto. Tiene un tiempo de espera de conexión por defecto de 300 segundos, pero una vez establecida la conexión, curl esperará alegremente indefinidamente una respuesta que nunca llega por completo. En un script de shell que se ejecuta en cron, eso supone una tarea que nunca termina y un archivo de bloqueo que nadie borra.

Los dos tiempos de espera que importan

Todo lo demás es un matiz de estos dos.

--max-time

(forma abreviada: -m

) limita toda la operación. Según el manual de curl: «Tiempo máximo, en segundos, que se permite que dure la operación de transferencia». Conexión, establecimiento de la conexión, solicitud, respuesta… todo ello. Cuando se alcanza el límite, curl se interrumpe y sale con el código 28.

curl -m 10 https://example.com

Diez segundos en total; tras ese tiempo, curl se da por vencido independientemente de la fase en la que se encuentre.

--connect-timeout

limita únicamente la fase de configuración. El manual es preciso sobre lo que esto incluye: «La fase de conexión se considera completada cuando se han realizado la resolución de DNS y los handshakes solicitados de TCP, TLS o QUIC». Una vez establecida la conexión, esta opción deja de aplicarse.

curl --connect-timeout 3 https://example.com

Tres segundos para resolver el nombre y completar los handshakes. A partir de ahí, curl espera el tiempo que tarde la transferencia.

En la práctica, lo ideal es utilizar ambas, ya que responden a cuestiones diferentes:

OpciónAbarcaValor típicoContra qué protege
--connect-timeout

| DNS + protocolo de enlace TCP/TLS/QUIC | 3–10 s | Hosts inactivos, paquetes perdidos, fallos de DNS | | --max-time

| Toda la operación | 10–60 s, dependiendo de la carga de trabajo | Respuestas lentas, transferencias bloqueadas, flujos interminables |

En conjunto:

curl --connect-timeout 5 -m 30 https://example.com

Cinco segundos para conectarse, treinta segundos para todo el proceso. Si no se puede acceder al servidor, el proceso falla en cinco segundos en lugar de en treinta, lo cual es muy importante cuando se recorre una lista de mil URL.

Elegir valores que no sean meras suposiciones

El enfoque habitual consiste en elegir una cifra redonda y aumentarla cada vez que algo falla. Esto hace que el valor se acerque a una cifra tan elevada que el tiempo de espera ya no sirve para nada.

Hay un método mejor que requiere un comando adicional. «curl» puede indicar dónde se ha gastado realmente el tiempo:

curl -o /dev/null -s -w "dns: %{time_namelookup}\nconnect: %{time_connect}\ntls: %{time_appconnect}\nttfb: %{time_starttransfer}\ntotal: %{time_total}\n" https://example.com

Ejecuta esa orden en tu destino real veinte o treinta veces y obtendrás una distribución en lugar de una estimación. A continuación:

Establece --connect-timeout según time_appconnect. Toma el p95 y duplícalo aproximadamente. El tiempo de conexión viene determinado por los tiempos de ida y vuelta de la red y es bastante estable; si tarda el doble de lo habitual, es que hay un problema real y no solo una ralentización.

Establece --max-time desde time_total. Aquí el multiplicador debería ser más generoso —entre tres y cinco veces el p95—, ya que el tiempo total depende del tamaño de la respuesta y de la carga del servidor, factores que varían de forma legítima. Un --max-time demasiado ajustado da lugar a scripts inestables que fallan en días en los que el servicio ya de por sí funciona mal.

Dos ajustes específicos para la carga de trabajo. Si estás descargando archivos grandes, --max-time no es en absoluto la herramienta adecuada, ya que una descarga legítima puede superar cualquier límite fijo razonable; en su lugar, utiliza la opción basada en la velocidad que se indica a continuación. Y si estás llamando a una API que realiza un trabajo real del lado del servidor, averigua cuál es su propio tiempo de espera y establece el tuyo ligeramente por encima; si se agota el tiempo de espera a los 10 segundos con un servicio que tarda 12 en responder, significa que pagas por el trabajo y descartas el resultado.

Precisión en fracciones de segundo y milisegundos

Ambas opciones admiten decimales, utilizando un punto como separador independientemente de la configuración regional. Esta función está disponible desde la versión 7.32.0 de curl.

curl --connect-timeout 0.5 -m 2.5 https://example.com

Medio segundo para conectarse, dos segundos y medio en total. Resulta útil para comprobaciones de estado y para cualquier bucle en el que se acumule un segundo completo de espera por cada fallo.

Una advertencia que conviene tener en cuenta: la precisión disminuye a medida que aumenta el valor. La documentación de curl señala que la precisión del tiempo de espera real disminuye a medida que aumenta la precisión decimal del tiempo de espera especificado. Escribir --max-time 30.001 no supone una diferencia significativa respecto a --max-time 30. Los decimales se utilizan para valores inferiores a un segundo; por encima de unos pocos segundos, utiliza números enteros.

La opción relacionada --expect100-timeout también admite decimales. Controla cuánto tiempo espera curl a que se produzca un «100 Continue» antes de enviar el cuerpo de la solicitud; el valor por defecto es de un segundo. Si estás enviando cuerpos de gran tamaño mediante POST a un servidor que nunca devuelve un «100 Continue», estás pagando ese segundo en cada solicitud; reduce ese tiempo o desactiva la expectativa con -H "Expect:".

Detectar transferencias atascadas que nunca agotan el tiempo de espera

Aquí está el problema. Una transferencia que envía un byte cada pocos segundos nunca está inactiva, por lo que no se activa ningún tiempo de espera a nivel de conexión, y si el valor de «--max-time

» está configurado lo suficientemente alto como para descargas grandes legítimas, tampoco se activará. La solicitud simplemente avanza a paso de tortuga.

Las opciones --speed-limit

y --speed-time

se encargan de esto. Según el manual: «Si una descarga es más lenta que --speed-limit

bytes por segundo durante un periodo de --speed-time

, la transferencia se interrumpe».

curl --speed-limit 1000 --speed-time 30 -O https://example.com/large-file.zip

Si el rendimiento se mantiene por debajo de los 1000 bytes por segundo durante 30 segundos consecutivos, curl la interrumpe —de nuevo con el código de salida 28—. Una descarga que se ejecuta durante seis horas a un ritmo adecuado no se ve afectada. Una descarga que se atasca se interrumpe en treinta segundos.

Este es el tiempo de espera adecuado para cualquier elemento de tamaño impredecible, y se integra bien:

curl --connect-timeout 5 --speed-limit 1000 --speed-time 30 -O https://example.com/large-file.zip

Fallo rápido en un servidor inactivo, sin límite global, pero con un detector de atascos en todo momento. En el caso concreto de las descargas de archivos, este patrón debe incluirse en todos los scripts; consulta nuestra guía sobre descarga de archivos con curl para conocer las opciones relacionadas.

Los tiempos de espera y los reintentos interactúan mal de forma predeterminada

Esta es la parte que suele despistar a la gente. La opción «

--retry N

» hace que curl reintente los errores transitorios hasta N veces. Lo que es fácil pasar por alto es que «--max-time

» se aplica a cada intento, no al comando en su conjunto, y que curl espera entre intentos con un retroceso exponencial que empieza en un segundo y se duplica.

Así que esto:

curl -m 10 --retry 5 https://example.com

puede tardar perfectamente más de un minuto: cinco intentos de hasta diez segundos cada uno, más esperas de retroceso de 1, 2, 4, 8 y 16 segundos. Si lo escribiste esperando un límite máximo de diez segundos, te equivocaste por un factor de seis.

--retry-max-time

es la solución. Limita el tiempo total dedicado a los reintentos:

curl -m 10 --retry 5 --retry-max-time 40 https://example.com

Ahora curl deja de iniciar nuevos intentos una vez transcurridos 40 segundos. Fíjate en la formulación: no iniciará un nuevo reintento tras el límite, pero un intento ya en curso se ejecutará hasta su propio --max-time

. El peor caso real es --retry-max-time

más un --max-time

.

--retry-delay

sustituye el retroceso exponencial por una espera fija, lo que hace que el tiempo de ejecución total sea predecible:

curl -m 10 --retry 3 --retry-delay 2 --retry-max-time 40 https://example.com

Hay otra opción que conviene conocer: por defecto, --retry

solo se activa en un conjunto reducido de condiciones transitorias. --retry-all-errors

amplía considerablemente este conjunto; el manual lo describe como un reintento de «todos los errores transitorios, incluidos los códigos de respuesta FTP 4xx y 5xx». Resulta realmente útil en scripts con redes inestables y realmente peligroso ante un POST no idempotente. Piénsalo bien antes de añadirlo.

Tiempos de espera al conectarse a través de un proxy

Añade -x

y los tiempos cambian, ya que ahora hay dos conexiones en lugar de una: la tuya con el proxy y la del proxy con el destino.

curl -x http://user:pass@proxy.example.com:9000 --connect-timeout 10 -m 45 https://example.com

Hay tres aspectos que se comportan de forma diferente respecto al caso directo.

**--connect-timeout

mide el tiempo de tu salto hasta el proxy, no el salto del proxy hasta el destino.** En el caso de HTTPS, curl emite un comando «CONNECT

» y el proxy establece la conexión posterior; el tiempo que tarda cuenta para --max-time

, no para --connect-timeout

. Por lo tanto, un tiempo de espera de conexión corto no te protegerá frente a un proxy que acepte tu conexión rápidamente y luego tarde veinte segundos en llegar al destino.

Los proxies residenciales son más lentos, y con razón. El tráfico sale a través de una conexión de usuario real, por lo que unos cientos de milisegundos adicionales son normales y no constituyen un fallo. Los valores de tiempo de espera ajustados para una conexión directa producirán fallos que parecen proxies defectuosos, pero que en realidad se deben simplemente a la física. Realiza mediciones a través del proxy con el comando «-w

» mencionado anteriormente y establece los valores a partir de esa medición, no a partir de tus cifras de conexión directa.

Los fallos son ambiguos. Un código de salida 28 a través de un proxy podría significar que el proxy es lento, que el destino es lento o que el destino está retrasando deliberadamente tu solicitud. Distinguirlos requiere probar los componentes por separado, lo cual es un tema lo suficientemente amplio como para que hayamos escrito una guía aparte sobre cómo probar proxies.

Un patrón práctico para las solicitudes a través de un proxy: un «--connect-timeout

» generoso (10 s), un «--max-time

» establecido en función del comportamiento medido y no de conjeturas, y nada de «--retry-all-errors

», ya que, a través de un proxy, un error 5xx suele significar que el destino te está rechazando, en lugar de estar pasando por un mal momento, y volver a intentarlo solo empeora la situación.

Interpretación del código de salida

El código de salida de curl indica en qué fase se ha producido el error, lo que supone más información de la que la mayoría de los scripts se molestan en utilizar.

CódigoNombreSignificado
6CURLE_COULDNT_RESOLVE_HOSTError de DNS — sin tiempo de espera
7CURLE_COULDNT_CONNECT«Error al llamar a connect() al host o al proxy»
28CURLE_OPERATION_TIMEDOUT«Se ha alcanzado el tiempo de espera especificado»
56CURLE_RECV_ERRORError al recibir datos de red: la conexión se interrumpió durante la transferencia

Las descripciones proceden de la referencia de errores de libcurl.

La distinción entre el 7 y el 28 es la más útil. El código 7 significa que la conexión fue rechazada de forma activa: se recibió una respuesta que decía «no» rápidamente. El código 28 significa que no se recibió ninguna respuesta a tiempo. El primero suele indicar un puerto incorrecto o un servicio cerrado; el segundo indica un paquete perdido, un cortafuegos que filtra de forma silenciosa o un host realmente sobrecargado. Reintentar es razonable en el caso del 28 y, por lo general, no tiene sentido en el del 7.

En un script:

curl --connect-timeout 5 -m 30 -sS https://example.com > out.txt
case $? in
  0)  echo "ok" ;;
  6)  echo "dns failure" ;;
  7)  echo "connection refused" ;;
  28) echo "timed out" ;;
  *)  echo "other failure" ;;
esac

Ten en cuenta que los tres mecanismos de tiempo de espera —--max-time, --connect-timeout y el par de límites de velocidad— devuelven el código 28. El código de salida te indica que se ha alcanzado un límite, pero no cuál. Si necesitas saberlo, utiliza -w "%{time_total}" y compáralo con los valores que tengas configurados.

Cuándo no establecer un tiempo de espera

Aunque vaya en contra de lo que se suele aconsejar, hay casos en los que el tiempo de espera no es la solución adecuada.

Descargas interactivas. Si estás escribiendo un comando curl en una terminal para descargar un archivo grande, tú mismo eres el tiempo de espera. Puedes ver la barra de progreso y pulsar Ctrl+C. Añadir «-m» aquí solo provoca la molestia de que la descarga se interrumpa al 90 %.

Flujos de larga duración. Eventos enviados por el servidor, seguimiento de registros, respuestas fragmentadas que permanecen abiertas por diseño: «--max-time» las interrumpirá exactamente en el momento menos oportuno. Utiliza «--speed-limit» y «--speed-time» si necesitas un detector de retrasos, o no utilices nada en absoluto.

Cualquier cosa que ya esté sujeta a un límite externo. Si curl se ejecuta bajo timeout(1), una unidad de systemd con RuntimeMaxSec o un paso de CI con su propio presupuesto, una segunda capa no aporta nada más que un segundo número con el que hay que mantenerse sincronizado. Elige la capa que genere el mensaje de error que quieras leer y configúralo allí.

Como solución para un destino lento. Un tiempo de espera hace que una solicitud lenta falle más rápido. No hace que tenga éxito. Si tu verdadero problema es que un servidor tarda 40 segundos en responder, las opciones son el almacenamiento en caché, la paginación, un punto final diferente o hablar con quien lo gestione —y aquí es donde repetiremos la advertencia del principio, ya que es el motivo más habitual por el que la gente compra proxies y una de las pocas cosas que los proxies no pueden resolver en absoluto. Nuestras tarifas empiezan en 0,79 $/GB para el tráfico residencial y 0,14 $/GB para el de centros de datos, según datos de septiembre de 2026, y ninguna de ellas acelerará un servidor de origen lento.

Preguntas frecuentes

¿Cuál es el tiempo de espera predeterminado en curl?

No hay un tiempo de espera general predeterminado: curl espera indefinidamente una respuesta una vez conectada. La fase de conexión sí tiene un valor predeterminado de 300 segundos. Por eso es importante el parámetro -m en los scripts: sin él, una solicitud bloqueada bloquea el script.

¿Cuál es la diferencia entre --max-time y --connect-timeout?

--connect-timeout solo cubre la resolución de DNS y los handshakes de TCP/TLS/QUIC, y deja de aplicarse una vez establecida la conexión. --max-time cubre toda la operación de principio a fin, incluida la transferencia de la respuesta. Utiliza ambos: un tiempo de espera de conexión corto para detectar rápidamente los fallos en hosts inactivos, y un tiempo máximo más largo como límite general.

¿Por qué mi comando curl tarda más de lo que he establecido como tiempo de espera?

Casi siempre se deben a los reintentos. --max-time se aplica por intento, y --retry añade tanto intentos adicionales como un retroceso exponencial entre ellos. Añade --retry-max-time para limitar el total, y recuerda que, en el peor de los casos, ese valor se incrementará en uno más: --max-time.

¿Cómo configuro un tiempo de espera de curl en milisegundos?

Utiliza un valor decimal: --connect-timeout 0.25 equivale a 250 milisegundos. Tanto --max-time como --connect-timeout aceptan decimales con un punto como separador, una característica compatible desde la versión 7.32.0 de curl. La precisión es óptima por debajo de unos pocos segundos; para valores mayores, la exactitud de la parte fraccionaria se reduce.

¿Qué código de salida devuelve curl al agotarse el tiempo de espera?

28, CURLE_OPERATION_TIMEDOUT. Los tres mecanismos de tiempo de espera lo devuelven, por lo que el código indica que se ha alcanzado un límite, pero no especifica cuál. Compáralo con el 7 (conexión rechazada) y el 6 (error de DNS), que tienen un significado diferente y, por lo general, no deben reintentarse.

¿Cómo puedo establecer un tiempo de espera para una descarga lenta sin interrumpir archivos de gran tamaño?

Utiliza --speed-limit y --speed-time en lugar de --max-time. Solo se interrumpen cuando el rendimiento se mantiene por debajo de un umbral durante un periodo prolongado, por lo que una descarga legítima de varias horas no se ve afectada, mientras que una que se ha estancado se interrumpe rápidamente.

¿Funcionan los tiempos de espera de forma diferente a través de un proxy?

Sí. --connect-timeout mide únicamente tu conexión al proxy; la conexión posterior del proxy al destino se tiene en cuenta en --max-time. Los proxies residenciales también añaden una latencia real, por lo que los valores ajustados para conexiones directas producirán falsos fallos. Realiza la medición a través del proxy y establece los valores a partir de ahí.

¿Puedo establecer un tiempo de espera solo para la resolución de DNS?

No como opción independiente: el DNS está incluido en --connect-timeout. Si necesitas limitar específicamente el DNS, resuelve la dirección por separado y pasa el resultado con --resolve, lo que omite por completo la propia búsqueda de curl.

Conclusión

Hay dos opciones que cubren casi todos los casos: «--connect-timeout» para un fallo rápido cuando no se puede acceder a un host, y «--max-time» para el límite máximo general. Configura ambas opciones en todos los scripts, siempre. El valor por defecto, que consiste en esperar indefinidamente, es una opción razonable para una herramienta interactiva, pero pésima para la automatización.

Vale la pena repetir los dos aspectos que suelen confundir a la gente. --max-time se aplica por intento, por lo que cualquier uso de --retry requiere --retry-max-time junto a él; de lo contrario, tu comando de diez segundos se convertirá en uno de un minuto. Además, un límite de tiempo fijo no es la herramienta adecuada para transferencias de tamaño impredecible: utiliza --speed-limit junto con --speed-time y obtendrás un detector de atascos que no interferirá en las descargas largas legítimas.

Establece los valores a partir de mediciones, en lugar de basarte en una cifra redonda que te parezca adecuada. Una ejecución de curl -w con tu objetivo real te proporciona una distribución, y un tiempo de espera derivado de dicha distribución fallará cuando haya un problema real, en lugar de hacerlo cada vez que la red tenga una mala tarde cualquiera.