Skip to content

English · Español

01 — Métricas RED + USE

🇪🇸 RED mide el servicio (lo que ven los usuarios). USE mide el hierro (lo que el servicio sufre). Juntas son completas; por separado son ciegas. Para LLMs hay que añadir métricas específicas — slots del KV cache, profundidad de cola del batcher — que no caen limpiamente en ninguna de las dos.

Hay dos filosofías de métricas que dominan la monitorización operativa, y se desarrollaron de forma independiente:

  • RED (Tom Wilkie, Weaveworks, ~2015) para servicios — rates, errors, durations.
  • USE (Brendan Gregg, Netflix, ~2013) para recursos — utilization, saturation, errors.

Son complementarias. RED te dice qué ve el usuario. USE te dice qué empuja desde abajo desde el hardware. Una historia madura de observabilidad usa ambas. Esta página deriva cada una, las ajusta al servicio de LLM y lista las métricas específicas de LLM que viven encima.

RED

Para cada servicio (handler HTTP, método gRPC, cola interna), registra tres series temporales:

Letra Métrica Unidades Tipo de Prometheus
R Rate (tasa) requests / segundo counter (con tasa vía rate())
E Errors (errores) errores / segundo, desglosado por status counter
D Duration (duración) distribución de latencia histogram

¿Por qué estas tres? Porque juntas caracterizan un servicio del mismo modo que lo hace un SLO: "el 99% de las peticiones tienen éxito en menos de T segundos".

  • La tasa por sí sola te dice la carga; sin errores, no sabes si la carga rompió el servicio.
  • Los errores por sí solos te dicen lo roto que está; sin tasa, no sabes si es entrada mala o servicio malo.
  • La duración por sí sola te dice la lentitud; sin tasa ni errores, no sabes si lento + pocos tuvieron éxito > rápido + todos fallaron.

RED para servir LLM

Para el servidor de la Fase 33, RED se instancia como:

  • Rate. http_requests_total{endpoint, method, status} — counter de Prometheus. PromQL: rate(http_requests_total[1m]) da RPS.
  • Errors. Ya en el mismo counter — filtra por status="5xx". Counter separado llm_generation_errors_total{reason} para errores de aplicación (p. ej., prompt_too_long, kv_cache_full).
  • Duration. Dos histogramas:
  • request_duration_seconds — end-to-end (HTTP-in a HTTP-out).
  • time_to_first_token_seconds (TTFT) — el específico de LLM. Distingue "el usuario mira una pantalla en blanco" de "el usuario está leyendo la respuesta".

La elección de buckets importa. Para LLMs:

buckets = (0.05, 0.1, 0.25, 0.5, 1, 2, 5, 10, 20, 30, 60, 120, float("inf"))

13 buckets cubriendo ~3.5 décadas. No añadas más — cada bucket es su propia serie temporal, y la cardinalidad es tu enemiga.

USE

Para cada recurso (CPU, RAM, disco, NIC de red, GPU, cola), registra tres series temporales:

Letra Métrica Pregunta
U Utilization (utilización) ¿qué fracción del recurso está ocupada?
S Saturation (saturación) ¿cuánto trabajo extra está encolado esperando al recurso?
E Errors (errores) ¿qué eventos de error emitió el recurso?

La claridad del método USE viene de un diagrama de flujo simple: para cada recurso, hazte las tres preguntas. Si alguna respuesta es preocupante, ahí es donde escarbas primero.

USE para una caja sirviendo LLM (solo CPU, Fase 34)

Recurso U S E
CPU node_cpu_seconds_total{mode="user\|system"} ratiado node_load1 node_cpu_seconds_total{mode="iowait"} (proxy)
RAM node_memory_MemAvailable_bytes node_memory_SwapUsed_bytes node_vmstat_oom_kill
Disco node_disk_io_time_seconds_total node_disk_io_now node_disk_io_errors_total (si está expuesto)
Cola del batcher llm_batcher_active_slots llm_batcher_queue_depth llm_batcher_admission_errors_total
KV cache llm_kv_cache_slots_used llm_kv_cache_evictions_total n/a (fallos de asignación = error de admisión del batcher)

La mayoría de las filas a nivel de SO vienen "gratis" con node_exporter. Las filas específicas de LLM — cola del batcher, KV cache — las cableas a mano en src/observability/metrics.py.

USE para una caja multi-GPU (referencia adelantada a la Fase 35)

Añade:

