pgbench: benchmark e teste de carga do PostgreSQL
7 min de leitura
O pgbench é o programa de benchmark que vem com o PostgreSQL: ele roda a mesma transação SQL sem parar em várias sessões simultâneas de banco de dados e informa as transações por segundo e a latência. Você cria as tabelas de teste com pgbench -i -s 50 mydb e depois roda algo como pgbench -c 10 -j 2 -T 300 mydb para dez clientes em duas threads durante cinco minutos. Ele mede só o banco de dados, então não diz nada sobre o que os usuários sentem através da aplicação que fica na frente.
Não rodamos o pgbench para este guia. Os fatos vêm da página do pgbench na documentação do PostgreSQL 18, a versão que o postgresql.org marca como atual, conferidos em 31 de outubro de 2026, e as avaliações são nossas.
| Opção | O que faz |
|---|---|
-i / -s | Criar as tabelas de teste / fator de escala (100.000 contas por unidade) |
-c | Clientes, ou seja, sessões simultâneas de banco de dados (padrão 1) |
-j | Threads de trabalho dentro do pgbench (padrão 1) |
-T / -t | Duração em segundos, ou transações por cliente (padrão 10) |
-b / -f | Um script embutido ou um arquivo seu, com um @peso opcional |
-P | Relatório de progresso a cada N segundos |
-R / -L | Taxa alvo em tps / limite de latência em ms |
-r / -l | Latências por comando / uma linha de log por transação |
O que o pgbench mede?
Ele roda um script de transação repetidas vezes num número fixo de sessões de banco de dados e informa a taxa média de transações e a latência. O script padrão se baseia livremente no benchmark bancário TPC-B.
Segundo a documentação do pgbench, o cenário padrão é inspirado no TPC-B sem ser de fato TPC-B, daí o nome: a saída o chama de TPC-B (sort of) (conferido em 31 de outubro de 2026).
Como preparar um banco de dados para o pgbench?
Rode pgbench -i contra um banco de dados existente, com -s para o fator de escala. O comando cria quatro tabelas e apaga qualquer tabela existente com o mesmo nome, então dê a ele um banco só seu.
Com fator 1, pgbench_branches tem uma linha, pgbench_tellers 10, pgbench_accounts 100.000 e pgbench_history nenhuma, e -s multiplica essas linhas: -s 100 gera 10.000.000 de linhas em pgbench_accounts. A documentação não informa o tamanho em disco, então meça depois de inicializar (conferido em 31 de outubro de 2026).
Quais scripts embutidos o pgbench traz?
Três: tpcb-like (o padrão), simple-update e select-only. Você escolhe um com -b ou com os atalhos -N e -S.
O padrão envia sete comandos por transação: BEGIN, um update e um select numa conta aleatória, updates em pgbench_tellers e pgbench_branches, um insert em pgbench_history e END. O simple-update tira os dois updates das tabelas pequenas, o que evita contenção nelas e, segundo a documentação, afasta o teste ainda mais do TPC-B. O select-only envia só o select.
Como escrever um script próprio para o pgbench?
Coloque seu SQL num arquivo, defina variáveis com \set e as funções aleatórias, e passe o arquivo com -f. Cada execução do arquivo conta como uma transação.
\set aid random(1, 100000 * :scale)
\set delta random(-5000, 5000)
BEGIN;
UPDATE pgbench_accounts SET abalance = abalance + :delta
WHERE aid = :aid;
SELECT abalance FROM pgbench_accounts WHERE aid = :aid;
END;
Um peso depois de @ define com que frequência cada script é escolhido: -f update.sql@9 -b select-only@1 escolhe o arquivo em cerca de nove de cada dez vezes. A documentação também lista random_exponential, random_gaussian e random_zipfian, com as quais dá para concentrar o acesso em poucas linhas. O \sleep adiciona uma pausa, a versão de banco de dados do tempo de pensamento. Se você roda só os seus próprios arquivos, passe o fator de escala do banco com -s; senão :scale fica em 1 e o script acima só mexe nas primeiras 100.000 contas. Com tabelas próprias, deixe de fora o -i e adicione -n para o pgbench não rodar VACUUM nas tabelas padrão (conferido em 31 de outubro de 2026).
Quais opções transformam o pgbench num teste de carga?
A concorrência vem de -c e -j, a duração de -T e o formato da carga de -R. Sem -R, cada cliente inicia a próxima transação assim que a anterior termina.
Esse padrão é um modelo de carga fechado, explicado no nosso artigo sobre o modelo de carga aberto vs fechado. Com -R, o pgbench inicia as transações num cronograma com distribuição de Poisson que avança a partir do início do cliente, não importa o que aconteceu com as transações anteriores. A latência informada passa a contar a partir de cada início previsto e inclui o atraso em relação ao cronograma (schedule lag), cuja média e máximo aparecem à parte: é a correção que o nosso artigo sobre coordinated omission descreve. O número de clientes fica fixo, então se o atraso não para de crescer, o sistema não aguenta essa taxa com os clientes e threads escolhidos: reduza o -R ou adicione clientes.
O --latency-limit (-L) conta como atrasadas as transações que passam de um limite em milissegundos; com -R, o pgbench também pula as transações que já estão atrasadas demais em relação ao cronograma e as informa como puladas. O -M prepared usa prepared statements, que segundo a documentação rodam mais rápido que os outros modos (conferido em 31 de outubro de 2026).
Como ler a saída do pgbench?
O resumo mostra as configurações, as transações processadas e com falha, a latência média, o tempo de conexão inicial e os tps. O formato abaixo vem da documentação, sem os números:
transaction type: <builtin: TPC-B (sort of)>
number of transactions actually processed: ...
number of failed transactions: ... (...%)
latency average = ... ms
latency stddev = ... ms (only with -P, -R or -L)
initial connection time = ... ms
tps = ... (without initial connection time)
As transações com falha são erros de serialização ou deadlocks, que o --max-tries pode repetir. Os outros erros de SQL abortam o cliente afetado e deixam o código de saída em 2. O resumo não traz percentis: para a latência de cauda, registre cada transação com -l, que grava a duração dela em microssegundos, e calcule você mesmo o p95 ou o p99.
Sem -P, -R ou -L, a latência média do resumo não é medida: o pgbench a deduz a partir da duração e do número de clientes, ou seja, a lei de Little aplicada ao contrário, com as falhas incluídas. Adicione -P quando a latência importar.
Como obter números confiáveis do pgbench?
Faça cada execução durar vários minutos, repita, mantenha o fator de escala pelo menos igual ao número de clientes e fique de olho no VACUUM. Se o próprio pgbench virar o gargalo, leve-o para outra máquina.
A primeira orientação da seção “Good Practices” da documentação avisa para não acreditar em nenhum teste que dure só alguns segundos, e acrescenta que números reproduzíveis podem levar horas (conferido em 31 de outubro de 2026). Com o script padrão, um fator de escala menor que o número de clientes mede principalmente a contenção dos updates, porque pgbench_branches tem só -s linhas e cada transação altera uma delas. Linhas mortas e o autovacuum mudam os resultados de uma execução para outra. Com muitas sessões, o pgbench pode saturar a própria máquina: rode-o numa máquina separada com baixa latência de rede, ou distribua várias instâncias por várias máquinas.
Quando o pgbench não é a ferramenta certa?
Quando a pergunta é sobre os usuários, sobre outro banco de dados ou sobre um mix OLTP padrão. O pgbench mede o PostgreSQL sozinho, sem o seu pool de conexões, ORM, cache ou camada HTTP.
Para ver o que os usuários sentem, coloque carga na camada HTTP ou de API que fica na frente. A LoadFocus, que publica este site, não roda o pgbench e não consegue se conectar diretamente ao PostgreSQL: ela roda planos de teste JMeter e scripts k6 a partir de 25 regiões na nuvem contra endpoints web e de API, e o template para os endpoints por trás das consultas pesadas é um ponto de partida.
Escolha o sysbench para MySQL: o repositório dele descreve uma ferramenta de benchmark programável e multithread com testes de banco de dados no estilo OLTP. Escolha o HammerDB para um mix no estilo TPC-C: a documentação descreve o TPROC-C, uma carga derivada do TPC-C, que ele roda no PostgreSQL e em outros bancos. Escolha o JMeter com o sampler JDBC Request para misturar SQL e HTTP num mesmo plano de teste nas suas próprias máquinas (tudo conferido em 31 de outubro de 2026).
FAQ
Para que serve a opção -s do pgbench? Ela define o fator de escala na inicialização. Cada unidade adiciona 100.000 linhas a pgbench_accounts, então -s 100 cria 10.000.000 de linhas. Com o script padrão, mantenha o valor pelo menos igual ao seu número de clientes.
Qual é a diferença entre -c e -j no pgbench? A opção -c define o número de clientes simulados, cada um uma sessão simultânea de banco de dados. A opção -j define quantas threads de trabalho do pgbench dividem esses clientes.
A LoadFocus consegue rodar o pgbench? Não. A LoadFocus roda planos de teste JMeter e scripts k6 e não tem conexão direta com o PostgreSQL, então com ela você coloca carga na camada web ou de API que fica na frente do banco de dados.
Leituras relacionadas
- Coordinated omission: o que é e como evitar
- Modelo de carga aberto vs fechado: qual usar e quando
- Latência de cauda: o que é e como medir
- Lei de Little em teste de carga: dimensionar e conferir
- Como usar o sysbench: benchmarks de CPU, disco e MySQL
- YCSB: cargas de trabalho A-F, execução e limites
- redis-benchmark: como usar e ler os resultados
- TPC-H: o que o benchmark mede e como executá-lo
As afirmações técnicas deste artigo não foram revisadas de forma independente.