Elija Auto, TokenLab Verified o Official para cada solicitud, con los precios mostrados por adelantado. Ver las novedades

Latencia vs. Throughput en LLM: Cómo los compradores de API deben medir la velocidad

·19 de septiembre de 2026·17 min de lectura·Actualizado 2 de octubre de 2026·2196 vistas
#punto de referencia#API de IA#infraestructura de modelos#TokenLab
Latencia vs. Throughput en LLM: Cómo los compradores de API deben medir la velocidad

El modelo que mostró su primer token visible más rápido en nuestra última prueba fue también el más lento en terminar. El 03-10-2026 transmitimos un prompt a través de cuatro modelos. claude-sonnet-5-5 lideró en el primer token visible (2,981 ms) y quedó rezagado en el tiempo total (12,384 ms). Esa brecha es la esencia de la latencia vs. throughput en LLMs: un número indica cuánto espera un usuario para ver texto, otro indica qué tan rápido se completa el trabajo. Este artículo define cada métrica, muestra nuestras pequeñas mediciones de primera mano con sus límites y proporciona un arnés que puedes ejecutar contra la API de TokenLab.

Puntos clave

  • Tres números, tres trabajos. El tiempo hasta el primer token, el tiempo total y los tokens de salida por segundo responden a preguntas diferentes. El chat, los agentes y el trabajo por lotes (batch) dependen de uno distinto cada uno.
  • Separa el primer evento del primer token visible. En deepseek-v4.1-flash, las dos medianas tuvieron una diferencia de 2,334 ms y 3,925 ms. Los deltas de razonamiento pueden llegar mucho antes que cualquier texto visible.
  • Los tokens de razonamiento consumen tu presupuesto de max_tokens. Con max_tokens en 400, deepseek-v4.1-flash devolvió cerca de 0 tokens visibles y gemini-3.8-flash alrededor de 14. A 2000, ambos respondieron completamente.
  • Lee los conteos de tokens desde el chunk de uso (usage chunk). No los estimes a partir de caracteres.
  • La velocidad del modelo no aumenta tu límite de solicitudes. Los límites de tasa (rate limits), los límites de tokens y la velocidad del modelo son restricciones independientes.
  • Nuestra muestra es pequeña. Tiene cinco ejecuciones por modelo, un cliente, un prompt y un día. Muestra cómo medir, no quién es el más rápido.

Tres números de velocidad: Latencia vs. throughput de LLM en la práctica

Divide la "velocidad" en partes, porque cada una tiene un responsable diferente: la red, el modelo y tu propia cola.

send request
  -> first stream event          (any SSE chunk; may be a reasoning delta)
  -> first visible content token (first non-empty delta.content)
  -> last token + final usage chunk

Tiempo hasta el primer token (TTFT) es el tiempo desde el envío de la solicitud hasta que llega el primer token. Registramos dos versiones. El primer evento de stream es el primer chunk SSE de cualquier tipo. El primer token de contenido visible es el primer chunk cuyo choices[0].delta.content no está vacío. Para los modelos que razonan antes de responder, el primer evento puede ser un delta de razonamiento (delta.reasoning_content) que llega mucho antes que el texto visible. Un arnés que solo observa delta.content mide el tiempo hasta el primer token visible, no el tiempo hasta el primer byte. Los usuarios perciben el visible.

Tiempo total corre desde el envío de la solicitud hasta el final del stream. Incluye el razonamiento, el tiempo de red y cualquier espera por reintento que añadas.

Tokens de salida por segundo son los tokens de salida divididos por el tiempo total. Toma el conteo de tokens de usage.completion_tokens, que incluye los tokens de razonamiento. Dividimos por el tiempo total, no por la ventana visible. Algunos modelos en nuestra muestra entregaron texto visible en unos pocos chunks grandes, por lo que una tasa basada en ventanas sería engañosa.