Recurso U S E
GPU SM DCGM_FI_DEV_GPU_UTIL n/a (no hay concepto de cola) DCGM_FI_DEV_XID_ERRORS
Ancho de banda HBM DCGM_FI_DEV_MEM_COPY_UTIL n/a DCGM_FI_DEV_MEM_ERRORS
Capacidad HBM DCGM_FI_DEV_FB_USED / FB_TOTAL eventos OOM eventos del OOM-killer
Colectivos NCCL histograma de latencia gauge de colectivo activo counter de timeout

El exporter DCGM de NVIDIA es el estándar. Lo cablearemos en la Fase 35; no es alcance aquí.

Métricas específicas de LLM que no encajan en RED ni USE

Cinco métricas viven en su propia categoría:

  1. tokens_total{kind="prompt|completion"} — counter. Tokens acumulados servidos. Se usa para calcular throughput en tokens/seg y coste por 1k tokens.
  2. time_to_first_token_seconds — histogram. La cola de esto es lo que "se siente lento" para un usuario durante streaming.
  3. inter_token_latency_seconds — histogram. Velocidad de generación en estado estable.
  4. generation_length_tokens — histogram. Distribución sesgada a la derecha; te deja detectar los outliers del estilo "el usuario pidió un ensayo de 10k tokens".
  5. cost_per_request_usd — histogram. Cubierto en theory/02-cost-accounting.md.

Estas cinco más RED más USE te dan el dashboard completo de LLM. Seis paneles para RED, ~6 para USE, 5 para específicos de LLM. ~17 paneles en un dashboard.

Un ejemplo trabajado: ¿qué alertas deberías escribir?

Tres alertas que cualquier servicio LLM debería tener desde el día uno:

  1. Tasa de errores alta. PromQL: (sum(rate(http_requests_total{status=~"5.."}[5m])) / sum(rate(http_requests_total[5m]))) > 0.01 durante 5 minutos. Objetivo: cazar un deployment que rompió la generación.
  2. TTFT p95 lento. histogram_quantile(0.95, rate(time_to_first_token_seconds_bucket[5m])) > 2 durante 5 minutos. Objetivo: cazar regresiones en prefill.
  3. Explosión de coste. histogram_quantile(0.95, rate(cost_per_1k_completion_tokens_usd_bucket[15m])) > 0.05 durante 15 minutos. Objetivo: cazar un patrón de prompt fuera de control.

Estas tres son las alertas de guardia para un servicio LLM.

Cardinalidad: el asesino silencioso

Cada combinación de etiquetas es una serie temporal separada. Prometheus escala a ~1M de series activas en hardware básico; pasado eso, se cae.

Etiquetas con cardinalidad acotada (buenas):

  • endpoint (5–20 valores)
  • method (4 valores)
  • status (decenas de valores)
  • model_name (un puñado)
  • tenant_id si tienes una lista cerrada

Etiquetas que explotan (malas):

  • user_id (no acotada)
  • prompt_hash (no acotada)
  • request_id (no acotada — para esto está trace_id, no las métricas)
  • prompt_first_100_chars (efectivamente no acotada)

Regla: si una etiqueta puede tomar más de ~1000 valores distintos a lo largo del tiempo, no pertenece a una métrica. Pertenece a un log o a un atributo de span de traza, donde el coste de almacenamiento es lineal en eventos y no en número de series.

El modelo mental del cliente Prometheus

Para el laboratorio de Borja, la librería prometheus_client expone cuatro tipos de métrica:

  • Counter: monotónicamente creciente. .inc(). Úsalo para tasas y totales.
  • Gauge: valor arbitrario. .set(), .inc(), .dec(). Úsalo para cosas que suben y bajan (profundidad de cola, slots usados).
  • Histogram: pre-bucketizado. .observe(value). Úsalo para latencia, coste, cualquier cosa donde quieras percentiles.
  • Summary: como histogram pero con estimación de cuantiles hecha del lado cliente. Evítalo — no agregable entre instancias. Usa histogramas.

Para la Fase 34 usas exactamente tres: Counter, Gauge, Histogram. Nunca Summary.

Recapitulación en un párrafo

RED (rate, errors, duration) caracteriza un servicio por lo que ven sus usuarios; USE (utilization, saturation, errors) caracteriza un recurso por lo que empuja desde abajo. Juntas son completas; por separado cada una es ciega a la mitad del cuadro. Servir LLM añade cinco métricas específicas (counters de tokens, TTFT, ITL, longitud de generación, coste por petición) que no encajan limpiamente en ninguna. Los buckets de histograma deben tener forma LLM (sub-segundo a dos minutos, 13 buckets). Las etiquetas deben tener cardinalidad acotada — las dimensiones por usuario pertenecen a trazas/logs, no a métricas.


Siguiente: theory/02-cost-accounting.md.