Escolha Auto, TokenLab Verified ou Official para cada solicitação, com preços exibidos antecipadamente. Veja as novidades

Latência vs. Throughput de LLMs: Como compradores de API devem medir a velocidade

·19 de setembro de 2026·18 min de leitura·Atualizado 2 de outubro de 2026·2195 visualizações
#benchmark#api de ia#infraestrutura de modelo#TokenLab
Latência vs. Throughput de LLMs: Como compradores de API devem medir a velocidade

O modelo que exibiu seu primeiro token visível mais rapidamente em nosso teste mais recente também foi o mais lento para finalizar. Em 03/10/2026, transmitimos um prompt através de quatro modelos. O claude-sonnet-5-5 liderou no primeiro token visível (2.981 ms) e ficou para trás no tempo total (12.384 ms). Essa lacuna é o cerne da latência vs. throughput de LLMs: um número indica quanto tempo um usuário espera para ver o texto, outro indica quão rápido o trabalho é concluído. Este artigo define cada métrica, mostra nossas pequenas medições de primeira mão com suas limitações e fornece um mecanismo que você pode executar contra a API do TokenLab.

Principais conclusões

  • Três números, três funções. O tempo para o primeiro token, o tempo total e os tokens de saída por segundo respondem a perguntas diferentes. Chat, agentes e trabalho em lote dependem de métricas diferentes.
  • Separe o primeiro evento do primeiro token visível. No deepseek-v4.1-flash, as duas medianas tiveram uma diferença de 2.334 ms e 3.925 ms. Deltas de raciocínio podem chegar bem antes de qualquer texto visível.
  • Tokens de raciocínio consomem seu orçamento de max_tokens. Com max_tokens 400, o deepseek-v4.1-flash retornou cerca de 0 tokens visíveis e o gemini-3.8-flash cerca de 14. Em 2000, ambos responderam na íntegra.
  • Leia a contagem de tokens a partir do chunk de uso (usage chunk). Não os estime a partir de caracteres.
  • A velocidade do modelo não aumenta seu limite de requisições. Limites de taxa, limites de tokens e velocidade do modelo são restrições separadas.
  • Nossa amostra é pequena. Possui cinco execuções por modelo, um cliente, um prompt e um dia. Ela mostra como medir, não quem é o mais rápido.

Três números de velocidade: latência vs. throughput de LLM na prática

Divida a "velocidade" em partes, porque cada parte tem um responsável diferente: a rede, o modelo e sua própria fila.

send request
  -> first stream event          (qualquer chunk SSE; pode ser um delta de raciocínio)
  -> first visible content token (primeiro delta.content não vazio)
  -> last token + final usage chunk

Tempo para o primeiro token (TTFT) é o tempo desde o envio da requisição até a chegada do primeiro token. Registramos duas versões. O primeiro evento de stream é o primeiro chunk SSE de qualquer tipo. O primeiro token de conteúdo visível é o primeiro chunk cujo choices[0].delta.content não é vazio. Para modelos que raciocinam antes de responder, o primeiro evento pode ser um delta de raciocínio (delta.reasoning_content) que chega bem antes do texto visível. Um mecanismo que monitora apenas delta.content mede o tempo para o primeiro token visível, não o tempo para o primeiro byte. Os usuários sentem o visível.

Tempo total vai desde o envio da requisição até o final do stream. Inclui raciocínio, tempo de rede e qualquer espera de nova tentativa que você adicionar.

Tokens de saída por segundo são os tokens de saída divididos pelo tempo total. Obtenha a contagem de tokens de usage.completion_tokens, que inclui tokens de raciocínio. Dividimos pelo tempo total, não pela janela visível. Alguns modelos em nossa amostra entregaram texto visível em poucos chunks grandes, portanto, uma taxa baseada em janela seria enganosa.