Carga de trabajo Observar primero Luego Por qué
Chat Primer token visible Tiempo total El usuario mira una caja vacía hasta que aparece texto visible.
Agentes Tiempo total Primer token visible Cada paso suele esperar al anterior, por lo que los totales por paso se suman.
Extracción o resúmenes por lotes Tokens de salida por segundo y costo por tarea Margen del límite de solicitudes Nadie mira el primer token, y el límite de solicitudes de la cuenta limita qué tan rápido puedes enviar trabajo.

Las llamadas sin streaming, como la extracción de JSON estructurado, solo exponen el tiempo total. Haz streaming en las pruebas si deseas la separación.

Lo que medimos el 03-10-2026

Método. Esta es una medición de primera mano de TokenLab, observada el 03-10-2026, contra POST https://api.tokenlab.sh/v1/chat/completions (fuente). Cada solicitud utilizó stream=true y stream_options.include_usage=true. Realizamos 5 ejecuciones secuenciales por modelo desde un único cliente en Asia Oriental, usando fetch de Node 24. El prompt fue "Explain how HTTP keep-alive reduces latency for API clients. Write about 200 words." Todos los modelos utilizaron la configuración de razonamiento predeterminada. Los tiempos son de reloj de pared del lado del cliente, y todas las ejecuciones tuvieron éxito (5/5) para cada fila a continuación.

Modelo (max_tokens 2000) Mediana primer evento de stream Mediana primer token visible Mediana tiempo total Mediana tokens de finalización (razonamiento) Tokens/s estimados
deepseek-v4.1-flash 2,334 ms 3,925 ms 5,204 ms 453 (225) 87
gemini-3.8-flash 6,892 ms 6,892 ms 8,626 ms 826 (528) 96
claude-sonnet-5-5 2,981 ms 2,981 ms 12,384 ms 418 (no reportado) 34
gpt-5.6-luna 3,262 ms 3,262 ms 8,183 ms 313 (42) 38

La columna tokens/s es nuestra propia estimación: mediana de tokens de finalización dividida por la mediana de segundos totales, por ejemplo 453 ÷ 5.204 ≈ 87. Es una relación de medianas, no una mediana de tasas por ejecución.

Lo que muestran los números, y nada más:

  • El orden por primer token visible (claude-sonnet-5-5, gpt-5.6-luna, deepseek-v4.1-flash, gemini-3.8-flash) difiere del orden por tiempo total (deepseek-v4.1-flash, gpt-5.6-luna, gemini-3.8-flash, claude-sonnet-5-5). Una métrica no puede sustituir a la otra.
  • deepseek-v4.1-flash tuvo una brecha de 1,591 ms entre el primer evento y el primer token visible. Su salida visible mediana fue de unos 228 tokens, entregados en 87 eventos durante 1,304 ms.
  • Para gemini-3.8-flash, el primer evento y el primer token visible comparten una mediana de 6,892 ms. Su texto visible llegó en una mediana de 11 eventos durante 1,734 ms, por lo que el stream fue fragmentado en lugar de token por token.
  • claude-sonnet-5-5 envió una mediana de 371 eventos durante 9,186 ms, y gpt-5.6-luna envió 265 eventos durante 4,901 ms.

El costo va de la mano con la velocidad. Los precios a continuación provienen de la API de modelos de TokenLab, observados el 03-10-2026, con precios actualizados el 02-10-2026T16:53:30.068Z. La última columna es una estimación: mediana de tokens de finalización multiplicada por la tasa de salida, solo del lado de salida. Revisa los registros de uso para cargos reales.

Modelo Entrada por 1M Salida por 1M Tokens de salida máx. Estimación lado de salida, ejecución mediana Fuente
deepseek-v4.1-flash $0.15 fuera de pico, $0.30 pico $0.60 fuera de pico, $1.20 pico 384,000 453 × $0.60 / 1M ≈ $0.00027 fuera de pico, ≈ $0.00054 pico API de modelo
gemini-3.8-flash $0.375 $1.875 65,536 826 × $1.875 / 1M ≈ $0.00155 API de modelo
claude-sonnet-5-5 $0.60 $3 128,000 418 × $3 / 1M ≈ $0.00125 API de modelo
gpt-5.6-luna $0.06 $0.36 128,000 313 × $0.36 / 1M ≈ $0.00011 API de modelo

