Blog de Obi Madu
Volver a todos los artículos
AI EngineeringInfrastructureBackend

LiteLLM como AI Gateway distribuido

Cómo agrupar claves de API y múltiples backends bajo un único id de modelo para aumentar tu capacidad de rate limit, y cómo LiteLLM mantiene ese pooling consistente entre múltiples nodos.

LiteLLM como AI Gateway distribuido

Cuando integras LLMs en tu producto, alcanzas los rate limits del provider rápido. Una sola clave de OpenAI te da 1M TPM y 10K RPM. Si tienes algunos usuarios intensos procesando documentos grandes, esa cuota se va en segundos.

La solución es el pooling. Provisionas varias claves de API para el mismo modelo y balanceas el tráfico entre ellas. Cinco claves te dan 5M TPM. También puedes mezclar backends: OpenAI y Azure OpenAI bajo el mismo alias gpt-5.2, de modo que una petición a gpt-5.2 golpea el backend que tenga capacidad. Esta es la razón principal por la que la gente busca un gateway como LiteLLM.

Pero el pooling introduce un problema de estado compartido. Si ejecutas varios nodos de gateway detrás de un load balancer, cada nodo necesita saber cuánta cuota le queda a cada clave. Si el Nodo A agota una clave, el Nodo B necesita saberlo de inmediato. El tracking puramente en memoria local no funciona aquí. Superas los límites del provider y recibes errores 429.

LiteLLM está escrito en Python. Eso conlleva el overhead que el lenguaje ya conoce, pero su arquitectura está diseñada para el estado distribuido. Al separar los datos durables en Postgres de los contadores calientes de runtime en Redis, LiteLLM pasa la prueba multi-nodo donde otros fallan.

Configurar el pooling de claves en la práctica

Configurar el pooling de claves en LiteLLM es directo. Defines una configuración de router que agrupa varios despliegues bajo un único nombre de modelo y les asigna límites.

Mismo provider, varias claves:

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

Backends distintos, mismo id de modelo. Esto es útil cuando tienes OpenAI, Azure, OpenRouter y despliegues regionales de Azure para el mismo modelo y quieres tratarlos como un único pool:

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

En ambos setups, LiteLLM actúa como un load balancer inteligente. Al configurar el router para usage-based-routing-v2 y dar a router_settings acceso a Redis, usa una implementación asíncrona de Redis para rastrear el uso global (redis.mget y redis.incr). Evalúa la capacidad restante en todas las instancias y enruta el tráfico a la clave de API con el menor uso actual para ese minuto, filtrando las claves que han excedido sus límites de TPM/RPM.

Por qué el pooling se rompe entre múltiples nodos

Si estás agrupando 5 claves de API de OpenAI bajo un único alias como gpt-5.2, esas claves tienen una restricción de capacidad combinada. Si el Nodo A agota la cuota de una clave, el Nodo B necesita saberlo de inmediato.

LiteLLM logra esto conectándose directamente a Redis para crear token buckets y contadores de peticiones centralizados. Cuando llega una petición:

  1. El Nodo A calcula los tokens requeridos y solicita una reserva.
  2. Redis incrementa el contador global atómicamente.
  3. Si el Nodo B procesa una petición un milisegundo después, lee el contador actualizado de Redis antes de enviar su payload.

Esto resuelve el problema de las peticiones superpuestas. Aunque todavía hay un margen pequeño para race conditions (que LiteLLM reconoce como desviación acotada), este enfoque respaldado por Redis evita los estallidos masivos de presupuesto que ocurren con el tracking puramente en memoria local.

La filosofía de arquitectura de LiteLLM

LiteLLM no intenta ser un nodo inteligente y aislado que guarda toda la verdad en memoria local. En cambio, actúa como un "Distributed Executor".

Descarga la gestión de estado a sistemas dedicados construidos a propósito para ese trabajo:

  • Redis: Maneja estado rápido y efímero (rate limits, cooldowns, contadores de gasto en vivo).
  • Postgres: Maneja estado durable y relacional (virtual keys, presupuestos, usuarios, equipos y logs permanentes de gasto).

Esta filosofía significa que puedes desplegar 10 instancias de LiteLLM detrás de un load balancer, y actuarán como un único cluster proxy globalmente coordinado, out of the box, en el tier open-source. Para habilitarlo, tu config.yaml apunta el estado durable a Postgres y el estado del router a 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

Compartir Virtual Keys de forma segura

Más allá de las claves de provider, LiteLLM permite generar Virtual Keys para tus usuarios, equipos o servicios internos.

A diferencia de la trampa multi-nodo de Postgres en OSS Bifrost, múltiples nodos de LiteLLM pueden conectarse de forma segura a exactamente la misma base de datos de Postgres. Cuando llega una petición con una Virtual Key, LiteLLM autentica la clave contra la base de datos, comprueba el presupuesto del usuario y actualiza el tracking de gasto como estado durable compartido.

Como la verdad vive externamente, puedes crear programáticamente una Virtual Key vía la API, y cada nodo LiteLLM en tu cluster la reconocerá al instante. Aquí hay un ejemplo de creación de una clave con scope dinámico para un equipo específico con un presupuesto mensual estricto:

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"
    }
  }'

Una vez generada, esta clave es válida al instante en todos los nodos. La API aplica el max_budget usando el ledger durable de Postgres y aplica el rpm_limit usando los contadores calientes de Redis.

Por qué esto importa para tu arquitectura

LiteLLM no se elige simplemente porque tenga una función de Virtual Key; muchos gateways la tienen. Se elige porque su modelo de estado soporta de forma nativa las Virtual Keys como sujetos de presupuesto globalmente coordinados en despliegues open-source multi-nodo.

Cuando la viabilidad financiera de tu aplicación depende de nunca exceder los rate limits de un provider y de nunca dejar que un usuario exceda su presupuesto asignado, necesitas un sistema que respete el estado compartido. LiteLLM proporciona exactamente eso.

En el próximo post, pondremos a LiteLLM y Bifrost cara a cara para ayudarte a decidir qué filosofía de arquitectura se adapta mejor a tus necesidades de infraestructura.