Blog von Obi Madu
Zurück zu allen Artikeln
AI EngineeringInfrastructureBackend

LiteLLM als verteiltes AI Gateway

Wie man API-Schlüssel und mehrere Backends unter einer einzigen Model-ID bündelt, um die Rate-Limit-Kapazität zu erhöhen, und wie LiteLLM dieses Pooling über mehrere Knoten hinweg konsistent hält.

LiteLLM als verteiltes AI Gateway

Wenn man LLMs in sein Produkt integriert, stößt man schnell an Provider-Rate-Limits. Ein einzelner OpenAI-Schlüssel gibt einem 1M TPM und 10K RPM. Wenn man einige Power-User hat, die große Dokumente verarbeiten, ist dieses Kontingent in Sekunden aufgebraucht.

Die Lösung ist Pooling. Man provisioniert mehrere API-Schlüssel für dasselbe Modell und verteilt den Traffic Lastverteilend über sie. Fünf Schlüssel geben einem 5M TPM. Man kann auch Backends mischen: OpenAI und Azure OpenAI unter demselben gpt-5.2-Alias, sodass eine Anfrage an gpt-5.2 den Backend trifft, der gerade Kapazität hat. Das ist der Hauptgrund, warum Leute zu einem Gateway wie LiteLLM greifen.

Aber Pooling bringt ein Problem mit geteiltem Zustand. Wenn man mehrere Gateway-Knoten hinter einem Load Balancer betreibt, muss jeder Knoten wissen, wie viel Quota jeder Schlüssel noch hat. Wenn Knoten A einen Schlüssel erschöpft, muss Knoten B das sofort wissen. Rein lokales Speicher-Tracking funktioniert hier nicht. Man sprengt seine Provider-Limits und bekommt 429-Fehler.

LiteLLM ist in Python geschrieben. Das bringt den Overhead mit sich, den die Sprache bekanntermaßen hat, aber seine Architektur ist auf verteilten Zustand ausgelegt. Indem es dauerhafte Daten in Postgres von heißen Laufzeit-Zählern in Redis trennt, besteht LiteLLM den Multi-Knoten-Test, an dem andere scheitern.

Key-Pooling in der Praxis konfigurieren

Key-Pooling in LiteLLM einzurichten, ist direkt. Man definiert eine router-Konfiguration, die mehrere Deployments unter einem einzigen Modellnamen gruppiert, und weist ihnen Limits zu.

Selber Provider, mehrere Schlüssel:

model_list:
  - model_name: gpt-5.2
    litellm_params:
      model: openai/gpt-5.2
      api_key: sk-key-1
      tpm: 1000000
      rpm: 10000
  - model_name: gpt-5.2
    litellm_params:
      model: openai/gpt-5.2
      api_key: sk-key-2
      tpm: 1000000
      rpm: 10000

router_settings:
  routing_strategy: usage-based-routing-v2
  redis_host: os.environ/REDIS_HOST
  redis_port: os.environ/REDIS_PORT
  redis_password: os.environ/REDIS_PASSWORD
  enable_pre_call_check: true

Verschiedene Backends, selbe Model-ID. Das ist nützlich, wenn man OpenAI, Azure, OpenRouter und regionale Azure-Deployments für dasselbe Modell hat und sie als einen Pool behandeln will:

model_list:
  - model_name: gpt-5.2
    litellm_params:
      model: openai/gpt-5.2
      api_key: sk-openai-key
      tpm: 1000000
      rpm: 10000
  - model_name: gpt-5.2
    litellm_params:
      model: azure/gpt-5.2
      api_base: https://my-deployment.openai.azure.com
      api_key: os.environ/AZURE_API_KEY
      tpm: 1000000
      rpm: 10000
  - model_name: gpt-5.2
    litellm_params:
      model: openrouter/openai/gpt-5.2
      api_key: os.environ/OPENROUTER_API_KEY
      tpm: 1000000
      rpm: 10000
  - model_name: gpt-5.2
    litellm_params:
      model: azure/gpt-5.2
      api_base: https://my-eu-deployment.openai.azure.com
      api_key: os.environ/AZURE_EU_API_KEY
      tpm: 1000000
      rpm: 10000

router_settings:
  routing_strategy: usage-based-routing-v2
  redis_host: os.environ/REDIS_HOST
  redis_port: os.environ/REDIS_PORT
  redis_password: os.environ/REDIS_PASSWORD
  enable_pre_call_check: true

In beiden Setups agiert LiteLLM als smarter Load Balancer. Indem man den Router für usage-based-routing-v2 konfiguriert und router_settings Zugriff auf Redis gibt, nutzt es eine asynchrone Redis-Implementierung, um die globale Nutzung (redis.mget und redis.incr) zu verfolgen. Es berechnet die verbleibende Kapazität über alle Instanzen und leitet den Traffic an den API-Schlüssel mit der geringsten aktuellen Auslastung in dieser Minute weiter, wobei es alle Schlüssel herausfiltert, die ihre TPM/RPM-Limits überschritten haben.

Warum Pooling über mehrere Knoten hinweg kaputtgeht