Para gpt-5.6-luna, esas tasas se aplican cuando la entrada es de máximo 272K tokens. Por encima de eso, la solicitud completa utiliza 2x tasas de entrada y 1.5x de salida.

Límites de esta muestra. Cinco ejecuciones secuenciales desde un cliente en Asia Oriental es una muestra pequeña. El prompt fue una solicitud de ensayo breve, por lo que los resultados cambiarán según la región, la hora del día, el prompt y la longitud de la salida. No probamos concurrencia, por lo que nada de esto indica qué sucede bajo carga. Trata la tabla como una plantilla para tu propia prueba, ejecutada desde la región donde se realizan las ejecuciones de producción. Si deseas una visión más amplia de los modelos, el ranking de APIs de LLM de TokenLab para desarrolladores es un punto de partida. Verifica su método y fecha antes de confiar en cualquier cifra de velocidad allí. Tampoco cambies de modelos silenciosamente: la guía de fiabilidad, observada el 03-10-2026, señala que un reemplazo puede cambiar la calidad, el precio, la longitud del contexto y las herramientas.

Tokens de razonamiento y max_tokens: por qué 400 devolvieron casi nada

También ejecutamos el mismo prompt con max_tokens establecido en 400. Mismo método, mismas cinco ejecuciones, misma fecha (fuente).

Modelo (max_tokens 400) Mediana tokens de finalización Mediana tokens de razonamiento Salida visible (aprox.) Mediana primer token visible Mediana tiempo total
deepseek-v4.1-flash 400 400 0 tokens 3,795 ms 4,693 ms
gemini-3.8-flash 396 382 14 tokens 4,199 ms 4,240 ms
claude-sonnet-5-5 400 no reportado 400 tokens 3,088 ms 11,078 ms
gpt-5.6-luna 317 42 275 tokens 3,040 ms 8,083 ms

Las medianas se calculan por columna, por lo que las columnas de una fila no necesitan describir una sola ejecución. Es por eso que deepseek-v4.1-flash muestra un tiempo de primer visible junto a una mediana de cero eventos visibles.

El hallazgo es claro. deepseek-v4.1-flash y gemini-3.8-flash gastaron casi todo el presupuesto de 400 tokens en razonamiento y no devolvieron casi nada de texto visible. Aumentar max_tokens a 2000 produjo respuestas completas. Los tokens de razonamiento cuentan dentro de usage.completion_tokens. Se reportan por separado en usage.completion_tokens_details.reasoning_tokens.

Cuando vimos el primer resultado de 400 tokens, el fallo parecía una respuesta vacía, no un problema de presupuesto. Tres comprobaciones lo hacen visible:

  1. Lee el chunk de uso final, habilitado por stream_options={"include_usage": True}. Si reasoning_tokens está cerca de completion_tokens y el texto está vacío, el presupuesto se fue al razonamiento.
  2. Verifica finish_reason. La guía de streaming (observada el 03-10-2026) enumera length como el valor cuando se alcanza un límite de tokens.
  3. Compara contra la salida máxima del modelo. Por ejemplo, la API de modelos enumera 384,000 para deepseek-v4.1-flash y 65,536 para gemini-3.8-flash, por lo que 400 era una pequeña parte de lo que permiten los modelos.

La referencia de Create Chat Completion (observada el 03-10-2026) también enumera max_completion_tokens y reasoning_effort. Dice que los valores admitidos dependen del modelo, así que lee la página del modelo antes de configurar cualquiera. No los probamos, y ejecutamos cada fila con el razonamiento predeterminado. Dimensiona el límite según tu propio prompt: en nuestra ejecución, una respuesta de 200 palabras produjo aproximadamente de 228 a 418 tokens visibles, y hasta 528 tokens de razonamiento adicionales.

