Ollama: NUM_PARALLEL y MAX_QUEUE, cómo funcionan
Descubre cuándo la segunda solicitud espera o devuelve HTTP 503 y por qué cada espacio paralelo de Ollama necesita su propia caché KV y más VRAM.
Qué ocurre con la segunda solicitud de Ollama mientras se genera la primera
La concurrencia de Ollama se controla mediante tres variables de entorno. De forma predeterminada, un modelo cargado atiende una solicitud cada vez. La segunda solicitud no se rechaza ni recibe una respuesta parcial. Espera en una cola hasta que haya un espacio disponible y después se ejecuta a velocidad normal.
Una solicitud entrante puede tener tres destinos. Puede iniciarse de inmediato en un espacio libre. Puede esperar en la cola. O la cola puede estar llena y el servidor puede rechazarla con HTTP 503. El resultado depende de OLLAMA_NUM_PARALLEL, OLLAMA_MAX_QUEUE y OLLAMA_MAX_LOADED_MODELS.
La configuración predeterminada es segura. También explica por qué un segundo usuario informa de que el servidor se ha «bloqueado» cuando no hay ningún problema. Añadir espacios requiere cambiar dos líneas. El problema está en la memoria. Cada espacio paralelo necesita su propia caché de clave/valor (caché KV), el bloque de memoria que el modelo conserva para los tokens que ya ha procesado. Si añade espacios sin aumentar la VRAM (memoria de vídeo de la GPU), convertirá una respuesta lenta en un error de carga.
Qué controla cada una de OLLAMA_NUM_PARALLEL, OLLAMA_MAX_QUEUE y OLLAMA_MAX_LOADED_MODELS
Estos son los valores predeterminados de las versiones actuales de Ollama en agosto de 2026. Compruebe los de su instalación en lugar de confiar en los números de aquí. Use la línea del registro que se muestra más adelante.
OLLAMA_NUM_PARALLELindica cuántas solicitudes puede gestionar al mismo tiempo un modelo cargado. El valor predeterminado es 1, por lo que las solicitudes se atienden una detrás de otra.OLLAMA_MAX_LOADED_MODELSindica cuántos modelos diferentes permanecen cargados al mismo tiempo. El valor predeterminado es 0. Esto significa que Ollama elige tres modelos por GPU y tres modelos en una máquina sin GPU.OLLAMA_MAX_QUEUEindica cuántas solicitudes pueden permanecer en espera. El valor predeterminado es 512. La solicitud que llega cuando la cola está llena se rechaza inmediatamente.
La memoria máxima posible es el producto de los dos primeros valores. Dos modelos cargados con cuatro slots cada uno representan ocho asignaciones de slots de caché KV, todas residentes al mismo tiempo, y Ollama intentará satisfacer esa demanda. En un equipo con una sola GPU, normalmente es mejor mantener un modelo cargado y asignarle slots, porque el cálculo sigue siendo fácil de hacer mentalmente.
Por qué cada ranura paralela consume VRAM
Cuando Ollama carga un modelo, inicia un proceso runner independiente. Dos de los argumentos que le pasa son importantes aquí: -c es el contexto total para el que runner asigna una caché KV, y -np es el número de secuencias paralelas. Ollama establece -c multiplicando la longitud de contexto por solicitud por el número de ranuras. Después, runner divide ese total por igual entre las ranuras, de modo que cada solicitud sigue recibiendo la longitud de contexto solicitada.
Esta es toda la limitación y explica por qué el paralelismo no es gratuito. Pasar de una ranura a cuatro exige cuatro veces más caché KV con la misma longitud de contexto por solicitud. Las ranuras no comparten nada. La parte de una ranura inactiva tampoco se presta a una ranura ocupada, porque la división queda fijada cuando se inicia runner.
Puede consultar los valores reales en lugar de los que pretendía establecer:
journalctl -u ollama --no-pager -n 500 | grep "starting llama-server"Esa línea contiene la línea de comandos completa de runner, incluidos -c y -np. Si -np vale 1 después de establecer la variable, la configuración no está llegando al servidor. La siguiente sección explica el motivo.
Si los pesos del modelo y esa caché KV no caben en la VRAM, Ollama mueve algunas capas a la RAM del sistema y esas capas se ejecutan en la CPU. Las capas de la CPU son mucho más lentas que las de la GPU, por lo que todas las solicitudes tardan más, incluida la única solicitud que inició. Por tanto, aumentar el paralelismo puede reducir el rendimiento en lugar de aumentarlo.
ollama psLa columna PROCESSOR muestra 100% GPU cuando todo cabe. Un reparto como 35%/65% CPU/GPU indica que parte del modelo se ejecuta en la CPU. La columna SIZE incluye la caché KV, por lo que aumenta al incrementar el número de ranuras y volver a cargar el modelo. Aumente OLLAMA_NUM_PARALLEL, reinicie, envíe una solicitud y vuelva a ejecutar ollama ps: así medirá el coste de memoria del cambio en lugar de calcularlo a partir de una suposición.
La longitud de contexto y el número de ranuras se multiplican, por lo que deben elegirse conjuntamente. Un contexto grande con cuatro ranuras equivale a cuatro contextos grandes. Si también está ajustando la ventana de contexto num_ctx del modelo, cambie sólo uno de los dos valores cada vez. De lo contrario, no sabrá cuál de ellos llenó la tarjeta.
Cómo configurar estas variables para que persistan tras un reinicio
En Linux, Ollama se ejecuta como un servicio de systemd. Ejecutar export OLLAMA_NUM_PARALLEL=4 en el shell no cambia nada, porque systemd inicia el servicio con su propio entorno y nunca ve el shell. Use un archivo drop-in.
sudo systemctl edit ollama.serviceAñada esto en el editor que se abre:
[Service]
Environment="OLLAMA_NUM_PARALLEL=4"
Environment="OLLAMA_MAX_LOADED_MODELS=1"
Environment="OLLAMA_MAX_QUEUE=32"Después, recargue la configuración y reinicie el servicio:
sudo systemctl daemon-reload
sudo systemctl restart ollama
systemctl show ollama --property=Environmentsystemctl show muestra lo que systemd entregará al proceso. Si la variable falta allí, no se guardó el drop-in o se omitió daemon-reload. Confírmelo también desde el propio servidor:
journalctl -u ollama --no-pager | grep "server config" | tail -1Ollama registra todo su entorno al iniciarse en una línea cuyo mensaje es server config. Ese mapa es la fuente de verdad. Es la forma más rápida de determinar si una variable surtió efecto.
Un modelo que ya está cargado conserva el número de slots con el que se inició, porque el valor queda fijado en el proceso runner durante el arranque. El reinicio anterior descarga todo, por lo que la siguiente petición vuelve a cargar el modelo con la nueva configuración y sólo paga una vez el tiempo de carga. Cuánto tiempo permanece residente el modelo después es un control independiente, explicado en mantener un modelo de Ollama cargado entre peticiones.
Qué aspecto tienen las solicitudes atendidas, en cola y rechazadas desde el cliente
Envíe varias solicitudes a la vez y mida sus tiempos. Esto ejecuta ocho solicitudes de streaming en paralelo e imprime el estado y los tiempos de cada una:
for i in $(seq 1 8); do
curl -s -o /dev/null \
-w "req$i http=%{http_code} ttfb=%{time_starttransfer}s total=%{time_total}s\n" \
http://127.0.0.1:11434/api/generate \
-d '{"model":"llama3.2:3b","prompt":"Explain what a KV cache is.","stream":true}' &
done
waitttfb es el tiempo hasta el primer byte del stream. Se aproxima al tiempo hasta el primer token (TTFT), porque el primer bloque enviado por streaming contiene el primer token.
Atendidas en paralelo. Todas las solicitudes muestran un ttfb similar y total aumenta para todas al mismo tiempo. La GPU se comparte entre los slots en ejecución. Por eso cada respuesta es más lenta que si se ejecutara por separado, aunque se completan más respuestas por minuto. Este es el comportamiento que obtiene al aumentar OLLAMA_NUM_PARALLEL.
En cola. Las primeras solicitudes responden rápido y las posteriores muestran un ttfb elevado, seguido de una generación normal. La espera corresponde a la cola, no al modelo. Un usuario que observa una ventana de chat ve una pausa larga sin contenido y después texto a velocidad normal. Este patrón, inicio lento seguido de generación rápida, indica una cola y no una GPU sobrecargada.
Rechazadas. El cliente recibe http=503 casi de inmediato y el cuerpo es:
{"error":"server busy, please try again. maximum pending requests exceeded"}Ese mensaje significa que la cola estaba llena cuando llegó la solicitud. No indica nada sobre la VRAM ni sobre el modelo.
Hay un límite importante: Ollama no publica la profundidad de la cola. ollama ps y el endpoint /api/ps informan de los modelos cargados, no de las solicitudes en espera. Por tanto, debe medir la cola desde el cliente observando el tiempo hasta el primer byte, o contar las respuestas 503 en el componente que se encuentre delante.
Por qué un MAX_QUEUE más pequeño suele ser la mejor configuración
Una cola de 512 parece amplia, pero con un único slot resulta casi inútil. La solicitud 300 espera detrás de 299 generaciones completas. En el mejor de los casos, eso tarda varios minutos. Todos los clientes HTTP abandonan mucho antes, por lo que el cliente recibe un tiempo de espera agotado. Esto no indica la causa y no proporciona nada útil para las alertas de monitorización.
Configure la cola con un tamaño aproximado al número de solicitudes que el servidor puede procesar dentro del tiempo de espera del cliente. Así, el exceso se convierte inmediatamente en un error 503. Un 503 resulta útil: un reverse proxy puede reintentarlo, un cliente puede aplicar una espera progresiva, un panel puede contabilizarlo y una persona puede leerlo. Calcule el valor a partir de sus propias mediciones. Si una generación tarda unos diez segundos y el cliente espera sesenta, cada slot puede procesar aproximadamente seis solicitudes dentro de ese intervalo. Una cola mucho más profunda sólo produce tiempos de espera agotados.
Cuándo poner una cola delante de Ollama
La cola integrada funciona según el principio primero en entrar, primero en salir (FIFO) y no sabe quién realiza cada llamada. Para una aplicación que se comunica con un solo servidor, esto es suficiente, y añadir infraestructura sólo introduciría más puntos de fallo. Utilice otro componente delante cuando se cumpla alguna de estas condiciones.
- Necesita prioridades. Un chat interactivo no debería esperar detrás de un trabajo por lotes de resumen. La cola de Ollama no admite prioridades, por lo que el trabajo por lotes debe mantenerse fuera de ella y enviarse gradualmente.
- Necesita equidad. Un cliente puede llenar la cola por sí solo y provocar que todos los demás reciban 503.
- Necesita que los trabajos sobrevivan a un reinicio. La cola reside en la memoria del servidor. Si reinicia Ollama, todas las solicitudes en espera se pierden.
- Necesita reintentos reales con espera progresiva, registrados en algún lugar que pueda inspeccionar después.
La opción ligera es un reverse proxy. En nginx, limit_conn limita las conexiones simultáneas y limit_req limita la tasa de llegada por cliente, por lo que el exceso se rechaza en el proxy y nunca llega a la cola de Ollama. La opción más completa es una cola de trabajos con una base de datos delante de un worker que llame a Ollama. Esto es lo que necesita cuando las solicitudes deben sobrevivir al reinicio de un proceso. Dimensionarla para tráfico real requiere un análisis propio: planificar un LLM autoalojado para usuarios simultáneos explica los cálculos, y ejecutar Ollama en un VPS cubre la instalación base que asumen estas variables.
Cuando la respuesta correcta es otro servidor
Hay un límite que no se puede superar ajustando parámetros. Ollama divide la caché KV en ranuras iguales y fijas cuando carga el modelo. La memoria de una ranura inactiva no puede utilizarla una ranura ocupada, y el número de ranuras no puede cambiar sin descargar el modelo. Este diseño es adecuado para una persona, un equipo pequeño o un agente de programación.
Los servidores diseñados para muchos usuarios simultáneos funcionan de otra manera. Asignan la caché KV en páginas pequeñas según la demanda y añaden las solicitudes entrantes a un lote que ya está en ejecución. Así, la memoria sigue la demanda real en lugar de dividirse de forma fija. Si el objetivo es atender a muchos usuarios simultáneos en una sola GPU, esta diferencia arquitectónica importa más que cualquier valor de OLLAMA_NUM_PARALLEL. La comparación entre Ollama y vLLM es el lugar adecuado para tomar esa decisión. No cambie por principio: otro servidor requiere más operación, y si el tráfico procede de unas pocas personas, el comportamiento integrado es la respuesta correcta.
Mida su propio rendimiento y el tiempo hasta el primer token
Las cifras publicadas de tokens por segundo proceden de la GPU, el modelo, la cuantización, la longitud del contexto y el prompt de otra persona. Ninguno de esos valores coincide con los suyos. Por tanto, considere cualquier cifra que lea como una referencia aproximada y mida el equipo que tiene delante.
Ollama devuelve los tiempos en el objeto JSON final de cada respuesta. eval_count es el número de tokens generados y eval_duration es el tiempo empleado en generarlos, en nanosegundos.
sudo apt install -y jq
curl -s http://127.0.0.1:11434/api/generate \
-d '{"model":"llama3.2:3b","prompt":"Explain what a KV cache is.","stream":false}' \
| jq '{prompt_eval_count, eval_count, eval_duration, tokens_per_second: (.eval_count / (.eval_duration / 1000000000))}'Ejecute el comando con un slot y después repítalo con la concurrencia que realmente espera. Compare las dos cifras que determinan si los usuarios estarán satisfechos: el tiempo hasta el primer token y los tokens por segundo por solicitud. El rendimiento por solicitud siempre disminuye al añadir slots. La cuestión es si disminuye más de lo que sus usuarios están dispuestos a aceptar. Medición de tokens por segundo en un LLM local explica el método con más detalle, incluido cómo mantener constante el prompt entre ejecuciones.
Un endpoint público con una cola amplia es un objetivo de denegación de servicio
Configurar OLLAMA_HOST=0.0.0.0:11434 hace que la API escuche en todas las interfaces, y Ollama no tiene autenticación integrada. Un endpoint abierto con la cola predeterminada aceptará 512 solicitudes en espera de cualquiera que lo encuentre. Llenar esa cola cuesta muy poco a un atacante: prompts largos, sin inicio de sesión, sin límite de tasa y sin coste. Tus propios usuarios recibirán respuestas 503 o tendrán que esperar mucho tiempo, mientras la máquina permanece ocupada.
Mantén el listener en loopback y accede a él mediante un túnel SSH o una red privada, o coloca autenticación y limitación de tasa delante del endpoint. Proteger un endpoint de la API de Ollama cubre ambas opciones. Ajusta la cola después de aplicar esas medidas, porque la longitud de la cola es un parámetro de capacidad y no proporciona protección.
FAQ
¿Por qué mi segunda solicitud a Ollama espera a que termine la primera?
Porque OLLAMA_NUM_PARALLEL tiene el valor predeterminado 1. Por eso, un modelo cargado procesa una solicitud cada vez y las demás esperan en orden. La solicitud en espera mantiene abierta la conexión HTTP y no envía bytes hasta que se libera un slot. Desde el cliente, esto parece un modelo lento. La diferencia está en el patrón temporal: una pausa larga seguida de texto a velocidad máxima indica una cola; un flujo lento desde el primer token indica un modelo lento. Aumente el número de slots con un drop-in de systemd y reinicie el servicio.
¿Qué significa "server busy, please try again. maximum pending requests exceeded"?
Es el error de desbordamiento de la cola de Ollama, que se devuelve con el estado HTTP 503. El número de solicitudes que ya esperaban alcanzó OLLAMA_MAX_QUEUE, cuyo valor predeterminado es 512. Por eso, la solicitud más reciente se rechazó en lugar de añadirse a la cola. No es un error de memoria ni un error del modelo. Aumentar la cola sólo hace que los clientes esperen más antes de recibir el mismo rechazo. Las soluciones reales son aumentar el número de slots si dispone de suficiente VRAM, reducir la carga entrante o colocar delante una cola que pueda reintentar y establecer prioridades.
¿Aumentar OLLAMA_NUM_PARALLEL hace que Ollama sea más rápido?
No. Permite procesar más solicitudes al mismo tiempo, pero cada una tarda más que si se ejecutara sola porque todas comparten una GPU. También multiplica la caché KV, ya que Ollama inicia el runner con un contexto total igual a la longitud de contexto multiplicada por el número de slots. Si el resultado ya no cabe en la VRAM, Ollama mueve capas a la CPU y todas las solicitudes se ralentizan, incluida una solicitud única sin competencia. Compruebe ollama ps después del cambio y confirme que la columna PROCESSOR todavía muestra 100% GPU.
¿Tengo que reiniciar Ollama después de cambiar estas variables?
Sí. El servidor las lee al arrancar y un modelo en ejecución conserva el número de slots fijado en su proceso runner cuando se inició. Edite el drop-in con sudo systemctl edit ollama.service y ejecute sudo systemctl daemon-reload y sudo systemctl restart ollama. Confirme el resultado con systemctl show ollama --property=Environment. Después, compruebe la línea server config en journalctl -u ollama, que muestra el entorno que el servidor cargó realmente.
¿Cuántos slots paralelos debo configurar?
Empiece con 1 y aumente el valor de uno en uno. Después de cada cambio, reinicie Ollama, envíe una solicitud para cargar el modelo y ejecute ollama ps. Deténgase en el último valor en el que PROCESSOR todavía muestre 100% GPU y la columna SIZE conserve margen para el contexto más largo que atiende. Después, mida el tiempo hasta el primer token y los tokens por segundo con ese valor y bajo la concurrencia real. Reduzca el valor un paso si la velocidad por solicitud cae por debajo de lo que sus usuarios toleran.