Benchmark
Come si comporta il gateway Wäg rispetto a LiteLLM in condizioni identiche. Questa pagina espone il metodo per intero e pubblica le misure che ne sono risultate. Non pubblichiamo moltiplicatori.
Come è stata fatta la misura
Tutto è girato in Docker su una sola macchina, con ogni componente fissato ai propri core perché nulla competesse per la CPU.
- Entrambi i gateway stanno davanti allo stesso upstream con configurazione del modello identica: nessuno dei due ha il percorso più facile.
- Ogni gateway gira come raccomanda la sua documentazione: LiteLLM secondo la guida di produzione, con worker pari alle vCPU; Wäg con i valori predefiniti. La cache delle risposte è disattivata su entrambi.
- I test a ciclo chiuso misurano il throughput massimo. Quelli a ciclo aperto inviano a cadenza fissa e contano la latenza dall'istante di invio previsto: un gateway che accoda non può nasconderlo.
- Ogni risposta viene validata: stato, struttura del corpo e, per gli stream, il numero di chunk atteso e la chiusura. Tutto il resto conta come errore, mai come risposta veloce.
- Ogni scenario viene eseguito tre volte e le tabelle mostrano la mediana. Senza gateway nel percorso lo stesso carico raggiunge circa 90.000 req/s, ben oltre entrambi i gateway: i risultati sono limitati dal gateway, non dall'harness.
Impronta
Quanto costa ogni gateway prima di servire alcunché: memoria a riposo, tempo di avvio, dimensione dell'immagine e latenza aggiunta a una singola richiesta con upstream istantaneo.
Che cosa significa: La memoria decide quante repliche stanno su un nodo, la dimensione dell'immagine quanto è rapido un rollout. Con 3,8 MB residenti e un'immagine da 123 MB, Wäg sta in un sidecar ed è pronto prima che scada un health check; 2,3 GB e 11 secondi sono un pod attorno al quale bisogna pianificare.
La latenza aggiunta è il p50 del gateway meno il p50 misurato senza gateway nel percorso.
Con un upstream realistico
Un modello reale risponde in centinaia di millisecondi, quindi migliaia di richieste sono in volo insieme. Qui l'upstream impiega 300 ms e le richieste arrivano a cadenza fissa qualunque cosa faccia il gateway. A 2.000 req/s circa 600 richieste sono in corso in ogni momento.
| richieste al secondo | Wäg p50 | Wäg p99 | Wäg Errori | Wäg CPU | LiteLLM p50 | LiteLLM p99 | LiteLLM Errori | LiteLLM CPU | × |
|---|---|---|---|---|---|---|---|---|---|
| 100 | 303 ms | 305 ms | 0,00% | 10,2% | 305 ms | 308 ms | 0,00% | 38,7% | 1,0× |
| 500 | 301 ms | 303 ms | 0,00% | 15,6% | 304 ms | 321 ms | 0,00% | 140,5% | 1,1× |
| 1000 | 301 ms | 302 ms | 0,00% | 20,2% | 317 ms | 605 ms | 0,00% | 263,7% | 2,0× |
| 2000 | 301 ms | 302 ms | 0,00% | 31,7% | 3,26 s | 28 s | 7,99% | 391,9% | 92× |
Che cosa significa: Questa è la forma del traffico reale: un modello risponde in centinaia di millisecondi e migliaia di richieste sono in volo. Un gateway che accoda trasforma una risposta da 300 ms in una da diversi secondi, e nessuno se ne accorge fino al picco. Wäg resta alla soglia fino a 2.000 req/s con meno di un terzo del suo budget di CPU. LiteLLM accoda già a 1.000 e fallisce l'8% delle richieste a 2.000.
Il solo upstream impiega 300 ms: quella è la soglia minima. Tutto ciò che la supera è tempo passato in coda dentro il gateway. La colonna × si legge sempre allo stesso modo: più alto significa che Wäg è avanti. È Wäg ÷ LiteLLM per il throughput e LiteLLM ÷ Wäg per la latenza.
Throughput e latenza
Ciclo chiuso verso un upstream istantaneo: puro costo del gateway, senza latenza del modello dietro cui nascondersi. Sono i numeri che servono a un piano di capacità. Non sono il motivo per scegliere un control plane.
4 vCPU, senza database
| Client simultanei | Wäg req/s | Wäg p99 | Wäg CPU | LiteLLM req/s | LiteLLM p99 | LiteLLM CPU | × |
|---|---|---|---|---|---|---|---|
| 1 | 6232 | 0,27 ms | 63,4% | 463 | 3,2 ms | 98,1% | 13× |
| 8 | 25.711 | 0,70 ms | 311,5% | 1237 | 15 ms | 286,1% | 21× |
| 32 | 25.093 | 2,6 ms | 321,8% | 1621 | 46 ms | 385,1% | 15× |
| 128 | 23.639 | 11 ms | 328,3% | 1669 | 111 ms | 396,2% | 14× |
| 512 | 22.407 | 45 ms | 336,9% | 1569 | 749 ms | 391,6% | 14× |
1 vCPU, senza database
| Client simultanei | Wäg req/s | Wäg p99 | LiteLLM req/s | LiteLLM p99 | × |
|---|---|---|---|---|---|
| 1 | 6589 | 0,35 ms | 459 | 3,2 ms | 14× |
| 8 | 16.594 | 1,3 ms | 484 | 26 ms | 34× |
| 32 | 15.226 | 3,8 ms | 506 | 85 ms | 30× |
| 128 | 13.264 | 15 ms | 505 | 438 ms | 26× |
Che cosa significa: Questo determina quante repliche servono a un dato livello di traffico, e quindi quanto costa far girare il gateway. Per Kubernetes la tabella da leggere è quella a 1 vCPU: è l'efficienza per core che un pod ottiene davvero.
Streaming, payload, embedding, failover
4 vCPU, senza database. Gli stream sono 50 token a 5 ms di distanza; il test di durata invia 200 stream al secondo di risposte da circa 1,2 secondi per tre minuti.
| Scenario | Wäg | Wäg p99 | Wäg Errori | LiteLLM | LiteLLM p99 | LiteLLM Errori | × |
|---|---|---|---|---|---|---|---|
| Streaming, 64 clients | 233 | 286 ms | 0,00% | 179 | 674 ms | 0,00% | 1,3× |
| Streaming, 256 clients | 911 | 288 ms | 0,00% | 307 | 1,09 s | 0,00% | 3,0× |
| 64 KB conversation history, 32 clients | 3583 | 29 ms | 0,00% | 568 | 106 ms | 0,00% | 6,3× |
| Embeddings (1,536 dims), 32 clients | 13.558 | 4,3 ms | 0,00% | 740 | 69 ms | 0,00% | 18× |
| Fallback after upstream 500, 16 clients | 19.816 | 1,8 ms | 0,00% | 584 | 62 ms | 0,00% | 34× |
| Soak: 200 streams/s for 3 minutes | 200 | 1,27 s | 0,00% | 176 | 20 s | 12,09% | 1,1× |
Che cosa significa: Streaming, prompt lunghi, embedding e failover sono i percorsi su cui un carico di produzione passa il tempo. Leggete le colonne degli errori prima di quelle del throughput: una richiesta fallita è una richiesta utente fallita, non una lenta.
Il valore sui payload da 64 KB è al soffitto dell'harness: senza gateway nel percorso lo stesso carico raggiunge 3711 req/s di corpi da 64 KB su un core. Il numero di Wäg è quindi un limite inferiore, non un massimo.
Che cosa questo non mostra
Ogni benchmark descrive un allestimento. Questi sono i limiti del nostro.
- I valori assoluti dipendono dall'host. Entrambi i gateway hanno girato sulla stessa macchina con core fissati, quindi il confronto tra loro regge, ma aspettatevi valori assoluti diversi sul vostro hardware.
- L'harness che ha guidato queste prove non è pubblicato, quindi non potete ripeterle comando per comando. Il metodo sopra è descritto in modo abbastanza dettagliato da ricostruirne uno equivalente.
- LiteLLM rilascia quasi ogni settimana. Questi dati sono stati misurati con v1.104.2, l'attuale versione stabile. Quando una versione cambia il percorso di inoltro, rieseguiamo la prova e pubblichiamo i risultati.
- LiteLLM è stato configurato secondo la sua guida di produzione, non dai suoi manutentori. Potrebbe esistere una configurazione migliore: se ne trovate una, rieseguiremo e ripubblicheremo.
- Entrambi i gateway hanno girato su una sola macchina con core fissati. Nulla qui misura il comportamento attraverso una rete, sotto lo scheduling di Kubernetes o con vicini rumorosi.