Carga de trabalho Observe primeiro Depois Por que
Chat Primeiro token visível Tempo total O usuário olha para uma caixa em branco até que o texto visível apareça.
Agentes Tempo total Primeiro token visível Cada etapa geralmente espera pela anterior, então os totais por etapa se somam.
Extração ou resumos em lote Tokens de saída por segundo e custo por tarefa Margem do limite de requisições Ninguém observa o primeiro token, e o limite de requisições da conta limita a rapidez com que você pode enviar trabalho.

Chamadas sem streaming, como extração de JSON estruturado, expõem apenas o tempo total. Faça streaming delas nos testes se quiser a separação.

O que medimos em 03/10/2026

Método. Esta é uma medição de primeira mão do TokenLab, observada em 03/10/2026, contra POST https://api.tokenlab.sh/v1/chat/completions (fonte). Cada requisição usou stream=true e stream_options.include_usage=true. Executamos 5 rodadas sequenciais por modelo a partir de um único cliente no Leste Asiático, usando fetch do Node 24. O prompt foi "Explique como o HTTP keep-alive reduz a latência para clientes de API. Escreva cerca de 200 palavras." Todos os modelos usaram configurações padrão de raciocínio. Os tempos são de relógio do lado do cliente, e todas as execuções foram bem-sucedidas (5/5) para cada linha abaixo.

Modelo (max_tokens 2000) Mediana primeiro evento de stream Mediana primeiro token visível Mediana tempo total Mediana tokens de conclusão (raciocínio) 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 (não reportado) 34
gpt-5.6-luna 3.262 ms 3.262 ms 8.183 ms 313 (42) 38

A coluna tokens/s é nossa própria estimativa: mediana de tokens de conclusão dividida pela mediana de segundos totais, por exemplo 453 ÷ 5,204 ≈ 87. É uma razão de medianas, não uma mediana de taxas por execução.

O que os números mostram, e nada mais:

  • A ordenação pelo primeiro token visível (claude-sonnet-5-5, gpt-5.6-luna, deepseek-v4.1-flash, gemini-3.8-flash) difere da ordenação pelo tempo total (deepseek-v4.1-flash, gpt-5.6-luna, gemini-3.8-flash, claude-sonnet-5-5). Uma métrica não pode substituir a outra.
  • O deepseek-v4.1-flash teve uma lacuna de 1.591 ms entre o primeiro evento e o primeiro token visível. Sua saída visível mediana foi de cerca de 228 tokens, entregues em 87 eventos ao longo de 1.304 ms.
  • Para o gemini-3.8-flash, o primeiro evento e o primeiro token visível compartilham uma mediana de 6.892 ms. Seu texto visível veio em uma mediana de 11 eventos ao longo de 1.734 ms, então o stream foi "em blocos" em vez de token por token.
  • O claude-sonnet-5-5 enviou uma mediana de 371 eventos ao longo de 9.186 ms, e o gpt-5.6-luna enviou 265 eventos ao longo de 4.901 ms.

O custo acompanha a velocidade. Os preços abaixo vêm da API de modelos do TokenLab, observados em 03/10/2026, com preços atualizados em 02/10/2026T16:53:30.068Z. A última coluna é uma estimativa: mediana de tokens de conclusão vezes a taxa de saída, apenas do lado da saída. Verifique os registros de uso para cobranças reais.

Modelo Entrada por 1M Saída por 1M Max tokens de saída Estimativa lado da saída, rodada mediana Fonte
deepseek-v4.1-flash $0,15 fora de pico, $0,30 pico $0,60 fora de pico, $1,20 pico 384.000 453 × $0,60 / 1M ≈ $0,00027 fora 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 o gpt-5.6-luna, essas taxas se aplicam quando a entrada é de no máximo 272K tokens. Acima disso, a requisição completa usa 2x as taxas de entrada e 1,5x as taxas de saída.

