Modelo de carga aberto vs fechado: qual usar e quando
7 min de leitura
Escolher um modelo de carga aberto vs fechado depende principalmente de como os usuários chegam ao seu sistema. Use um modelo aberto, que inicia novas iterações a uma taxa de chegada definida, para sites e APIs públicos em que os usuários continuam chegando por mais lento que você responda, e um modelo fechado, um número fixo de usuários virtuais que esperam cada um o fim da iteração anterior, só onde o próprio sistema limita a concorrência. A escolha pesa mais na saturação, quando um teste fechado freia a própria carga e faz o sistema parecer mais saudável do que está.
Os fatos sobre as ferramentas vêm da documentação de cada projeto, conferida em 9 de outubro de 2026.
| Modelo aberto | Modelo fechado | |
|---|---|---|
| O que você define | Novas iterações ou usuários por segundo | Usuários virtuais simultâneos |
| Quando as respostas ficam lentas | O trabalho continua chegando e as filas crescem | Os usuários esperam e menos carga é enviada |
| Sistemas reais assim | A maioria dos sites e APIs públicos | Call centers, filas de venda de ingressos, pools de workers |
| k6 | constant-arrival-rate, ramping-arrival-rate | constant-vus, ramping-vus |
| Gatling | injectOpen | injectClosed |
| Locust | Aproximado com constant_throughput ou poisson | Usuários com um wait_time |
| JMeter | Open Model Thread Group, plugin Arrivals | Thread Group |
Qual é a diferença entre um modelo de carga aberto e um fechado?
No modelo aberto, quem decide quando o trabalho chega é o gerador de carga, e no fechado é o tempo de resposta do sistema.
A documentação do k6 diz isso com clareza: no modelo fechado, a próxima iteração de um usuário virtual só começa quando a anterior termina, enquanto no modelo aberto as novas iterações chegam sem depender do fim das anteriores (conferido em 9 de outubro de 2026). Um teste fechado com 50 usuários virtuais nunca tem mais de 50 iterações em andamento. Um teste aberto a 50 iterações por segundo dispara mais 50 a cada segundo, e se cada uma demora mais, mais delas se sobrepõem.
Por que um modelo fechado esconde a latência quando o sistema satura?
Porque o teste fica lento junto com o sistema. Quando as respostas demoram mais, cada usuário de um modelo fechado envia menos requisições, e a carga cai bem na hora em que você queria vê-la subir.
A documentação do k6 descreve o efeito: respostas mais lentas significam iterações mais longas e uma taxa de chegada menor de iterações novas. A página do Gatling sobre modelos de carga vai além e diz que usar um modelo fechado contra um sistema que na verdade é aberto é um teste quebrado, que mede um comportamento imaginário (conferido em 9 de outubro de 2026).
Por isso um teste fechado mostra tempos de resposta que se estabilizam, já que nunca pode haver mais requisições em andamento do que usuários. Um teste aberto mostra a fila crescendo, com tempos de resposta que sobem enquanto as chegadas superam o que o sistema processa. Essa segunda imagem é a que seus usuários veriam, e os tempos de resposta p95 e p99 que você lê no fim só são tão confiáveis quanto o modelo de carga que os produziu.
A documentação do k6 observa que parte da literatura sobre testes chama esse problema de coordinated omission. Um artigo da USENIX de 2006 citado pela documentação do Gatling, Open Versus Closed: A Cautionary Tale, concluiu que os dois modelos dão resultados bem diferentes mesmo com a mesma carga e as mesmas demandas de serviço.
Qual modelo combina com o seu tráfego real?
Escolha um modelo aberto para tudo que o público consegue acessar, e um fechado só onde o próprio sistema limita quantos usuários ficam ativos ao mesmo tempo.
A documentação do Gatling cita como sistemas fechados os call centers com todos os atendentes ocupados e os sites de venda de ingressos que colocam os usuários em fila quando lotam, e diz que a maioria dos sites se comporta como sistema aberto. Um job em lote com um número fixo de workers, ou um consumidor de fila com concorrência definida, também é fechado. APIs públicas, páginas web e webhooks são abertos: nada segura a próxima requisição porque a anterior foi lenta.
Muitos sistemas ficam no meio do caminho: uma compradora chega no próprio ritmo e depois espera cada página durante a visita. O artigo citado chama isso de modelo parcialmente aberto. No k6 ou no Gatling, defina a taxa de chegada das sessões e faça de cada iteração uma jornada de usuário completa, com as próprias pausas.
Como configurar cada modelo no k6?
Pelo executor. constant-vus e ramping-vus dão um modelo fechado, e constant-arrival-rate e ramping-arrival-rate dão um aberto.
Um cenário fechado define executor: "constant-vus" com um número de vus e uma duration. Um cenário aberto define uma taxa, e você pré-aloca usuários virtuais suficientes para sustentá-la:
export const options = {
scenarios: {
open_model: {
executor: "constant-arrival-rate",
rate: 50,
timeUnit: "1s",
duration: "5m",
preAllocatedVUs: 100,
},
},
thresholds: {
dropped_iterations: ["count<10"],
},
};
O k6 só inicia uma iteração enquanto tem um usuário virtual livre, e a documentação desaconselha depender de maxVUs, porque adicionar usuários no meio do teste pode sobrecarregar o gerador de carga. Quando nenhum usuário está livre, o k6 registra uma iteração descartada, o que, já perto do fim de um teste, costuma indicar que o sistema está ficando lento. O limite acima faz a execução falhar ao chegar a dez. Não coloque sleep() no fim de uma iteração com taxa de chegada, porque o executor já cadencia os inícios (conferido em 9 de outubro de 2026).
Se você roda scripts k6 na LoadFocus, a execução de k6 na nuvem da plataforma usa a carga definida nas configurações do teste, e o validador de scripts avisa que cenários com taxa de chegada rodam ali com um número fixo de usuários, então a taxa de requisições não é mantida. Para um teste de verdade com modelo aberto, rode os executors de taxa de chegada com o próprio k6, ou em um serviço que os execute do jeito que foram escritos.
Como Gatling, Locust e JMeter expressam cada modelo?
O Gatling separa os dois modelos na API, o JMeter oferece os dois por meio de thread groups diferentes, e o Locust é construído em torno de um número fixo de usuários.
Gatling. Um cenário usa injectOpen ou injectClosed. Passos abertos como constantUsersPerSec e rampUsersPerSec definem taxas de chegada, e passos fechados como constantConcurrentUsers e rampConcurrentUsers definem a concorrência. Um mesmo perfil de injeção não pode misturar os dois (conferido em 9 de outubro de 2026).
Locust. Você define um número de usuários, e o wait_time de cada usuário controla a pausa entre tarefas. constant_throughput e constant_pacing ajustam essa pausa para que cada usuário rode no máximo um número definido de tarefas por segundo, mas a documentação diz que o tempo de espera só consegue limitar a vazão e não inicia novos usuários para atingir uma meta. poisson() sorteia pausas aleatórias, que a documentação considera mais próximas das chegadas reais. O exemplo da documentação para 500 iterações de tarefa por segundo é constant_throughput(0.1) com 5.000 usuários, um pool fechado com bastante folga (conferido em 9 de outubro de 2026).
JMeter. O Thread Group clássico é um pool fechado de threads. Os timers Constant Throughput e Precise Throughput cadenciam esse pool rumo a uma taxa alvo, e a referência avisa que a vazão cai se o servidor não der conta ou se faltarem threads. Para chegadas, o JMeter 5.5 adicionou o Open Model Thread Group, ainda marcado como experimental, com agendas como rate(10/sec) random_arrivals(1 min). O plugin da comunidade Arrivals Thread Group inicia novas threads quando todas as existentes estão ocupadas, com um limite de concorrência como válvula de segurança (conferido em 9 de outubro de 2026).
O que observar em um teste com modelo aberto?
Observe o gerador de carga tão de perto quanto o sistema sob teste. No modelo aberto, um sistema lento significa mais usuários simultâneos do seu lado, e isso custa memória e CPU.
Defina um teto, como maxVUs no k6 ou o limite de concorrência do plugin do JMeter, e trate atingi-lo como um resultado: o sistema não conseguiu absorver a taxa que você pediu.
FAQ
Um modelo de carga fechado é a escolha certa em algum caso? Sim. Use-o quando o sistema real limita a concorrência, como um pool fixo de workers, um consumidor de fila ou um call center, ou quando você quer saber quantas sessões simultâneas um componente aguenta. Para tráfego web público, um modelo aberto se encaixa melhor.
Adicionar tempo de pensamento transforma um modelo fechado em aberto? Não. O tempo de pensamento reduz a frequência com que cada usuário envia requisições, mas cada usuário continua esperando a resposta anterior, então um sistema lento ainda freia o teste. Só uma taxa de chegada definida independentemente dos tempos de resposta gera um modelo aberto.
Quantos usuários virtuais um teste com taxa de chegada precisa? O suficiente para cobrir todas as iterações em andamento ao mesmo tempo. A documentação do k6 sugere a mediana da duração de uma iteração multiplicada pela taxa alvo, mais uma margem para a variação, ajustada com testes curtos antes do teste completo.
Leituras relacionadas
- Coordinated omission: o que é e como evitar
- Lei de Little em teste de carga: dimensionar e conferir
- Tempo de pensamento em teste de carga: como definir
- Vazão vs latência: como se relacionam sob carga
- Lei de Amdahl: fórmula, exemplos e limites
- Teoria das filas: o que é e por que a latência dispara
As afirmações técnicas deste artigo não foram revisadas de forma independente.