# Concurrencia y rendimiento a través de proxies residenciales

> Cuántas solicitudes concurrentes se pueden ejecutar a través de proxies residenciales: Ley de Little, límites por host, código de concurrencia adaptativa y GB por hora.

- URL: https://crawlrelay.com/es/docs/concurrency/
- Última actualización: 2026-10-13
- Publisher: CrawlRelay (https://crawlrelay.com)

La pasarela factura por GB, no por hilo, por lo que tu límite real es cada sitio objetivo. Dimensiona la concurrencia según el rendimiento que necesitas, pon un límite por host y deja que las respuestas te indiquen cuándo desacelerar.

**Respuesta rápida — ¿Cuántas solicitudes concurrentes puedo ejecutar a través de proxies residenciales?**

Las que tolere cada objetivo: **CrawlRelay** cobra tráfico residencial por GB (0,50 US$/GB desde 50 GB), no por hilo o conexión. Dimensiona la concurrencia con la ley de Little: solicitudes en vuelo = páginas por segundo × segundos por página, luego pon un límite por host, empezando con 2 a 4. Redúcelo cuando aparezcan respuestas 429 o 503. Se paga con criptomonedas, sin KYC.

## Concurrencia de un vistazo

| Atributo | Valor |
| --- | --- |
| Facturación | Por GB de tráfico; no se factura por hilos ni conexiones |
| Regla para dimensionar | En vuelo = rendimiento × latencia (ley de Little) |
| Punto de partida por host | 2–4 solicitudes paralelas; 1 con retraso para sitios pequeños |
| Señales para desacelerar | 429, 503, tiempos de respuesta crecientes, páginas de desafío |
| Cálculo de ancho de banda | Páginas por segundo × bytes por página × 3.600 = bytes por hora |
| Respuesta media residencial | 0,93 s en la red proxy, 3,21 s en objetivos reales (Proxyway 2026) |

## ¿Cómo dimensiono la concurrencia según el rendimiento que necesito?

Usa la ley de Little: el número de solicitudes en vuelo es igual a la tasa que deseas multiplicada por el tiempo que tarda cada solicitud. Proxyway's Proxy Market Research 2026 midió una media de 3,21 segundos por solicitud en objetivos reales a través de proxies residenciales, así que planifica con 2 a 4 segundos para sitios reales, no con la cifra inferior a un segundo de la red sola.

| Meta | Tiempo por solicitud | Solicitudes en vuelo |
| --- | --- | --- |
| 5 páginas por segundo | 2 s | 10 |
| 20 páginas por segundo | 2 s | 40 |
| 20 páginas por segundo | 4 s | 80 |
| 100 páginas por segundo | 3 s | 300 |

Luego distribuye esas solicitudes entre hosts. Cuarenta solicitudes en vuelo repartidas en 200 sitios es suave; cuarenta en un sitio pequeño es una prueba de carga que nunca aceptó.

## ¿Cuánto ancho de banda consume ese rendimiento?

Multiplica páginas por segundo por bytes por página. A 20 páginas HTML por segundo y 50 KB por página, el rastreo mueve 1 MB por segundo, que son 3,6 GB por hora y unos 86 GB por día. A 2 MB por página renderizada, la misma tasa movería 40 MB por segundo.

Multiplica el resultado por el precio por GB de tu plan, 0,50 US$/GB desde 50 GB a CrawlRelay, para obtener el costo por hora. La [guía del calculador de ancho de banda](https://crawlrelay.com/es/guides/bandwidth-calculator/) ofrece pesos típicos según el tipo de página.

## ¿Con qué límites por host debería comenzar?

| Objetivo | Solicitudes paralelas por host | Retraso entre solicitudes | Notas |
| --- | --- | --- | --- |
| Sitio pequeño (blog, tienda local) | 1 | 2–5 s | Respeta `Crawl-delay` en robots.txt si está presente |
| Sitio mediano | 2–4 | 0.5–2 s | Vigila los tiempos de respuesta; reduce la velocidad cuando se dupliquen |
| Gran plataforma con CDN | 4–16 | AutoThrottle o adaptativo | Aumenta solo mientras las tasas de 429 y 5xx se mantengan constantes |
| API pública | El límite documentado | Como se documenta | Usa la clave API y los límites que te proporciona el proveedor |

## ¿Cómo adapto la concurrencia automáticamente?

Usa aumento aditivo y disminución multiplicativa, la regla que usa TCP para congestión: añade un espacio tras una serie de respuestas limpias, reduce a la mitad el límite ante un 429 o 503. El limitador siguiente mantiene un límite por host, pausa cada solicitud a ese host por el retraso `Retry-After`, reintenta una vez, y nunca supera un techo que configures. Los errores de red regresan como valores, así un timeout no detiene el lote.

*Python asyncio: límite adaptativo con httpx*

```python
import asyncio
import random
from urllib.parse import urlsplit

import httpx

PROXY = "http://USERNAME-country-us:PASSWORD@gw.crawlrelay.com:7777"


class AdaptiveLimit:
    """One per host: +1 slot after 20 clean responses, halve on 429/503, pause for Retry-After."""

    def __init__(self, start=2, low=1, high=16):
        self.limit, self.low, self.high = start, low, high
        self.in_flight, self.clean = 0, 0
        self.pause_until = 0.0
        self.cond = asyncio.Condition()

    async def __aenter__(self):
        loop = asyncio.get_running_loop()
        while True:
            async with self.cond:
                await self.cond.wait_for(lambda: self.in_flight < self.limit)
                delay = self.pause_until - loop.time()
                if delay <= 0:
                    self.in_flight += 1
                    return self
            await asyncio.sleep(delay)  # the host asked for a pause: wait outside the lock

    async def __aexit__(self, *exc):
        async with self.cond:
            self.in_flight -= 1
            self.cond.notify_all()

    def record(self, status, retry_after=None):
        if status in (429, 503):
            self.limit, self.clean = max(self.low, self.limit // 2), 0
            wait = int(retry_after) if retry_after and retry_after.isdigit() else 5 + random.random()
            now = asyncio.get_running_loop().time()
            self.pause_until = max(self.pause_until, now + wait)
        elif status < 400:
            self.clean += 1
            if self.clean >= 20 and self.limit < self.high:
                self.limit, self.clean = self.limit + 1, 0


gates = {}


def gate_for(url):
    host = urlsplit(url).hostname
    if host not in gates:
        gates[host] = AdaptiveLimit()
    return gates[host]


async def fetch(client, url, attempts=2):
    gate = gate_for(url)
    status = None
    for _ in range(attempts):
        try:
            async with gate:
                r = await client.get(url)
        except httpx.HTTPError as exc:
            return "error: %s" % type(exc).__name__
        status = r.status_code
        gate.record(status, r.headers.get("Retry-After"))
        if status not in (429, 503):
            break  # the retry, if any, waits for the host's pause in __aenter__
    return status


async def main(urls):
    timeout = httpx.Timeout(30.0, connect=10.0)
    async with httpx.AsyncClient(proxy=PROXY, timeout=timeout) as client:
        print(await asyncio.gather(*(fetch(client, u) for u in urls)))
    print({host: gate.limit for host, gate in gates.items()})


asyncio.run(main(["https://example.com/"] * 10))
```

## ¿Qué ralentiza un rastreo con proxy además del objetivo?

- **Handshakes TLS.** Una conexión nueva por solicitud, necesaria para una IP nueva cada vez, añade una negociación con el sitio en cada vez. Mantén sesión pegajosa con keep-alive para páginas del mismo sitio cuando la diversidad de IP no importe.
- **Salidas lentas.** Las salidas residencial y móvil son conexiones reales de hogar y celular. Usa timeouts y reintenta con nueva conexión en lugar de esperar.
- **Objetivo restringido.** Una ciudad pequeña o un ASN único tiene menos salidas que un país. Apunta estrictamente donde los datos cambian.
- **Renderizado.** Un navegador sin cabeza consume mucho más CPU, memoria y tráfico por página que un cliente HTTP. Renderiza solo las páginas que requieren JavaScript.
- **DNS.** Con `socks5h://` o el puerto HTTP, el DNS se resuelve en la salida; no necesitas caché local para resolver los hosts objetivo.

## Preguntas sobre concurrencia

### ¿CrawlRelay limita el número de hilos o conexiones?

Los planes se facturan por GB de tráfico, no por hilo, conexión o solicitud, y los planes publicados no establecen límite de hilos. Los límites prácticos son la tolerancia de cada objetivo y tu propia máquina. Si planeas un rastreo muy grande, escribe primero a support@crawlrelay.com para que podamos verificar la cobertura según tu objetivo.

### ¿Por qué mi rastreo se volvió más lento al añadir más hilos?

Normalmente porque el objetivo empezó a limitarte: suben los tiempos de respuesta, aparecen respuestas 429 o 503, y los reintentos añaden más carga. Otra causa común es que tu máquina se quede sin CPU o sockets, especialmente con navegadores sin cabeza. Mide la latencia y tasa de errores por host antes de añadir hilos.

### ¿Una conexión por solicitud es más lenta que keep-alive?

Sí, implica un handshake TCP y TLS por solicitud, normalmente unos cientos de milisegundos a través de una salida residencial. Ese es el costo de una IP nueva en cada solicitud. Para muchas páginas de un mismo sitio donde la IP no importa, una sesión pegajosa con keep-alive es más rápida y usa menos tráfico.

### ¿Cómo respeto el crawl-delay de robots.txt en un rastreador concurrente?

Analiza robots.txt una vez por host, guárdalo en caché hasta 24 horas como sugiere RFC 9309, y convierte un valor `Crawl-delay` en un intervalo mínimo entre solicitudes por host con concurrencia 1. El `urllib.robotparser` de Python lo expone vía `crawl_delay()`.

**Escala con precios por GB** 0,50 US$/GB de 50 GB a 1 TB, tráfico que nunca expira. [Ver precios](https://crawlrelay.com/es/pricing/) · [Calculadora de ancho de banda](https://crawlrelay.com/es/guides/bandwidth-calculator/)

---

CrawlRelay: CrawlRelay es un servicio de proxies residenciales rotativos y proxies móviles 4G/5G para desarrolladores, ideal para scrapers y pipelines de datos de IA: tráfico prepago sin vencimiento desde 0,50 US$/GB, pagado con criptomonedas, sin subir documentos de identidad. Sin KYC — sin ID, sin selfie, sin documentos. Paga con criptomonedas.