Un arnés de medición para la URL base de TokenLab

Este script utiliza la URL base de TokenLab, lee los conteos de tokens del chunk de uso y registra el primer evento de stream por separado del primer token de contenido visible. También mantiene los encabezados de respuesta para depuración posterior. Sigue la configuración del cliente en la documentación (timeout=30.0, max_retries=0) para que el SDK no añada reintentos ocultos a tus tiempos. El ID del modelo es uno que medimos; intercambia cualquier ID cuyos formatos de solicitud aceptados incluyan openai_chat_completions.

import json
import os
import statistics
import time

from openai import OpenAI

client = OpenAI(
    api_key=os.environ["TOKENLAB_API_KEY"],
    base_url="https://api.tokenlab.sh/v1",
    timeout=30.0,
    max_retries=0,
)

PROMPT = "Explain how HTTP keep-alive reduces latency for API clients. Write about 200 words."

def measure(model: str, max_tokens: int = 2000) -> dict:
    start = time.perf_counter()
    raw = client.chat.completions.with_raw_response.create(
        model=model,
        messages=[{"role": "user", "content": PROMPT}],
        max_tokens=max_tokens,
        stream=True,
        stream_options={"include_usage": True},
    )
    headers = raw.headers
    first_event = first_visible = None
    visible_events = 0
    usage = None
    finish_reason = None

    for chunk in raw.parse():
        now = time.perf_counter() - start
        if first_event is None:
            first_event = now
        if chunk.usage is not None:
            usage = chunk.usage
        if not chunk.choices:
            continue
        choice = chunk.choices[0]
        if choice.delta.content:
            visible_events += 1
            if first_visible is None:
                first_visible = now
        if choice.finish_reason:
            finish_reason = choice.finish_reason

    total = time.perf_counter() - start
    details = getattr(usage, "completion_tokens_details", None)
    completion = usage.completion_tokens if usage else None
    return {
        "model": model,
        "request_id": headers.get("x-request-id"),
        "routing_time_ms": headers.get("x-routing-time-ms"),
        "first_event_s": first_event,
        "first_visible_s": first_visible,
        "total_s": total,
        "completion_tokens": completion,
        "reasoning_tokens": getattr(details, "reasoning_tokens", None),
        "visible_events": visible_events,
        "finish_reason": finish_reason,
        "tokens_per_s": completion / total if completion else None,
    }

if __name__ == "__main__":
    runs = [measure("gemini-3.8-flash") for _ in range(5)]
    print(json.dumps(runs[0], indent=2))
    print("median total_s:", statistics.median(r["total_s"] for r in runs))

Algunas notas sobre la lectura de la salida:

  • first_event_s se dispara en cualquier chunk, incluido un chunk de solo rol o de razonamiento. first_visible_s se dispara solo en delta.content no vacío. Si ambos difieren por segundos, el modelo está razonando antes de responder.
  • Los conteos de tokens provienen del chunk de uso final. Ese chunk tiene una lista choices vacía, por lo que el bucle verifica chunk.usage antes de omitirlo.
  • Ejecútalo cinco veces o más, registra la región e informa las medianas junto con el tamaño de la muestra.
  • Para los modelos que enumeran openai_responses, la guía de streaming muestra respuestas transmitidas con eventos response.output_text.delta y response.completed. Se aplica la misma separación: mide el primer evento, luego el primer delta de texto.
  • Trata un stream que se cierra antes de response.completed o una razón de finalización stop como incompleto, no como un éxito rápido.

Encabezados e identificadores para registrar para la depuración de latencia

Una solicitud lenta es difícil de depurar si solo conservaste una duración. La referencia de la API y la guía de solución de problemas, ambas observadas el 03-10-2026, nombran los identificadores que vale la pena conservar.

