Os limites de taxa de LLM determinam quanto tráfego sua aplicação pode enviar a um modelo dentro de uma janela de tempo. Os dois limites que os engenheiros encontram com mais frequência são RPM (requests per minute) e TPM (tokens per minute). Uma carga de trabalho pode ficar abaixo de um e ainda assim exceder o outro.
Essa distinção importa. Se você tratar cada 429 como um problema genérico de contagem de requisições, pode adicionar tentativas que aumentam a pressão de tokens, elevam a latência e pioram uma indisponibilidade. Um design seguro para produção identifica primeiro o recurso limitado e, então, escolhe entre controle de ritmo, enfileiramento, novas tentativas, redução de tokens ou roteamento para outro lugar.
Este guia explica os mecanismos, fornece fórmulas de planejamento de capacidade e inclui um padrão de retry com limite para APIs compatíveis com OpenAI em TypeScript.
RPM vs. TPM: a resposta rápida
| Limite | Mede | Cargas de trabalho que o atingem primeiro | Melhor primeira resposta |
|---|---|---|---|
| RPM | Requisições admitidas durante uma janela de tempo definida pelo provedor | Muitas chamadas pequenas, loops de ferramentas de agentes, avaliações com alto fan-out | Controlar o ritmo das requisições, agrupar o trabalho ou enfileirar picos |
| TPM | Tokens de entrada e/ou saída admitidos durante uma janela de tempo | Contexto longo, saídas grandes, prompts com muita recuperação, avaliações paralelas | Reduzir o volume de tokens, limitar a saída ou rotear capacidade |
| RPD | Requisições por dia | Rastreios agendados, avaliações offline amplas, cargas de trabalho de plano gratuito | Reagendar ou aumentar o nível do serviço |
| Requisições concorrentes | Requisições em andamento ao mesmo tempo | Gerações lentas e cargas de trabalho de streaming | Limitar workers e aplicar backpressure |
| 429 | Uma política de limite ou capacidade rejeitou a requisição | Qualquer carga de trabalho que exceda um bucket ativo | Classificar o erro antes de tentar novamente |
RPM controla a frequência. TPM controla a vazão. A concorrência controla o trabalho simultâneo. Eles interagem, mas não são intercambiáveis.
Por que uma requisição pode falhar abaixo do limite principal
Um limite publicado, como 600 RPM, não significa necessariamente que um cliente possa enviar 600 requisições no primeiro segundo de cada minuto. Os provedores normalmente aplicam limites com janelas móveis ou controles no estilo token bucket. Um pico curto pode esgotar a capacidade imediatamente disponível mesmo quando a matemática do minuto inteiro parece segura.
Outros motivos pelos quais um 429 pode aparecer cedo incluem:
- O limite se aplica a um projeto, organização, conta, família de modelo ou nível de serviço, em vez de uma única chave de API.
- Tokens de entrada e saída usam buckets separados.
- Vários workers, serviços ou usuários compartilham o mesmo pool de cota.
- Tentativas de falhas anteriores estão consumindo o mesmo limite.
- O provedor está aplicando um limite de aceleração ou de burst enquanto o tráfego aumenta rapidamente.
- Um pool específico de modelo está cheio mesmo que outro modelo ainda tenha capacidade.
É por isso que a aplicação não deve inferir a causa apenas a partir de seu próprio contador de requisições. Leia o corpo da resposta e os cabeçalhos, preserve os IDs de requisição do provedor e registre o modelo, a conta, as estimativas de tokens, o número da tentativa e o atraso na fila.
Uma fórmula prática de capacidade
Comece com dois tetos independentes.
request_ceiling = RPM × safety_factor
token_ceiling = (TPM × safety_factor) ÷ average_tokens_per_request
safe_requests_per_minute = min(request_ceiling, token_ceiling)
Use um fator de segurança abaixo de 1.0 — por exemplo, 0.7 a 0.9 — para absorver a variação de tokens, retries, consumidores compartilhados e padrões de chegada desiguais.
Exemplo
Suponha que um pool de modelos permita:
- 1.000 RPM
- 2.000.000 TPM
- 4.000 tokens totais médios por requisição
- fator de segurança operacional de 80%
request_ceiling = 1,000 × 0.8 = 800 requests/minute
token_ceiling = (2,000,000 × 0.8) ÷ 4,000
= 400 requests/minute
safe_requests_per_minute = min(800, 400) = 400
TPM é a restrição limitante. Adicionar mais workers não aumentará a vazão sustentável; apenas criará uma fila maior ou mais respostas 429.
Para sistemas online, traduza a vazão em um ponto de partida de concorrência com a Lei de Little:
target_concurrency ≈ requests_per_second × average_request_seconds
Se a taxa segura for 400 requisições por minuto (6,67 por segundo) e a latência média do modelo for 3 segundos, uma concorrência inicial é de cerca de 20. Adicione margem com cuidado e depois ajuste com base na latência p95 real e nas distribuições de tokens.
Os limites de tokens frequentemente são o gargalo oculto
As equipes frequentemente monitoram contagens de requisições, mas ignoram o volume de tokens. A pressão de TPM aumenta quando você:
- Adiciona mais documentos recuperados a cada prompt.
- Mantém históricos longos de conversa.
- Executa várias conclusões candidatas por tarefa.
- Aumenta os limites de saída.
- Envia repetidamente o mesmo prompt de sistema grande.
- Inicia suítes de avaliação paralelas contra uma cota de projeto.
Meça pelo menos quatro valores de tokens por requisição bem-sucedida:
- Tokens de entrada.
- Tokens de saída.
- Tokens totais.
- Um p50, p95 e máximo em tempo real por carga de trabalho e modelo.
O planejamento de capacidade usando apenas a média é otimista. Um agendador mais seguro reserva com base em um percentil alto ou em uma estimativa específica da carga de trabalho e, em seguida, reconcilia a reserva com o uso real após a conclusão.
O que significa um 429 — e o que ele não significa
HTTP 429 Too Many Requests informa que o servidor rejeitou a requisição sob um limite ativo ou uma política de capacidade. Isso não significa automaticamente “aguarde um segundo e tente novamente”.
Classifique um 429 em uma categoria operacional:
| classe 429 | Evidência | Ação correta |
|---|---|---|
| Rajada curta | Pico recente; o cabeçalho de retry é curto; a fila, de resto, está saudável | Espere a indicação do servidor e, em seguida, tente novamente com jitter |
| Esgotamento sustentado de RPM | A taxa de requisições permanece perto do limite | Reduza o ritmo ou coloque em fila; tentativas sozinhas não conseguem corrigir isso |
| Esgotamento sustentado de TPM | A taxa de tokens está alta; prompts ou saídas longas predominam | Reduza os tokens, adie o trabalho ou encaminhe para outro pool elegível |
| Limite diário ou de nível | O erro identifica quota diária, faturamento ou restrição de nível | Pare as tentativas; reagende ou altere a capacidade da conta |
| Limite de aceleração | O tráfego aumentou rapidamente a partir de uma base baixa | Aumente gradualmente e suavize as rajadas |
| Evento de capacidade do provedor | Taxa normal do cliente, mas rejeição transitória repetida | Use um pequeno orçamento de retry e, depois, um fallback seguro para o contrato |
O corpo e os cabeçalhos diferem conforme o provedor. Prefira um sinal explícito Retry-After ou de redefinição do limite de taxa quando fornecido. Caso contrário, use backoff exponencial com jitter aleatório.
Backoff exponencial com jitter
O backoff exponencial aumenta o atraso após cada tentativa malsucedida. O jitter randomiza esse atraso para que centenas de trabalhadores não tentem novamente no mesmo instante.
Uma fórmula comum de full-jitter é:
delay_ms = random(0, min(cap_ms, base_ms × 2^attempt))
Uma política de retry em produção também precisa de limites:
- Máximo de tentativas: geralmente um número pequeno, não um loop infinito.
- Tempo máximo decorrido: pare quando o orçamento de latência do chamador se esgotar.
- Lista de status passíveis de retry: comumente
429, respostas5xxselecionadas e falhas de rede seguras. - Dicas do servidor: respeite
Retry-Afterquando ele for válido. - Cancelamento: pare imediatamente quando a requisição upstream for abortada.
- Observabilidade: registre a contagem de tentativas, o tempo de espera, o status final e o ID da requisição do provedor.
Requisições malsucedidas ainda podem consumir capacidade do limite de taxa. Tentativas agressivas podem, portanto, estender o período de limitação.
TypeScript: um helper de retry com limites
O exemplo a seguir usa a URL base Flatkey compatível com OpenAI. Ele tenta novamente apenas antes que o corpo de uma resposta bem-sucedida seja consumido e para quando o limite de tentativas ou o orçamento total de tempo se esgota.
type ChatRequest = {
model: string;
messages: Array<{ role: "system" | "user" | "assistant"; content: string }>;
max_tokens?: number;
};
const sleep = (milliseconds: number) =>
new Promise((resolve) => setTimeout(resolve, milliseconds));
function retryAfterMilliseconds(response: Response): number | null {
const value = response.headers.get("retry-after");
if (!value) return null;
const seconds = Number(value);
if (Number.isFinite(seconds)) return Math.max(0, seconds * 1_000);
const date = Date.parse(value);
return Number.isNaN(date) ? null : Math.max(0, date - Date.now());
}
export async function createChatCompletion(
apiKey: string,
request: ChatRequest,
options: { maxAttempts?: number; maxElapsedMs?: number } = {},
) {
const maxAttempts = options.maxAttempts ?? 4;
const maxElapsedMs = options.maxElapsedMs ?? 30_000;
const startedAt = Date.now();
for (let attempt = 0; attempt < maxAttempts; attempt += 1) {
const response = await fetch(
"https://router.flatkey.ai/v1/chat/completions",
{
method: "POST",
headers: {
Authorization: `Bearer ${apiKey}`,
"Content-Type": "application/json",
},
body: JSON.stringify(request),
},
);
if (response.ok) return response.json();
const retryable = response.status === 429 || response.status >= 500;
const finalAttempt = attempt === maxAttempts - 1;
if (!retryable || finalAttempt) {
throw new Error(`A requisição LLM falhou com ${response.status}: ${await response.text()}`);
}
const hintedDelay = retryAfterMilliseconds(response);
const exponentialCap = Math.min(8_000, 500 * 2 ** attempt);
const jitteredDelay = Math.random() * exponentialCap;
const delayMs = hintedDelay ?? jitteredDelay;
if (Date.now() + delayMs - startedAt >= maxElapsedMs) {
throw new Error("Orçamento de tentativas da LLM esgotado");
}
await sleep(delayMs);
}
throw new Error("Estado de tentativa inalcançável");
}
Para uso em produção, adicione timeouts de requisição, tipos de erro estruturados, métricas e o sinal de cancelamento da sua aplicação. Se a operação puder criar efeitos colaterais externos — como enviar um e-mail ou executar uma ferramenta — torne a operação de negócio idempotente antes de tentar novamente.
Retentar, enfileirar, reduzir ou rotear?
Use a causa, não apenas o código de status, para escolher o controle.
| Situação | Retentativa | Fila | Reduzir tokens | Encaminhar para outro lugar |
|---|---|---|---|---|
Um único 429 transitório isolado |
Sim, com limite | Opcional | Não | Normalmente não |
| Esgotamento repetido de RPM | Limitado | Sim | Não | Às vezes |
| Esgotamento repetido de TPM | Limitado | Sim | Sim | Frequentemente útil |
| Cota diária esgotada | Não | Para depois | Opcional | Sim, se a política permitir |
Incidente 5xx do provedor |
Sim, com limite | Sim | Não | Sim após o orçamento de tentativas |
| Resposta de streaming parcial | Sem repetição automática | Específico da aplicação | Não | Somente com semântica explícita de recuperação |
Retentativa
Refaça a tentativa quando a falha for transitória e o chamador ainda tiver tempo. Mantenha um orçamento de retentativas por solicitação e um orçamento de retentativas no nível do serviço para que um incidente do provedor não multiplique o tráfego total.
Fila
Use fila quando a taxa de chegada exceder temporariamente a taxa de serviço sustentável. Uma fila útil expõe:
- Idade do item mais antigo.
- Horário estimado de início.
- Justiça por locatário.
- Cancelamento para trabalhos obsoletos.
- Uma profundidade máxima com comportamento explícito de descarte.
Reduzir tokens
Quando o TPM limita, remova contexto irrelevante, resuma o histórico, reduza a contagem de candidatos, diminua os limites de saída, armazene em cache prefixos reutilizáveis de prompts quando suportado e separe o tráfego interativo curto de trabalhos em lote longos.
Encaminhar para outro lugar
O encaminhamento é apropriado quando outro modelo ou provedor atende ao mesmo contrato e tem capacidade saudável. O fallback deve preservar recursos necessários como saída estruturada, chamada de ferramentas, comprimento de contexto, política de segurança e meta de latência. Para uma estrutura de implementação mais aprofundada, use o manual de fallback e roteamento de API de LLM.
Limites de taxa em avaliações de modelos
Um controle inadequado de taxa pode invalidar uma avaliação.
Suponha que o modelo A seja testado com 10 workers enquanto o modelo B seja testado com 100. Se o modelo B passar mais tempo sendo limitado, sua latência medida inclui enfileiramento e atraso de tentativas que o modelo A nunca enfrentou. O resultado pode descrever a configuração do seu harness em vez do desempenho do modelo.
Para comparações defensáveis:
- Separe latência do modelo, atraso de fila e atraso de retentativa.
- Aplique o mesmo processo de chegada ou o mesmo nível normalizado de utilização a cada provedor.
- Aqueça o tráfego gradualmente quando os provedores usarem controles de aceleração.
- Registre tokens e tentativas por tarefa concluída.
- Relate tanto a taxa de sucesso na primeira tentativa quanto a taxa de sucesso eventual.
- Compare o custo por tarefa aceita, não apenas o custo por token.
- Execute testes de sobrecarga separadamente dos benchmarks de qualidade e latência.
Se você estiver avaliando provedores com foco em confiabilidade e custo, combine este processo com a comparação de preços de API de IA.
Uma arquitetura de limite de taxa para produção
Um caminho de requisição robusto normalmente tem cinco camadas de controle:
- Controle de admissão rejeita ou adia trabalhos que não podem cumprir seu prazo.
- Reserva de tokens estima o provável custo de quota da requisição.
- Limitador de taxa regula o ritmo de cada provedor, pool de modelos, tenant e classe de prioridade.
- Controlador de tentativas consome um orçamento limitado de tentativas com jitter.
- Roteador seleciona uma alternativa compatível com o contrato depois que o orçamento de tentativas ou a política de capacidade diz para mudar.
client
→ admission control
→ priority queue
→ RPM + token reservation limiter
→ provider/model route
→ bounded retry
→ contract-safe fallback
→ usage and latency logs
Não coloque um loop de tentativas ilimitado em cada worker da aplicação. Centralize a política para que todos os chamadores compartilhem a mesma compreensão da capacidade disponível.
Métricas que valem alertas
Acompanhe estas por provedor, modelo, projeto, rota, tenant e carga de trabalho:
- Requisições por minuto e tokens por minuto.
- Tokens estimados reservados versus tokens efetivamente usados.
- Taxa de sucesso na primeira tentativa.
- Tentativas por requisição bem-sucedida.
- Taxa de
429por causa classificada. - Profundidade da fila e idade do item mais antigo.
- Tempo gasto aguardando capacidade de taxa.
- Latência ponta a ponta p50, p95 e p99.
- Taxa de fallback e resultado do fallback.
- Custo por tarefa bem-sucedida ou aceita.
Um alerta apenas sobre a contagem total de 429 é ruidoso. Um sinal melhor combina a taxa de limitação com a idade da fila, a amplificação por tentativas e a taxa final de falha.
Erros comuns
Tratar RPM como um limite de concorrência
RPM mede admissões ao longo do tempo; concorrência mede trabalho em execução. Requisições lentas podem criar alta concorrência com um RPM modesto.
Repetir imediatamente todo 429
Tentativas imediatas sincronizam workers e consomem mais capacidade. Respeite o tempo do servidor quando उपलब्धo e adicione jitter.
Usar um único limitador para cada modelo
Os provedores podem usar pools separados ou compartilhados. A política específica do modelo deve seguir o escopo de quota documentado pelo provedor e os cabeçalhos observados.
Ignorar consumidores compartilhados
Um dashboard, um job em lote e uma API de produção podem compartilhar uma única quota de projeto. Reserve capacidade por carga de trabalho e isole o tráfego crítico quando possível.
Repetir um stream parcial
Depois que os tokens chegam ao usuário, repetir a requisição pode duplicar conteúdo ou ações de ferramentas. Defina semânticas explícitas de continuação ou reinício em vez de repetir silenciosamente.
Como a Flatkey muda o modelo operacional
A Flatkey fornece uma chave de API e uma URL base compatível com a OpenAI para acesso em provedores de modelos suportados. Isso dá à aplicação uma superfície de integração única, ao mesmo tempo em que permite que a política de roteamento considere adequação do modelo, capacidade, confiabilidade e custo.
O gateway não remove os limites do upstream. Ele facilita a implementação de controles consistentes em torno deles: uma integração de cliente, logs de solicitações centralizados e a opção de mover tráfego elegível quando uma rota está restrita. Consulte o guia de arquitetura de gateway de API de IA para o design de roteamento mais amplo, ou veja os preços atuais da Flatkey antes de selecionar rotas de produção.
FAQ
Qual é a diferença entre RPM e TPM?
RPM limita quantas solicitações são admitidas ao longo do tempo. TPM limita quantos tokens de entrada e/ou saída são admitidos. Prompts pequenos geralmente pressionam primeiro o RPM; cargas de trabalho com grande contexto ou alta geração de saída frequentemente pressionam primeiro o TPM.
Por que recebo erros 429 abaixo do meu limite de RPM?
O provedor pode impor janelas móveis mais curtas, buckets de tokens, cotas de projeto compartilhadas, limites separados de tokens, limites de aceleração ou pools específicos por modelo. Seu contador local de solicitações pode não representar o escopo total da cota.
Devo tentar novamente todo 429?
Não. Tente novamente um throttling de curta duração com um pequeno orçamento e jitter. Não faça novas tentativas repetidas para esgotamento de cota diária, restrições de faturamento ou sobrecarga sustentada que não tenha tempo para se recuperar.
O backoff exponencial garante sucesso?
Não. O backoff reduz a colisão e dá tempo para que a capacidade transitória se recupere. Ele não pode criar cota. O esgotamento persistente exige menor demanda, mais capacidade, trabalho adiado ou outra rota elegível.
Quantas tentativas uma solicitação de LLM deve usar?
Não existe um número universal. Defina as tentativas com base no orçamento de latência visível ao usuário e no modo de falha. Muitas aplicações interativas devem permitir apenas algumas tentativas curtas antes de falhar ou encaminhar por outro caminho; jobs offline podem tolerar filas mais longas.
As tentativas contam contra os limites de taxa?
Podem contar. Os provedores podem contabilizar tentativas malsucedidas nos limites ativos, então a amplificação por retry deve ser monitorada e limitada.
Lista de verificação final
- Modele RPM, TPM, limites diários e concorrência separadamente.
- Calcule a capacidade a partir do mínimo entre os limites de solicitações e de tokens.
- Opere abaixo do máximo publicado com um fator de segurança.
- Use filas e cadência para carga sustentada.
- Respeite
Retry-Aftere use backoff exponencial com jitter. - Limite as tentativas e o tempo total de retry.
- Não reproduza automaticamente streams parciais ou efeitos colaterais.
- Encaminhe apenas para modelos que preservem o contrato exigido.
- Separe o atraso de fila e retry da latência do modelo nas avaliações.
- Emita alertas sobre a amplificação de retries e a idade da fila, não apenas sobre contagens brutas de
429.
Limites de taxa são antes um problema de planejamento de capacidade do que um problema de retry. Quando você mede separadamente a frequência de solicitações, o throughput de tokens, a concorrência e a amplificação de retry, os erros 429 se tornam sinais acionáveis em vez de ruído imprevisível em produção.