Limites desta amostra. Cinco execuções sequenciais de um único cliente no Leste Asiático é uma fatia fina. O prompt foi um pedido de redação curta, então os resultados mudarão com a região, hora do dia, prompt e tamanho da saída. Não testamos concorrência, então nada disso diz o que acontece sob carga. Trate a tabela como um modelo para seu próprio teste, executado a partir da região onde as execuções de produção ocorrem. Se você quiser uma visão mais ampla dos modelos, o leaderboard de API de LLM do TokenLab para desenvolvedores é um ponto de partida. Verifique seu método e data antes de confiar em qualquer número de velocidade lá. Não troque modelos silenciosamente também: o guia de confiabilidade, observado em 03/10/2026, observa que uma substituição pode alterar qualidade, preço, tamanho de contexto e ferramentas.

Tokens de raciocínio e max_tokens: por que 400 retornou quase nada

Também executamos o mesmo prompt com max_tokens definido como 400. Mesmo método, mesmas cinco execuções, mesma data (fonte).

Modelo (max_tokens 400) Mediana tokens de conclusão Mediana tokens de raciocínio Saída visível (aprox.) Mediana primeiro token visível Mediana tempo 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 não reportado 400 tokens 3.088 ms 11.078 ms
gpt-5.6-luna 317 42 275 tokens 3.040 ms 8.083 ms

As medianas são calculadas por coluna, portanto, as colunas de uma linha não precisam descrever uma única execução. É por isso que o deepseek-v4.1-flash mostra um tempo para o primeiro visível ao lado de uma mediana de zero eventos visíveis.

A descoberta é clara. deepseek-v4.1-flash e gemini-3.8-flash gastaram quase todo o orçamento de 400 tokens em raciocínio e retornaram quase nenhum texto visível. Aumentar max_tokens para 2000 produziu respostas completas. Tokens de raciocínio contam dentro de usage.completion_tokens. Eles são relatados separadamente em usage.completion_tokens_details.reasoning_tokens.

Quando vimos o primeiro resultado de 400 tokens, a falha parecia uma resposta vazia, não um problema de orçamento. Três verificações a tornam visível:

  1. Leia o chunk de uso final, habilitado por stream_options={"include_usage": True}. Se reasoning_tokens estiver próximo de completion_tokens e o texto estiver vazio, o orçamento foi para o raciocínio.
  2. Verifique finish_reason. O guia de streaming (observado em 03/10/2026) lista length como o valor quando um limite de token é atingido.
  3. Compare com a saída máxima do modelo. Por exemplo, a API de modelo lista 384.000 para deepseek-v4.1-flash e 65.536 para gemini-3.8-flash, então 400 foi uma pequena fatia do que os modelos permitem.

A referência Create Chat Completion (observada em 03/10/2026) também lista max_completion_tokens e reasoning_effort. Ela diz que os valores suportados dependem do modelo, então leia a página do modelo antes de definir qualquer um deles. Não os testamos, e executamos cada linha com raciocínio padrão. Dimensione o limite a partir do seu próprio prompt: em nossa execução, uma resposta de 200 palavras produziu aproximadamente 228 a 418 tokens visíveis, e até 528 tokens de raciocínio além disso.

Um mecanismo de medição para a URL base do TokenLab

Este script usa a URL base do TokenLab, lê contagens de tokens do chunk de uso e registra o primeiro evento de stream separadamente do primeiro token de conteúdo visível. Ele também mantém cabeçalhos de resposta para depuração posterior. Ele segue as configurações de cliente nos docs (timeout=30.0, max_retries=0) para que o SDK não adicione novas tentativas ocultas aos seus tempos. O ID do modelo é um que medimos; substitua por qualquer ID cujos formatos de requisição aceitos incluam 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))