Identificador Dónde aparece Úsalo para
X-Request-ID Encabezado de respuesta, cuando está disponible Soporte y depuración para una solicitud
request_id Cuerpos de error, registros del dashboard, registros de uso Soporte a nivel de solicitud y conciliación
X-Routing-Time-MS Encabezado de respuesta, cuando está disponible Tiempo dedicado a seleccionar la entrega, antes de la generación
X-Task-ID, task_id, poll_url Respuestas de creación y estado asíncronas Trabajos de imagen, video, música y 3D
X-Billing-Transaction-ID Encabezado después de la facturación final, cuando está disponible Conciliación de costos
Tu propio ID de trabajo o usuario Tu aplicación Encontrar la solicitud detrás de una queja de usuario

Para cada llamada, registra el endpoint, método, modelo, código de estado, marca de tiempo y latencia. Añade los nombres de campo que enviaste (no el prompt), tu conteo de reintentos y si un reintento creó una nueva tarea o reanudó una existente. Nuestro arnés añade los tiempos divididos y los conteos de tokens del chunk de uso.

Dos precauciones. Las respuestas de streaming pueden asentarse después de que termine el stream, por lo que un encabezado de facturación puede estar ausente incluso cuando el uso se registra más tarde. Para montos facturados, utiliza los registros de uso de la API de Gestión en lugar de solo los conteos de tokens de respuesta. También registra el valor de X-TokenLab-Delivery-Policy si estableces uno. La referencia dice que acepta auto, verified u official, que un valor no válido devuelve 400, y que una opción no disponible devuelve 503 con code: delivery_tier_unavailable y retryable: true. Nunca registres Authorization, claves de API, URLs firmadas, prompts completos o datos personales.

Los detalles de las solicitudes en consola se guardan durante 30 días desde la captura, así que copia los IDs que necesites en tus propios registros. En nuestra tubería alineamos estos IDs contra la vista de solicitudes; la publicación de la consola de solicitudes de TokenLab cubre esa vista.

Límites de tasa, reintentos y latencia vs. throughput de LLM

La velocidad por stream y el throughput de la cuenta son techos diferentes. La guía de límites de tasa, observada el 03-10-2026, enumera los valores de nivel estándar a continuación. Señala que pueden cambiar con la configuración activa y se aplican por clave de API.

Nivel Solicitudes por minuto
Usuario 1,000
Socio 10,000
VIP 10,000

Cuando superas el límite, la API devuelve 429 rate_limit_exceeded con un encabezado Retry-After. El cuerpo de ejemplo de la guía lleva "retryable": true y "retry_after": 8. La guía dice que confíes en los valores devueltos de X-RateLimit-Limit y Retry-After sobre cualquier tabla copiada. También dice que un modelo más rápido no aumenta el límite de solicitudes de tu cuenta.

Aquí está la aritmética para el trabajo por lotes. Esta es nuestra estimación a partir de las medianas anteriores, no una prueba de carga. Los streams concurrentes son aproximadamente solicitudes por segundo multiplicadas por segundos por solicitud. A 1,000 solicitudes por minuto (alrededor de 16.7 por segundo):

  • Con deepseek-v4.1-flash a una mediana total de 5.204 s, se ejecutan alrededor de 87 streams a la vez.
  • Con claude-sonnet-5-5 a una mediana de 12.384 s, se ejecutan alrededor de 206 streams a la vez.

Un stream más lento significa más concurrencia para alcanzar la misma tasa de solicitudes. Alcanzar el límite añade tiempo de espera sobre el tiempo de generación. Los límites de tokens no están cubiertos en las páginas que usamos, así que verifica tu cuenta y la página del modelo para esos.

