Quantas requisições simultâneas seu LLM na VPS aguenta? Como configurar batching, fila e medir tokens por segundo

Descobrir quantas requisições simultâneas LLM VPS aguenta não é questão de tabela pronta, é configuração mais medição. No vLLM tu define o teto de concorrência com max_num_seqs, o contexto por requisição com max_model_len e o KV cache através de gpu_memory_utilization. No Ollama, o controle vem de OLLAMA_NUM_PARALLEL e OLLAMA_MAX_QUEUE. Depois de configurar, mede: no vLLM com vllm bench serve (TTFT, throughput, TPOT, ITL) e no Ollama pelos campos de timing da API. Número de terceiro em hardware diferente não serve pro teu caso
Fala aí, beleza? Aquele modelo que voava sozinho na tua VPS, respondendo lisinho enquanto só tu usava, engasga feio quando cinco pessoas apertam enter ao mesmo tempo
E isso não é bug, é comportamento esperado de um servidor de inferência que ninguém configurou pra concorrência
A questão "qual VPS aguenta rodar meu modelo" é uma pergunta de DIMENSIONAMENTO DE HARDWARE pra uma sessão: cabe na VRAM, roda numa velocidade aceitável, beleza
Esta pauta aqui é outra pergunta: capacidade de ATENDIMENTO concorrente
É a diferença entre "cabe" e "atende um time". Tem parâmetro próprio, tem fila, tem métrica própria e tem jeito certo de medir
Bora entender?
O que muda quando chega a segunda requisição ao mesmo tempo
A intuição errada é imaginar o servidor como uma fila de banco: atende o primeiro, termina, chama o próximo
Não é assim que funciona
O servidor moderno de inferência agrupa requisições em ITERAÇÕES do scheduler. A cada passo ele decide quais sequências vão avançar juntas, e requisições novas entram no meio do agrupamento em vez de esperar as anteriores acabarem inteiras
Isso é o batching contínuo
Que KV cache é esse?
Toda sequência em andamento guarda estado na memória da GPU, o KV cache
E aqui mora o acoplamento que quebra a cabeça de quem tá começando: a necessidade de KV cache é função de quantas sequências tu quer em paralelo E do quanto de contexto cada uma pode usar
Ou seja, os três parâmetros que tu vai mexer no vLLM (número de sequências, comprimento de contexto e fração de memória pré-alocada) não são independentes
Eles disputam o MESMO recurso
No vLLM, a documentação aponta o PagedAttention como o mecanismo de gerenciamento de memória que, junto com técnicas de scheduler como o batching, sustenta o throughput
Os dois níveis de concorrência do Ollama
O Ollama descreve a concorrência em dois níveis, e confundir os dois é erro clássico
- Entre modelos carregados: vários modelos ficam na memória ao mesmo tempo, se houver RAM de sistema (CPU) ou VRAM (GPU) disponível
- Dentro de um mesmo modelo: um modelo já carregado processando várias requisições em paralelo
São controles diferentes, com variáveis de ambiente diferentes. Já volto neles
Hospedagem que aguenta seu projeto crescer
Hospedagem rápida, painel simples, backups automáticos e suporte 24/7 em português.
O vocabulário que tu vai ver o resto do post inteiro
Antes de configurar qualquer coisa, precisa saber o que tá olhando:
| Métrica | O que é |
|---|---|
| TTFT (Time to First Token) | Quanto tempo até o primeiro token aparecer pro usuário |
| TPOT (Time per Output Token) | Tempo por token de saída |
| ITL (Inter-token Latency) | Latência entre tokens |
| Output token throughput | Tokens de saída por segundo |
| Request throughput | Requisições por segundo |
Guarda esses nomes, porque eles são literalmente o que o benchmark do vLLM cospe na tela
E são eles que decidem se tua configuração ficou boa ou ruim, não o "feeling" de rodar um prompt e achar rápido
Antes de mexer na concorrência: o que você precisa ter pronto
Esse post assume que o modelo JÁ está de pé
Se tu ainda tá no passo anterior, de escolher máquina e subir o serviço, resolve isso primeiro: lá a pergunta é de hardware, aqui é de configuração
Checklist do que precisa estar na mão:
- Modelo servido na VPS com vLLM ou Ollama
- Acesso ao servidor pra editar variáveis de ambiente (Ollama) ou flags de inicialização (vLLM)
- Dependências de benchmark do vLLM instaladas, se tu for medir nessa stack
pip install "vllm[bench]"
Duas coisas importantes antes de sair mexendo
Primeira: mudar esses parâmetros exige reiniciar o servidor. Não é hot reload, não é config que tu troca com o serviço no ar
Segunda, e essa é a que pega geral: MEDE ANTES
Se tu não tem o número de partida, tu não tem como saber se o ajuste melhorou ou piorou. Vai ficar no achismo, e achismo em benchmark é só opinião com terminal aberto
Tome cuidado com isso
Como configurar concorrência no vLLM: max_num_seqs, contexto e KV cache
A ordem importa aqui, porque cada parâmetro come memória do próximo
- Defina
max_num_seqs, o teto real de concorrência
Esse parâmetro define o número máximo de sequências processadas em uma única iteração do scheduler
Traduzindo: é quantas requisições o servidor consegue ter avançando ao mesmo tempo
O default mudou entre versões: era 256 no vLLM V0 e passou pra 1024 no V1
vllm serve SEU_MODELO --max-num-seqs 64
O erro comum deste passo: subir max_num_seqs achando que é só "liberar mais usuários". Sem KV cache pra sustentar essas sequências, tu só empurra o problema pra frente, porque o tamanho do KV cache é o que limita quantas sequências concorrentes o vLLM consegue processar antes de estourar a memória
- Defina
max_model_len, o teto de tokens por requisição
Esse limita o comprimento máximo de contexto do modelo, contando tokens de ENTRADA mais tokens GERADOS na mesma requisição
É prompt + saída somados, não só o prompt
vllm serve SEU_MODELO --max-num-seqs 64 --max-model-len 8192
O erro comum deste passo: pedir contexto gigante "por garantia" e derrubar a concorrência sem perceber. Como a necessidade de KV cache é função de max_num_seqs E max_model_len, contexto folgado demais rouba o espaço que você queria usar pra atender mais gente
- Ajuste
gpu_memory_utilization
Esse define a fração da memória da GPU pré-alocada pelo engine, indo de 0.0 a 1.0, com default 0.9
E essa fração é exatamente o que determina o tamanho do KV cache
vllm serve SEU_MODELO \
--max-num-seqs 64 \
--max-model-len 8192 \
--gpu-memory-utilization 0.9
Então é aqui que o triângulo fecha: gpu_memory_utilization define o KV cache, e o KV cache é o recurso disputado por max_num_seqs e max_model_len
Mexeu num, os outros dois sentem
O erro comum deste passo: tratar os três como configurações separadas em abas diferentes da cabeça. Eles são um sistema só
- Ajuste
max_num_batched_tokensconforme o OBJETIVO
Esse parâmetro define o máximo de tokens processados em uma única iteração, funcionando como orçamento de tokens por passo do scheduler
O default é 2048, e a doc do vLLM aponta esse valor como otimizado pra ITL, a latência entre tokens
E recomenda valores maiores que 2048 quando o objetivo é throughput
vllm serve SEU_MODELO --max-num-batched-tokens 4096
Repara que subir esse número não é "destravar performance", é uma ESCOLHA
Latência entre tokens boa (resposta fluindo suave pro usuário) ou volume total de tokens saindo do servidor? Dificilmente tu maximiza os dois ao mesmo tempo
O erro comum deste passo: subir o orçamento de tokens num caso de uso interativo e estranhar que a resposta ficou "mais travadinha" pro usuário final
- Entenda o chunked prefill antes de culpar a máquina
O chunked prefill quebra prefills grandes em pedaços e agrupa eles junto com requisições que já estão em decode
A política é clara: DECODE TEM PRIORIDADE
O scheduler agenda todas as requisições pendentes de decode antes de agendar prefill, e o prefill que não couber no orçamento de max_num_batched_tokens é fatiado
Isso explica um comportamento que parece esquisito: quem já tá recebendo tokens continua recebendo, enquanto quem acabou de chegar com um prompt enorme espera um pouquinho mais pro primeiro token
Não é lentidão aleatória, é política de agendamento
O erro comum deste passo: interpretar TTFT alto em prompt gigante como "VPS fraca" quando é o orçamento de tokens por iteração conversando com a prioridade de decode
Como configurar concorrência no Ollama: OLLAMA_NUM_PARALLEL e OLLAMA_MAX_QUEUE
No Ollama o controle é por variável de ambiente, o que deixa tudo mais simples de setar e MAIS FÁCIL de esquecer que existe
OLLAMA_NUM_PARALLEL: requisições paralelas por modelo
Define o número máximo de requisições paralelas que cada modelo processa ao mesmo tempo
O FAQ oficial atual documenta o default como 1
Lê de novo: UM
export OLLAMA_NUM_PARALLEL=4
O erro comum deste passo: montar um produto com vários usuários em cima de um servidor que, na configuração de fábrica, processa uma requisição por vez naquele modelo
- Faça a conta de memória antes de subir esse número
A documentação do Ollama é explícita: a RAM necessária escala pelo PRODUTO OLLAMA_NUM_PARALLEL * OLLAMA_CONTEXT_LENGTH
O exemplo é da própria doc: um contexto de 2K com 4 requisições paralelas resulta em 8K de contexto e alocação adicional de memória
Então paralelismo não é de graça, ele multiplica contexto
É a mesma lógica do KV cache do vLLM, só que exposta de um jeito diferente
O erro comum deste passo: subir OLLAMA_NUM_PARALLEL sem revisar o contexto, e aí a memória some sem explicação aparente
OLLAMA_MAX_QUEUE: a fila quando o servidor tá ocupado
Essa define o número máximo de requisições que o servidor enfileira quando está ocupado, antes de RECUSAR novas requisições
O default é 512
export OLLAMA_MAX_QUEUE=512
E quando estoura? O servidor responde com HTTP 503, indicando servidor sobrecarregado
Esse 503 é informação valiosa, não é só erro chato: é o teu servidor avisando exatamente onde bateu o teto
O erro comum deste passo: inflar a fila achando que resolve. Fila maior não processa mais rápido, ela só troca "erro na cara do usuário" por "usuário esperando muito tempo". Às vezes o 503 honesto é melhor
OLLAMA_MAX_LOADED_MODELS: quantos modelos ficam na memória
Define o máximo de modelos carregados simultaneamente, desde que caibam na memória disponível
O default é 3 × número de GPUs, ou 3 na inferência em CPU
export OLLAMA_MAX_LOADED_MODELS=2
E aqui tem um comportamento que confunde MUITO na hora do debug: se não houver memória suficiente pra carregar um novo modelo enquanto outros já estão carregados, o Ollama enfileira TODAS as novas requisições até que o novo modelo possa ser carregado
O espaço vai liberando conforme modelos anteriores ficam ociosos e são descarregados
O erro comum deste passo: ver requisições paradas na fila e sair mexendo em OLLAMA_NUM_PARALLEL, quando o problema real era memória pra carregar mais um modelo
Como medir: benchmark com vllm bench serve e os campos de timing do Ollama
Agora a parte que separa configuração de ACHISMO
Medindo no vLLM
O vLLM traz comandos de benchmark no próprio CLI: vllm bench latency, vllm bench serve e vllm bench throughput
Pra carga concorrente de serving online, o que interessa é o vllm bench serve: o servidor roda com vllm serve e o cliente roda vllm bench serve
Dois processos, duas pontas
# terminal 1: servidor
vllm serve SEU_MODELO
# terminal 2: cliente de benchmark
vllm bench serve --request-rate 10 --max-concurrency 32
As flags que moldam o padrão de carga, segundo a doc:
--request-rate: requisições por segundo alvo, ouinfpra buscar throughput máximo--burstiness: variabilidade do tráfego, via distribuição Gamma--max-concurrency: limita o número de requisições concorrentes em aberto
A sacada é usar essas três pra IMITAR o teu tráfego real, não pra gerar o número mais bonito possível
Tráfego de produto não chega em ritmo constante de metrônomo, ele chega em rajada. Por isso --burstiness existe
O que ler na saída:
| Campo | Pra que serve |
|---|---|
| Mean / Median / P99 TTFT (ms) | Quanto o usuário espera pelo primeiro token, incluindo o pior caso |
| Request throughput (req/s) | Requisições atendidas por segundo |
| Output token throughput (tok/s) | Volume de tokens saindo do servidor |
| TPOT | Tempo por token de saída |
| ITL | Latência entre tokens |
Repara no P99 de TTFT
A média engana: dá pra ter média linda e uma fatia dos usuários esperando um tempão. O P99 é quem conta essa história
O erro comum deste passo: rodar o benchmark com carga de uma requisição só e concluir que a VPS "aguenta". Requisição única não testa scheduler, não testa fila e não testa KV cache sob pressão
Medindo no Ollama
Aqui o caminho documentado é diferente: as respostas da API do Ollama trazem campos de medição de desempenho embutidos
São eles: total_duration, load_duration, prompt_eval_count, prompt_eval_cached_count, prompt_eval_duration, eval_count e eval_duration
Detalhe que já derrubou muita conta errada: os valores de tempo vêm em NANOSSEGUNDOS
Esses campos são retornados por endpoints incluindo /api/generate, /api/chat e /api/embed
curl http://localhost:11434/api/generate -d '{
"model": "SEU_MODELO",
"prompt": "Explique o que e batching continuo",
"stream": false
}'
Com eval_count (tokens gerados) e eval_duration (tempo de geração) tu deriva os tokens por segundo do TEU ambiente
E é isso que vale: número do teu hardware, do teu modelo, da tua configuração
O erro comum deste passo: pegar tokens por segundo de um post aleatório, com outra GPU, outra quantização e outro tamanho de contexto, e usar como meta. Comparação de hardware diferente não é benchmark, é folclore
Quantos usuários seu cenário pede: time interno, produto com picos e lote
Não existe configuração universal porque não existe carga universal
O que existe é: qual métrica o TEU cenário precisa otimizar
Time interno, poucos usuários
Aqui a prioridade é TTFT baixo e ITL confortável
São poucas pessoas, cada uma quer sentir a resposta começando rápido e fluindo. Throughput total é secundário, ninguém tá processando volume
É o cenário onde o orçamento de tokens por iteração otimizado pra ITL faz mais sentido
Produto exposto, tráfego irregular
Esse é o mais traiçoeiro
O tráfego chega em rajada, e o que quebra a experiência não é a média, é a CAUDA: o P99 de TTFT e o comportamento da fila quando o pico bate
Aqui tu precisa simular a rajada antes dela acontecer de verdade, com --burstiness e --max-concurrency no vllm bench serve
E no Ollama, saber exatamente quando começa o 503 é parte do dimensionamento, não um acidente
Vale lembrar que rajada também expõe outras camadas da infra. Se tua base de usuários tá longe da máquina, a escolha do datacenter da VPS entra na conta da latência percebida junto com o TTFT do modelo
Processamento em lote
Ninguém tá olhando a tela esperando token aparecer
A prioridade vira output token throughput: quantos tokens de saída por segundo a máquina consegue cuspir no total
É o cenário onde a doc do vLLM recomenda orçamento de tokens por iteração maior que 2048
Resumindo o raciocínio:
| Cenário | Métrica principal | O que ajustar com esse objetivo |
|---|---|---|
| Time interno | TTFT e ITL | Orçamento de tokens por iteração voltado a ITL |
| Produto com picos | P99 de TTFT e fila | Simular com --burstiness e --max-concurrency, revisar fila |
| Lote | Output token throughput | Orçamento de tokens por iteração maior |
Sinais de que sua VPS estourou o limite de concorrência
Sintoma, causa configurável e prevenção. Sem adivinhação
Sintoma: HTTP 503 no Ollama
Causa: a fila encheu. O Ollama responde 503 indicando servidor sobrecarregado quando requisições demais são enviadas
Onde olhar: OLLAMA_MAX_QUEUE (default 512) e OLLAMA_NUM_PARALLEL (default 1 no FAQ atual)
Prevenção: revisar o paralelismo por modelo ANTES de inflar a fila, lembrando que RAM escala pelo produto de paralelismo por contexto
Sintoma: requisições enfileiradas e paradas, sem 503
Causa provável: memória insuficiente pra carregar um novo modelo enquanto outros já estão carregados. Nesse caso o Ollama enfileira todas as novas requisições até liberar espaço, o que acontece conforme modelos anteriores ficam ociosos e são descarregados
Onde olhar: OLLAMA_MAX_LOADED_MODELS (default 3 × número de GPUs, ou 3 em CPU)
Prevenção: limitar quantos modelos distintos o servidor precisa manter vivos ao mesmo tempo
Sintoma: erro de memória ao subir o vLLM com contexto e concorrência altos
Causa: o triângulo do KV cache. A necessidade de KV cache é função de max_num_seqs e max_model_len, e o tamanho disponível é determinado por gpu_memory_utilization
Prevenção: mexer num parâmetro por vez e medir. Se precisa de mais concorrência, alguma coisa precisa ceder: contexto por requisição ou memória alocada
Sintoma: TTFT alto com throughput até que bom
Causa: orçamento de tokens por iteração e chunked prefill. O scheduler prioriza decode, agenda todas as pendentes de decode antes do prefill, e fatia o prefill que não couber no orçamento de max_num_batched_tokens
Prevenção: se o cenário é interativo, lembrar que o default de 2048 é otimizado pra ITL e que subir esse orçamento é uma escolha por throughput
Ou seja: throughput bom com TTFT alto pode ser exatamente a configuração fazendo o que tu pediu
Pra ver IA aplicada ao código na prática
Pra quem quer expandir o uso de IA no dia a dia de desenvolvimento além da infraestrutura, este vídeo do canal mostra uma skill que faz a IA ler seu código e desenhar a arquitetura sozinha
Conclusão
Capacidade concorrente não sai de tabela pronta
Sai de duas coisas: CONFIGURAÇÃO (os parâmetros certos, entendendo que eles disputam o mesmo recurso) e MEDIÇÃO (número do teu ambiente, não de um post com hardware diferente)
No vLLM tu tem max_num_seqs como teto de concorrência, max_model_len como teto de tokens por requisição, gpu_memory_utilization definindo o KV cache e max_num_batched_tokens como orçamento por iteração
No Ollama tu tem OLLAMA_NUM_PARALLEL, OLLAMA_MAX_QUEUE, OLLAMA_MAX_LOADED_MODELS e a conta de memória que multiplica paralelismo por contexto
Próximo passo é simples e chato do jeito certo: roda o benchmark na tua própria VPS ANTES e DEPOIS de cada ajuste
Registra TTFT e tokens por segundo em cada rodada, muda um parâmetro por vez
Em duas ou três iterações tu vai saber, com número na mão, quantos usuários simultâneos tua máquina atende de verdade
E se a conclusão for que o gargalo não é configuração e sim hardware, aí a conversa volta pro dimensionamento: vale olhar o dimensionamento dos planos de VPS com o número real do teu benchmark em mãos, e não no chute
Bora medir? 🙂
até o próximo post!
Perguntas frequentes
Qual a diferença entre max_num_seqs e max_num_batched_tokens no vLLM?
max_num_seqs limita quantas sequências o scheduler processa em uma iteração, ou seja, o teto de concorrência. max_num_batched_tokens limita quantos tokens no total cabem nessa mesma iteração, funcionando como orçamento de tokens por passo, com default de 2048, valor que a documentação aponta como otimizado para ITL. São dois limites diferentes disputando o mesmo passo do scheduler.
OLLAMA_NUM_PARALLEL alto sempre melhora o atendimento simultâneo?
Não necessariamente. O default é 1, e a documentação do Ollama mostra que a RAM necessária escala pelo produto OLLAMA_NUM_PARALLEL vezes OLLAMA_CONTEXT_LENGTH. Subir o paralelismo sem memória sobrando esbarra no mesmo problema de recurso disputado que acontece no KV cache do vLLM.
O que acontece quando o Ollama recebe mais requisições do que consegue enfileirar?
O Ollama enfileira as requisições até o limite de OLLAMA_MAX_QUEUE, cujo default é 512. Quando esse teto estoura, o servidor responde com erro HTTP 503 indicando que está sobrecarregado.
Rodar dois modelos ao mesmo tempo no Ollama reduz a concorrência de cada um?
Pode reduzir, porque são dois níveis de concorrência disputando a mesma memória: modelos carregados simultaneamente (controlado por OLLAMA_MAX_LOADED_MODELS, default 3 vezes o número de GPUs, ou 3 em CPU) e requisições paralelas dentro de cada modelo. Se não houver memória pra carregar um novo modelo, o Ollama enfileira as novas requisições até liberar espaço.
Como simular tráfego real de vários usuários ao medir throughput no vLLM?
O vllm bench serve tem as flags –request-rate para definir requisições por segundo alvo, –burstiness para simular variabilidade via distribuição Gamma e –max-concurrency para limitar requisições concorrentes em aberto. Combinadas, elas aproximam o benchmark de um padrão de uso real em vez de disparar tudo de uma vez.
Quais campos da resposta do Ollama mostram o tempo gasto em cada requisição?
A API do Ollama retorna total_duration, load_duration, prompt_eval_count, prompt_eval_cached_count, prompt_eval_duration, eval_count e eval_duration, todos em nanossegundos. Esses campos aparecem em endpoints como /api/generate, /api/chat e /api/embed, e servem pra medir desempenho sem depender de ferramenta externa.
Formações
Formação Claude Code
Domine Claude Code do absoluto zero até o avançado
- 120 aulas
- 4 projetos
- 9h 45min
Blog | Mais populares

Checklist de segurança n8n VPS pública: guia essencial para proteger sua instalação
Checklist de segurança n8n VPS pública: guia essencial para proteger sua instalação A popularidade da automação de processos com o n8n está em alta, principalmente […]

Checklist de segurança n8n VPS 2026: proteja sua automação
Confira o checklist de segurança n8n VPS 2026 e mantenha sua automação protegida. Veja práticas essenciais e atualizadas para seu servidor. Manter seu ambiente de […]
Quanto custa uma VPS? Preço atualizado 2026
Quando se fala em quanto custa uma VPS, é preciso contextualizar o tema a partir de um provedor específico, porque o preço só faz sentido […]