Wenn man 5 OpenAI-API-Schlüssel unter einem einzigen Alias wie gpt-5.2 bündelt, haben diese Schlüssel eine kombinierte Kapazitätsbeschränkung. Wenn Knoten A das Kontingent eines Schlüssels erschöpft, muss Knoten B das sofort wissen.

LiteLLM erreicht das, indem es sich direkt mit Redis verbindet, um zentralisierte Token-Buckets und Request-Zähler zu erzeugen. Wenn eine Anfrage kommt:

  1. Knoten A berechnet die benötigten Token und fordert eine Reservierung an.
  2. Redis inkrementiert den globalen Zähler atomar.
  3. Wenn Knoten B eine Millisekunde später eine Anfrage verarbeitet, liest es den aktualisierten Zähler aus Redis, bevor es seinen Payload sendet.

Das löst das Problem überlappender Anfragen. Zwar gibt es noch einen winzigen Spielraum für Race-Conditions (den LiteLLM als begrenzte Abweichung anerkennt), aber dieser Redis-gestützte Ansatz verhindert die massiven Budget-Sprengungen, die bei rein lokalem Speicher-Tracking passieren.

LiteLLMs Architekturphilosophie

LiteLLM versucht nicht, ein smarter, isolierter Knoten zu sein, der alle Wahrheiten im lokalen Speicher hält. Stattdessen agiert es als "Distributed Executor".

Es lagert das Zustandsmanagement an dedizierte Systeme aus, die genau für diesen Job gebaut sind:

  • Redis: Behandelt schnellen, flüchtigen Zustand (Rate-Limits, Cooldowns, Live-Spend-Zähler).
  • Postgres: Behandelt dauerhaften, relationalen Zustand (Virtual Keys, Budgets, Nutzer, Teams und permanente Spend-Logs).

Diese Philosophie bedeutet, dass man 10 Instanzen von LiteLLM hinter einem Load Balancer deployen kann, und sie fungieren als ein einziger, global koordinierter Proxy-Cluster, direkt out of the box, im Open-Source-Tier. Um das zu aktivieren, zeigt die config.yaml mit dauerhaftem Zustand auf Postgres und mit Router-Zustand auf Redis:

general_settings:
  master_key: sk-master-123
  database_url: "postgresql://user:pass@db:5432/litellm"

router_settings:
  redis_host: "redis-cluster.internal"
  redis_port: 6379
  redis_password: "redis-password"
  enable_pre_call_check: true

Virtual Keys sicher teilen

Über Provider-Keys hinaus erlaubt LiteLLM, Virtual Keys für Nutzer, Teams oder interne Dienste zu generieren.

Im Gegensatz zur Multi-Knoten-Postgres-Falle in OSS-Bifrost können sich mehrere LiteLLM-Knoten sicher mit genau derselben Postgres-Datenbank verbinden. Wenn eine Anfrage mit einem Virtual Key ankommt, authentifiziert LiteLLM den Schlüssel gegen die Datenbank, prüft das Budget des Nutzers und aktualisiert das Spend-Tracking als geteilten dauerhaften Zustand.

Weil die Wahrheit extern lebt, kann man programmatisch einen Virtual Key über die API erzeugen, und jeder LiteLLM-Knoten im Cluster erkennt ihn sofort. Hier ist ein Beispiel, wie man einen dynamisch begrenzten Schlüssel für ein bestimmtes Team mit einem harten monatlichen Budget erzeugt:

curl -X POST 'http://litellm-cluster:4000/key/generate' \
  -H 'Authorization: Bearer sk-master-123' \
  -H 'Content-Type: application/json' \
  -d '{
    "key_name": "marketing-team-prod",
    "models": ["gpt-5.2", "claude-3.5-sonnet"],
    "max_budget": 500.0,
    "budget_duration": "30d",
    "rpm_limit": 100,
    "metadata": {
      "team": "marketing",
      "environment": "production"
    }
  }'

Einmal erzeugt, ist dieser Schlüssel sofort über alle Knoten gültig. Die API setzt das max_budget über das dauerhafte Postgres-Konto durch und setzt das rpm_limit über die heißen Redis-Zähler durch.

Warum das für die eigene Architektur wichtig ist

LiteLLM wird nicht nur gewählt, weil es eine Virtual-Key-Funktion hat; viele Gateways haben das. Es wird gewählt, weil sein Zustandsmodell Virtual Keys als global koordinierte Budget-Subjekte in Open-Source-Multi-Knoten-Deployments nativ unterstützt.

Wenn die finanzielle Tragfähigkeit der eigenen Anwendung davon abhängt, nie die Rate-Limits eines Providers zu überschreiten und nie einen Nutzer sein zugewiesenes Budget überschreiten zu lassen, braucht man ein System, das geteilten Zustand respektiert. LiteLLM liefert genau das.

Im nächsten Beitrag werden wir LiteLLM und Bifrost direkt vergleichen, um bei der Entscheidung zu helfen, welche Architekturphilosophie am besten zur eigenen Infrastruktur passt.