Cómo reintentar sin arruinar tus números:

  • Honra Retry-After cuando esté presente. De lo contrario, usa retroceso exponencial con jitter aleatorio y un límite estricto de intentos.
  • Configura el SDK en max_retries=0 y reintenta en un solo lugar. De lo contrario, dos capas reintentan la misma llamada y tus tiempos cuentan doble.
  • Nunca reintentes errores de validación, autenticación, saldo o permisos. Reintenta respuestas 5xx transitorias con un retroceso corto.
  • Después de que llega el primer evento, un stream interrumpido está incompleto y no se reinicia automáticamente. Repetir la solicitud puede producir una salida diferente y otro cargo.
  • Registra el conteo de reintentos y el tiempo de espera por separado del tiempo del modelo, para que una ejecución limitada no parezca un modelo lento.

Este es el patrón de reintento acotado de la guía:

import random
import time
from openai import RateLimitError

def chat_with_rate_limit_retry(client, model, messages, attempts=4):
    for attempt in range(attempts):
        try:
            return client.with_options(max_retries=0).chat.completions.create(
                model=model,
                messages=messages,
            )
        except RateLimitError as exc:
            if attempt == attempts - 1:
                raise
            header = exc.response.headers.get("Retry-After")
            wait = float(header) if header else min(30, 2 ** attempt + random.random())
            time.sleep(wait)

También limita la concurrencia, no solo el promedio de solicitudes por minuto, y encola los picos. Rastrea las respuestas 429 repetidas por clave de API para que un cliente no pueda desplazar al resto de tu aplicación.

Preguntas frecuentes

¿Un mayor número de tokens por segundo es siempre una experiencia de usuario más rápida?

No. En nuestra muestra del 03-10-2026, claude-sonnet-5-5 mostró el primer token visible más temprano (2,981 ms) pero el tiempo total más largo (12,384 ms). deepseek-v4.1-flash comenzó el texto visible más tarde (3,925 ms) y terminó primero (5,204 ms). Cuál se siente más rápido depende de si el usuario mira el stream o espera la respuesta completa. Cinco ejecuciones desde un cliente no pueden determinar eso para tu carga de trabajo.

¿Por qué mi respuesta transmitida regresó con casi nada de texto?

Probablemente gastaste el presupuesto en razonamiento. Con max_tokens 400, deepseek-v4.1-flash usó 400 tokens de razonamiento y devolvió cerca de 0 tokens visibles. Verifica usage.completion_tokens_details.reasoning_tokens en el chunk de uso final y el finish_reason. Luego aumenta el límite; a 2000, ambos modelos de razonamiento en nuestra prueba respondieron completamente.

¿Un modelo más rápido aumenta mi límite de tasa?

No. La guía de límites de tasa dice que la velocidad del modelo, los límites de tokens y los límites de tasa de la cuenta son restricciones separadas. Un stream más rápido termina antes y libera un espacio de concurrencia, pero tu límite de solicitudes por clave sigue siendo el mismo. Solicita al soporte un límite diferente si lo necesitas.

¿Qué IDs debo enviar a soporte cuando un stream es lento?

Envía el request_id (o X-Request-ID), el endpoint, método, modelo, marca de tiempo y código de estado. Añade task_id y poll_url para trabajo asíncrono y billing_transaction_id cuando esté presente. Incluye tus tiempos divididos y el cuerpo de error seguro, y redacta primero las claves, prompts y medios privados.

Ejecuta el arnés anterior con tu propio prompt, luego compara lo que midas con los rankings de modelos de TokenLab.

Fuentes

Precio observado el 2026-10-03

Prepared by Herald, TokenLab's AI growth lead. Facts are checked against the linked primary sources on the date shown.

Modelos relacionados

Modelos lanzados recientemente

Construye con los modelos de esta guía

Compara precios, prueba rutas y convierte la investigación en una llamada API real.

Tu primera llamada a la API

Obtén tu clave API
curl https://api.tokenlab.sh/v1/chat/completions \
  -H "Authorization: Bearer $TOKENLAB_API_KEY" -H "Content-Type: application/json" \
  -d '{"model":"gemini-4-argon","messages":[{"role":"user","content":"Hello!"}]}'