Algumas notas sobre a leitura da saída:

  • first_event_s dispara em qualquer chunk, incluindo um chunk apenas de função ou de raciocínio. first_visible_s dispara apenas em delta.content não vazio. Se os dois diferirem por segundos, o modelo está raciocinando antes de responder.
  • Contagens de tokens vêm do chunk de uso final. Esse chunk tem uma lista choices vazia, e é por isso que o loop verifica chunk.usage antes de pulá-lo.
  • Execute cinco vezes ou mais, registre a região e relate as medianas junto com o tamanho da amostra.
  • Para modelos que listam openai_responses, o guia de streaming mostra Responses fazendo streaming com eventos response.output_text.delta e response.completed. A mesma separação se aplica: cronometre o primeiro evento, depois o primeiro delta de texto.
  • Trate um stream que fecha antes de response.completed ou um motivo de finalização stop como incompleto, não como um sucesso rápido.

Cabeçalhos e identificadores para registrar para depuração de latência

Uma requisição lenta é difícil de depurar se você manteve apenas uma duração. A referência da API e o guia de solução de problemas, ambos observados em 03/10/2026, nomeiam os identificadores que vale a pena manter.

Identificador Onde aparece Use para
X-Request-ID Cabeçalho de resposta, quando disponível Suporte e depuração para uma requisição
request_id Corpos de erro, logs de dashboard, registros de uso Suporte em nível de requisição e reconciliação
X-Routing-Time-MS Cabeçalho de resposta, quando disponível Tempo gasto selecionando a entrega, antes da geração
X-Task-ID, task_id, poll_url Respostas de criação e status assíncronos Trabalhos de imagem, vídeo, música e 3D
X-Billing-Transaction-ID Cabeçalho após faturamento final, quando disponível Reconciliação de custos
Seu próprio job ou ID de usuário Sua aplicação Encontrar a requisição por trás de uma reclamação de usuário

Para cada chamada, registre o endpoint, método, modelo, código de status, timestamp e latência. Adicione os nomes dos campos que você enviou (não o prompt), sua contagem de novas tentativas e se uma nova tentativa criou uma nova tarefa ou retomou uma existente. Nosso mecanismo adiciona os tempos divididos e contagens de tokens do chunk de uso.

Dois cuidados. Respostas de streaming podem se estabilizar após o término do stream, então um cabeçalho de faturamento pode estar ausente mesmo quando o uso é registrado posteriormente. Para valores faturados, use os registros de uso da API de Gerenciamento em vez de apenas contagens de tokens de resposta. Registre também o valor de X-TokenLab-Delivery-Policy se você definir um. A referência diz que aceita auto, verified ou official, que um valor inválido retorna 400, e que uma opção indisponível retorna 503 com code: delivery_tier_unavailable e retryable: true. Nunca registre Authorization, chaves de API, URLs assinadas, prompts completos ou dados pessoais.

Os detalhes da requisição no console são mantidos por 30 dias a partir da captura, então copie os IDs que você precisa para seus próprios logs. Em nosso pipeline, alinhamos esses IDs com a visualização de requisições; o post do console de requisições do TokenLab cobre essa visualização.

Limites de taxa, novas tentativas e latência vs. throughput de LLM

A velocidade por stream e o throughput da conta são tetos diferentes. O guia de limites de taxa, observado em 03/10/2026, lista os valores de nível padrão abaixo. Ele observa que eles podem mudar com a configuração ativa e são aplicados por chave de API.

Nível Requisições por minuto
Usuário 1.000
Parceiro 10.000
VIP 10.000

Quando você ultrapassa o limite, a API retorna 429 rate_limit_exceeded com um cabeçalho Retry-After. O corpo do exemplo do guia carrega "retryable": true e "retry_after": 8. O guia diz para confiar nos valores retornados de X-RateLimit-Limit e Retry-After em vez de qualquer tabela copiada. Ele também diz que um modelo mais rápido não aumenta o limite de requisições da sua conta.

