Pruebas

Benchmarks

Cómo se comporta la pasarela Wäg frente a LiteLLM en condiciones idénticas. Esta página expone el método completo y publica las mediciones que produjo. No publicamos multiplicadores.

8 vCPU Docker, pinned coresWäg v1.0.0LiteLLM v1.104.23 runs/scenario

Cómo se midió

Todo se ejecutó en Docker en una sola máquina, con cada componente fijado a sus propios núcleos para que nada compitiera por la CPU.

  • Ambas pasarelas se sitúan ante el mismo upstream con idéntica configuración de modelo, así que ninguna tiene el camino más fácil.
  • Cada pasarela se ejecuta como recomienda su propia documentación: LiteLLM según su guía de producción, con tantos workers como vCPU; Wäg con sus valores por defecto. La caché de respuestas está desactivada en ambas.
  • Las pruebas en bucle cerrado miden el rendimiento máximo. Las de bucle abierto envían a un ritmo fijo y cuentan la latencia desde el instante de envío previsto, así que una pasarela que encola no puede ocultarlo.
  • Cada respuesta se valida: estado, estructura del cuerpo y, en los flujos, el número de fragmentos esperado y su cierre. Todo lo demás cuenta como error, nunca como respuesta rápida.
  • Cada escenario se ejecuta tres veces y las tablas muestran la mediana. Sin pasarela en el camino, la misma carga alcanza unas 90.000 req/s, muy por encima de ambas pasarelas: los resultados los limita la pasarela, no el arnés.

Huella

Lo que cuesta cada pasarela antes de servir nada: memoria en reposo, tiempo de arranque, tamaño de imagen y latencia añadida a una sola petición con un upstream instantáneo.

Memoria tras el arranque3,8 MBLiteLLM 2302 MB
Tiempo de arranque0,32 sLiteLLM 11,2 s
Imagen del contenedor123 MBLiteLLM 1669 MB
Latencia añadida, un cliente (p50)0,11 msLiteLLM 2,1 ms

Qué significa: La memoria decide cuántas réplicas caben en un nodo, y el tamaño de la imagen, lo rápido que es un despliegue. Con 3,8 MB residentes y una imagen de 123 MB, Wäg cabe en un sidecar y está listo antes de que expire un health check; 2,3 GB y 11 segundos son un pod alrededor del cual hay que planificar.

La latencia añadida es el p50 de la pasarela menos el p50 medido sin pasarela en el camino.

Con un upstream realista

Un modelo real responde en cientos de milisegundos, así que hay miles de peticiones en vuelo a la vez. Aquí el upstream tarda 300 ms y las peticiones llegan a ritmo fijo haga lo que haga la pasarela. A 2.000 req/s hay unas 600 peticiones en curso en cada momento.

WägLiteLLM
200 ms500 ms1,00 s2,00 s5,00 s10 s20 s50 sSuelo: 300 ms de upstream1005001,0002,000peticiones por segundoLiteLLMWäg
peticiones por segundoWäg p50Wäg p99Wäg ErroresWäg CPULiteLLM p50LiteLLM p99LiteLLM ErroresLiteLLM CPU×
100303 ms305 ms0,00%10,2%305 ms308 ms0,00%38,7%1,0×
500301 ms303 ms0,00%15,6%304 ms321 ms0,00%140,5%1,1×
1000301 ms302 ms0,00%20,2%317 ms605 ms0,00%263,7%2,0×
2000301 ms302 ms0,00%31,7%3,26 s28 s7,99%391,9%92×

Qué significa: Esta es la forma del tráfico real: un modelo responde en cientos de milisegundos y hay miles de peticiones en vuelo. Una pasarela que encola convierte una respuesta de 300 ms en una de varios segundos, y nadie lo nota hasta el pico. Wäg se mantiene en el suelo hasta 2.000 req/s con menos de un tercio de su presupuesto de CPU. LiteLLM ya encola a 1.000 y falla el 8% de las peticiones a 2.000.

