O que é throughput e por que métricas de capacidade importam
A diferença entre velocidade percebida e capacidade real
Throughput é a quantidade de trabalho que um sistema consegue realizar em um determinado intervalo de tempo — geralmente expresso em requisições por segundo (RPS), transações por segundo (TPS) ou mensagens por segundo. Diferente da latência, que mede o tempo de uma operação individual, o throughput mede o volume de operações que o sistema consegue sustentar simultaneamente. Um sistema pode ter latência baixa para uma única requisição e ainda assim ter throughput miserável quando centenas de usuários acessam ao mesmo tempo, porque os recursos (CPU, memória, conexões de banco) ficam saturados e as requisições começam a enfileirar ou falhar.
Throughput vs latência — a diferença fundamental
Por que otimizar um pode piorar o outro
Latência e throughput parecem medir a mesma coisa, mas na prática representam perspectivas opostas: a latência é o tempo que uma única requisição leva para ser processada, enquanto o throughput é quantas requisições o sistema consegue processar simultaneamente. Aumentar o throughput geralmente exige paralelismo — mais threads, mais workers, mais instâncias — mas isso pode aumentar a contenção por recursos compartilhados (banco, cache, CPU) e elevar a latência média. A lei de Little estabelece que o número médio de requisições em processamento é igual ao throughput multiplicado pela latência média, o que significa que reduzir a latência ou aumentar o número de workers são as únicas formas de aumentar o throughput sem degradar o sistema.
Como medir throughput em aplicações reais
Ferramentas e abordagens para obter números confiáveis
Medir throughput em produção exige instrumentação correta: ferramentas como Prometheus com o histograma http_requests_total permitem calcular a taxa de requisições por segundo usando a função rate() em janelas de tempo. Em .NET, o middleware de métricas do ASP.NET Core expõe counters prontos para Prometheus ou Application Insights. Durante load tests, ferramentas como k6, Locust e JMeter medem o throughput real sob carga simulada, mostrando como o sistema se comporta quando múltiplos usuários operam simultaneamente. O ponto crítico é distinguir o throughput sustentado — o que o sistema mantém por minutos ou horas — do throughput de pico, que pode ser muito maior mas insustentável por conta de buffers e caches temporários.
Gargalos que limitam o throughput
Encontrando o elo mais fraco da cadeia
Todo sistema tem um gargalo — um recurso que se esgota primeiro e impede que o throughput cresça além de certo ponto. Os gargalos mais comuns são: pool de conexões com o banco de dados (cada requisição aguardando uma conexão disponível), contenção de locks em operações de escrita, CPU saturada por serialização JSON ou criptografia, e I/O de disco em operações de log ou leitura de arquivos. A teoria das restrições (Theory of Constraints) de Goldratt afirma que otimizar qualquer parte do sistema que não seja o gargalo não aumenta o throughput — é preciso identificar e aliviar o gargalo primeiro, e em seguida procurar o próximo. Ferramentas como profilers de CPU (dotnet-trace, async-profiler), análise de slow queries e flame graphs são essenciais para identificar onde o gargalo está.
Throughput em banco de dados e I/O
Por que o banco costuma ser o gargalo central
Bancos de dados são frequentemente o gargalo principal de throughput porque concentram operações de I/O, locks e serialização de transações. O pool de conexões é um fator crítico: se a aplicação abre e fecha conexões a cada requisição, o overhead de handshake TCP e autenticação consome tempo significativo e reduz o throughput. Com connection pooling (PgBouncer para PostgreSQL, pool integrado do MongoDB Driver), as conexões são reutilizadas e o throughput pode aumentar 5 a 10 vezes. Operações de I/O de disco — especialmente writes síncronos com fsync — limitam o throughput de escrita em bancos transacionais, razão pela qual tecnologias como write-ahead log (WAL) e batching de writes são essenciais para sistemas de alta escrita.
Como aumentar o throughput com concorrência
Paralelismo real vs ilusão de paralelismo
Aumentar o throughput exige que o sistema processe múltiplas requisições ao mesmo tempo, o que requer concorrência real — múltiplas threads ou processos usando núcleos de CPU distintos — ou I/O assíncrono para não bloquear threads durante operações de rede e disco. Em .NET, o modelo async/await garante que threads não fiquem bloqueadas aguardando respostas do banco ou chamadas HTTP, permitindo que o mesmo thread pool atenda muito mais requisições simultâneas. O número ideal de threads para workloads CPU-bound é próximo ao número de núcleos físicos; para workloads I/O-bound, pode ser dezenas ou centenas de vezes maior. Aumentar threads além do ponto ótimo causa context switching excessivo e degrada o throughput ao invés de melhorá-lo.
Throughput em filas de mensagens e workers
Processamento assíncrono como multiplicador de capacidade
Filas de mensagens como RabbitMQ, SQS e Kafka desacoplam a ingestão de eventos do processamento, permitindo que o throughput de entrada seja independente do throughput de processamento. Um sistema que recebe 10.000 eventos por segundo pode processá-los com workers que consomem 500 eventos por segundo cada — basta adicionar mais workers para escalar o processamento horizontalmente. O consumer group do Kafka distribui partições entre consumers, permitindo escalar o throughput de processamento adicionando instâncias sem alterar o produtor. A métrica de consumer lag — diferença entre o offset mais recente produzido e o offset consumido — indica se os workers estão acompanhando o throughput de entrada ou acumulando atraso.
Load testing para descobrir o throughput real
Testes que revelam limites antes que a produção revele
Testes de carga com k6 ou Locust simulam múltiplos usuários virtuais enviando requisições simultaneamente, permitindo observar como o throughput evolui com o aumento de carga. O padrão ideal é um gráfico de throughput que sobe linearmente com o número de usuários até atingir a capacidade máxima do sistema — chamada de knee of the curve — e depois se estabiliza ou cai. Testes de stress vão além da capacidade máxima para observar como o sistema se comporta sob sobrecarga: ele rejeita requisições com 503, enfileira, ou degrada silenciosamente? Um bom load test deve medir throughput sustentado por pelo menos 5 a 10 minutos, não apenas o pico inicial antes de caches e pools atingirem estado estável.
Throughput em sistemas distribuídos e microsserviços
O throughput é definido pelo componente mais lento da cadeia
Em arquiteturas de microsserviços, o throughput end-to-end de uma operação é limitado pelo componente mais lento da cadeia de chamadas — um serviço que processa 100 RPS mas depende de outro que processa apenas 30 RPS vai ter throughput máximo de 30 RPS. Circuit breakers e timeouts agressivos impedem que um componente lento consuma todos os recursos dos componentes upstream. O padrão de bulkhead (anteparo) isola pools de threads ou conexões por serviço dependente, garantindo que um serviço lento não esgote os recursos disponíveis para todos os outros. Monitorar o throughput de cada serviço individualmente com distributed tracing (Jaeger, Zipkin, OpenTelemetry) é a única forma de identificar qual componente está limitando o throughput do sistema como um todo.
Conclusão — throughput como norte para decisões de arquitetura
Medir antes de otimizar, otimizar com dados
Throughput não é apenas uma métrica de observabilidade — é um norte para decisões arquiteturais sobre particionamento, paralelismo, escolha de banco de dados e estratégia de escalonamento. Sistemas que conhecem seus limites de throughput tomam decisões melhores sobre quando escalar horizontalmente, onde adicionar cache, e quais operações precisam ser assíncronas. Medir, identificar o gargalo, remover o gargalo e medir novamente é o ciclo que diferencia engenheiros que aumentam throughput daqueles que apenas adicionam hardware sem resultado. Continue em: Fundamentos obrigatórios antes de produção.
Throughput e Performance no YouTube — ByteByteGo
System Design: Throughput e Latência explicados
Como identificar gargalos em sistemas distribuídos
Load Testing com k6 — medindo throughput real
Connection Pooling e performance de banco de dados
Filas de mensagens e throughput assíncrono
Escalabilidade horizontal e throughput em microsserviços
Conceitos de Throughput e Performance
Throughput
Número de operações que um sistema processa por unidade de tempo — RPS, TPS ou mensagens por segundo.
Latência
Tempo que uma única requisição leva para ser processada do início ao fim.
Gargalo
Recurso que se esgota primeiro e limita o throughput máximo do sistema inteiro.
Lei de Little
O número médio de requisições em processamento é igual ao throughput multiplicado pela latência média.
Consumer Lag
Diferença entre o offset mais recente produzido e o consumido em filas de mensagens como Kafka.
Connection Pool
Conjunto de conexões reutilizáveis com o banco, evitando o custo de handshake a cada requisição.
Throughput e Sistemas no Instagram
@bytebytego
Reels — Sistemas e Arquitetura
@bytebytego
ByteByteGo no Facebook
Throughput e Performance no X
Como testar que sua API é resiliente e segura para produção real
Ver post completo no X →Implementando padrões de resiliência em .NET Core com exemplos reais
Ver post completo no X →Vertical Slice Architecture — organizando sistemas para escala
Ver post completo no X →5 anos com Clean Architecture — lições de sistemas em produção
Ver post completo no X →Design de APIs resilientes — retry, backoff e idempotência juntos
Ver post completo no X →Monolito vs Microsserviços — como escolher para cada contexto
Ver post completo no X →Links Úteis
O que dizem
Depois de entender throughput vs latência, consegui identificar que nosso gargalo era o pool de conexões — aumentamos o throughput em 4x sem adicionar hardware.
A explicação da Lei de Little mudou como eu penso sobre dimensionamento de workers e threads no nosso sistema de processamento de pedidos.
Usar k6 para medir throughput sustentado versus pico revelou que nosso sistema travava após 2 minutos de carga — problema de memory leak que jamais encontraríamos em testes curtos.