Aqui está a aritmética para trabalho em lote. Esta é nossa estimativa a partir das medianas acima, não um teste de carga. Streams simultâneos são aproximadamente requisições por segundo vezes segundos por requisição. A 1.000 requisições por minuto (cerca de 16,7 por segundo):

  • Com deepseek-v4.1-flash a uma mediana total de 5,204 s, cerca de 87 streams rodam ao mesmo tempo.
  • Com claude-sonnet-5-5 a uma mediana de 12,384 s, cerca de 206 streams rodam ao mesmo tempo.

Um stream mais lento significa mais concorrência para atingir a mesma taxa de requisição. Atingir o limite adiciona tempo de espera sobre o tempo de geração. Limites de tokens não são cobertos nas páginas que usamos, então verifique sua conta e a página do modelo para eles.

Como tentar novamente sem destruir seus números:

  • Respeite Retry-After quando presente. Caso contrário, use backoff exponencial com jitter aleatório e um limite rígido de tentativas.
  • Defina o SDK para max_retries=0 e tente novamente em um só lugar. Caso contrário, duas camadas tentarão novamente a mesma chamada e seus tempos serão contados em dobro.
  • Nunca tente novamente erros de validação, autenticação, saldo ou permissão. Tente novamente respostas 5xx transitórias com um backoff curto.
  • Após a chegada do primeiro evento, um stream interrompido está incompleto e não é reiniciado automaticamente. Repetir a requisição pode produzir uma saída diferente e outra cobrança.
  • Registre a contagem de novas tentativas e o tempo de espera separadamente do tempo do modelo, para que uma execução limitada não pareça um modelo lento.

Este é o padrão de nova tentativa limitada do guia:

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)

Limite também a concorrência, não apenas a média de requisições por minuto, e enfileire rajadas. Acompanhe respostas 429 repetidas por chave de API para que um cliente não possa sobrecarregar o restante da sua aplicação.

FAQ

Tokens por segundo mais altos são sempre uma experiência de usuário mais rápida?

Não. Em nossa amostra de 03/10/2026, o claude-sonnet-5-5 mostrou o primeiro token visível mais cedo (2.981 ms), mas o tempo total mais longo (12.384 ms). O deepseek-v4.1-flash iniciou o texto visível mais tarde (3.925 ms) e terminou primeiro (5.204 ms). Qual deles parece mais rápido depende se o usuário assiste ao stream ou espera pela resposta completa. Cinco execuções de um único cliente não podem definir isso para sua carga de trabalho.

Por que minha resposta de stream voltou com quase nenhum texto?

Você provavelmente gastou o orçamento em raciocínio. Com max_tokens 400, o deepseek-v4.1-flash usou 400 tokens de raciocínio e retornou cerca de 0 tokens visíveis. Verifique usage.completion_tokens_details.reasoning_tokens no chunk de uso final e o finish_reason. Em seguida, aumente o limite; em 2000, ambos os modelos de raciocínio em nosso teste responderam na íntegra.

Um modelo mais rápido aumenta meu limite de taxa?

Não. O guia de limites de taxa diz que a velocidade do modelo, limites de tokens e limites de taxa da conta são restrições separadas. Um stream mais rápido termina mais cedo e libera um slot de concorrência, mas seu limite de requisições por chave permanece o mesmo. Peça ao suporte um limite diferente se precisar.

Quais IDs devo enviar ao suporte quando um stream está lento?

Envie o request_id (ou X-Request-ID), o endpoint, método, modelo, timestamp e código de status. Adicione task_id e poll_url para trabalho assíncrono e billing_transaction_id quando presente. Inclua seus tempos divididos e o corpo do erro seguro, e redija chaves, prompts e mídia privada primeiro.

Execute o mecanismo acima em seu próprio prompt, depois compare o que você mediu com os rankings de modelos do TokenLab.

Fontes

Preço observado em 2026-10-03

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

← Voltar ao blog
Compartilhar:

Modelos relacionados

Modelos lançados recentemente

Crie com os modelos deste guia

Compare preços, teste rotas e transforme a pesquisa em uma chamada de API funcional.

Sua primeira chamada à API

Obtenha sua chave de 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!"}]}'