El upstream por sí solo tarda 300 ms: ese es el suelo. Todo lo que lo supere es tiempo en cola dentro de la pasarela. La columna × se lee siempre igual: más alto significa que Wäg va por delante. Es Wäg ÷ LiteLLM para el rendimiento y LiteLLM ÷ Wäg para la latencia.

Rendimiento y latencia

Bucle cerrado contra un upstream instantáneo: coste puro de la pasarela, sin latencia de modelo tras la que esconderse. Son las cifras que necesita un plan de capacidad. No son la razón para elegir un plano de control.

4 vCPU, sin base de datos

Clientes simultáneosWäg req/sWäg p99Wäg CPULiteLLM req/sLiteLLM p99LiteLLM CPU×
162320,27 ms63,4%4633,2 ms98,1%13×
825.7110,70 ms311,5%123715 ms286,1%21×
3225.0932,6 ms321,8%162146 ms385,1%15×
12823.63911 ms328,3%1669111 ms396,2%14×
51222.40745 ms336,9%1569749 ms391,6%14×

1 vCPU, sin base de datos

Clientes simultáneosWäg req/sWäg p99LiteLLM req/sLiteLLM p99×
165890,35 ms4593,2 ms14×
816.5941,3 ms48426 ms34×
3215.2263,8 ms50685 ms30×
12813.26415 ms505438 ms26×

Qué significa: Esto determina cuántas réplicas necesita un nivel de tráfico y, por tanto, lo que cuesta operar la pasarela. Para Kubernetes, la tabla a leer es la de 1 vCPU: es la eficiencia por núcleo que un pod obtiene realmente.

Streaming, cargas útiles, embeddings, conmutación

4 vCPU, sin base de datos. Los flujos son 50 tokens separados 5 ms; la prueba de resistencia envía 200 flujos por segundo de respuestas de unos 1,2 segundos durante tres minutos.

EscenarioWägWäg p99Wäg ErroresLiteLLMLiteLLM p99LiteLLM Errores×
Streaming, 64 clients233286 ms0,00%179674 ms0,00%1,3×
Streaming, 256 clients911288 ms0,00%3071,09 s0,00%3,0×
64 KB conversation history, 32 clients358329 ms0,00%568106 ms0,00%6,3×
Embeddings (1,536 dims), 32 clients13.5584,3 ms0,00%74069 ms0,00%18×
Fallback after upstream 500, 16 clients19.8161,8 ms0,00%58462 ms0,00%34×
Soak: 200 streams/s for 3 minutes2001,27 s0,00%17620 s12,09%1,1×

Qué significa: Streaming, prompts largos, embeddings y conmutación son los caminos donde una carga de producción pasa el tiempo. Lea las columnas de errores antes que las de rendimiento: una petición fallida es una petición de usuario fallida, no una lenta.

La cifra de cargas de 64 KB está en el techo del arnés: sin pasarela en el camino la misma carga alcanza 3711 req/s de cuerpos de 64 KB en un núcleo, así que el número de Wäg ahí es una cota inferior, no un máximo.

Lo que esto no muestra

Todo benchmark describe un montaje. Estos son los límites de este.

  • Las cifras absolutas dependen del host. Ambas pasarelas se ejecutaron en la misma máquina con núcleos fijados, así que la comparación entre ellas se sostiene, pero espere valores absolutos distintos en su propio hardware.
  • El arnés que condujo estas mediciones no está publicado, así que no puede repetirlas comando a comando. El método anterior se describe con detalle suficiente para reconstruir uno equivalente.
  • LiteLLM publica casi cada semana. Estas cifras se midieron con v1.104.2, la versión estable actual. Cuando una versión modifique la ruta de reenvío, repetiremos la medición y publicaremos lo que salga.
  • LiteLLM se configuró a partir de su guía de producción, no por sus mantenedores. Puede existir una configuración mejor; si encuentra una, repetiremos la medición y volveremos a publicar.
  • Ambas pasarelas se ejecutaron en una sola máquina con núcleos fijados. Nada de esto mide el comportamiento a través de una red, bajo la planificación de Kubernetes o con vecinos ruidosos.