Guides

pgbench : benchmark et test de charge de PostgreSQL

7 min de lecture

pgbench est le programme de benchmark livré avec PostgreSQL : il exécute la même transaction SQL encore et encore dans plusieurs sessions de base de données simultanées et rapporte les transactions par seconde et la latence. Vous créez ses tables de test avec pgbench -i -s 50 mydb, puis une commande comme pgbench -c 10 -j 2 -T 300 mydb lance dix clients sur deux threads pendant cinq minutes. Il mesure la base de données seule, et ne dit donc rien de ce que vivent les utilisateurs à travers l’application placée devant.

Nous n’avons pas exécuté pgbench pour ce guide. Les faits proviennent de la page pgbench de la documentation de PostgreSQL 18, la version que postgresql.org désigne comme actuelle, vérifiés le 31 octobre 2026, et les appréciations sont les nôtres.

OptionEffet
-i / -sCréer les tables de test / facteur d’échelle (100 000 comptes par unité)
-cClients, c’est-à-dire sessions de base de données simultanées (1 par défaut)
-jThreads de travail dans pgbench (1 par défaut)
-T / -tDurée en secondes, ou nombre de transactions par client (10 par défaut)
-b / -fScript intégré ou fichier à vous, avec un @poids facultatif
-PRapport de progression toutes les N secondes
-R / -LDébit visé en tps / limite de latence en ms
-r / -lLatences par instruction / une ligne de journal par transaction

Que mesure pgbench ?

Il exécute un script de transaction encore et encore dans un nombre fixé de sessions de base de données, puis rapporte le taux moyen de transactions et la latence. Le script par défaut s’inspire librement du benchmark bancaire TPC-B.

D’après la documentation de pgbench, le scénario par défaut est inspiré de TPC-B sans être vraiment TPC-B, d’où son nom : la sortie l’appelle TPC-B (sort of) (vérifié le 31 octobre 2026).

Comment préparer une base pour pgbench ?

Lancez pgbench -i sur une base existante, avec -s pour le facteur d’échelle. La commande crée quatre tables et supprime toute table existante portant le même nom : donnez-lui une base à part.

Au facteur 1, pgbench_branches contient une ligne, pgbench_tellers 10, pgbench_accounts 100 000 et pgbench_history aucune, et -s multiplie ces lignes : -s 100 donne 10 000 000 de lignes dans pgbench_accounts. La documentation n’indique aucune taille sur disque, mesurez-la donc après l’initialisation (vérifié le 31 octobre 2026).

Quels scripts intégrés pgbench propose-t-il ?

Trois : tpcb-like (par défaut), simple-update et select-only. Vous en choisissez un avec -b, ou avec les raccourcis -N et -S.

Le script par défaut envoie sept commandes par transaction : BEGIN, un update et un select sur un compte au hasard, des updates sur pgbench_tellers et pgbench_branches, un insert dans pgbench_history, puis END. simple-update retire les deux updates sur les petites tables, ce qui y évite la contention et, selon la documentation, éloigne encore le test de TPC-B. select-only n’envoie que le select.

Comment écrire un script pgbench personnalisé ?

Mettez votre SQL dans un fichier, définissez des variables avec \set et les fonctions aléatoires, et passez le fichier avec -f. Chaque exécution du fichier compte comme une transaction.

\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;

Un poids après @ fixe la fréquence de choix de chaque script : -f update.sql@9 -b select-only@1 choisit le fichier environ neuf fois sur dix. La documentation liste aussi random_exponential, random_gaussian et random_zipfian, qui permettent de rendre quelques lignes très sollicitées. \sleep ajoute une pause, l’équivalent côté base de données du temps de réflexion. Si vous n’exécutez que vos propres fichiers, passez le facteur d’échelle de la base avec -s, sinon :scale reste à 1 et le script ci-dessus ne touche que les 100 000 premiers comptes. Avec vos propres tables, omettez -i et ajoutez -n pour que pgbench ne lance pas de VACUUM sur les tables standard (vérifié le 31 octobre 2026).

Quelles options font de pgbench un test de charge ?

La concurrence vient de -c et -j, la durée de -T et la forme de la charge de -R. Sans -R, chaque client lance sa transaction suivante dès que la précédente se termine.

Ce comportement par défaut correspond à un modèle de charge fermé, expliqué dans notre article sur le modèle de charge ouvert ou fermé. Avec -R, pgbench lance les transactions selon un calendrier à distribution de Poisson qui avance à partir du démarrage du client, quel que soit le sort des transactions précédentes. La latence rapportée compte alors à partir de chaque départ prévu et inclut donc le retard sur le calendrier (schedule lag), dont la moyenne et le maximum sont affichés à part : c’est la correction que décrit notre article sur la coordinated omission. Le nombre de clients reste fixe ; si le retard ne cesse de grandir, le système ne tient pas ce débit avec les clients et threads choisis : baissez -R ou ajoutez des clients.

--latency-limit (-L) compte comme en retard les transactions qui dépassent une limite en millisecondes ; avec -R, pgbench saute en plus les transactions déjà trop en retard sur le calendrier et les rapporte comme ignorées. -M prepared utilise des requêtes préparées, plus rapides que les autres modes selon la documentation (vérifié le 31 octobre 2026).

Comment lire la sortie de pgbench ?

Le résumé liste les réglages, les transactions traitées et en échec, la latence moyenne, le temps de connexion initial et le tps. La forme ci-dessous vient de la documentation, sans les chiffres :

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)

Les transactions en échec sont des erreurs de sérialisation ou des deadlocks, que --max-tries peut relancer. Les autres erreurs SQL interrompent le client concerné et donnent un code de sortie 2. Le résumé ne donne aucun percentile : pour la latence de queue, journalisez chaque transaction avec -l, qui enregistre sa durée en microsecondes, et calculez vous-même le p95 ou le p99.

Sans -P, -R ou -L, la latence moyenne du résumé n’est pas mesurée : pgbench la déduit de la durée du test et du nombre de clients, soit la loi de Little appliquée à l’envers, échecs compris. Ajoutez -P quand la latence compte.

Comment obtenir des chiffres pgbench fiables ?

Faites durer chaque exécution plusieurs minutes, répétez-la, gardez un facteur d’échelle au moins égal au nombre de clients et surveillez le VACUUM. Si pgbench devient lui-même le goulot d’étranglement, déplacez-le sur une autre machine.

La première consigne de la section « Good Practices » de la documentation met en garde contre tout test qui ne dure que quelques secondes, et ajoute que des chiffres reproductibles peuvent demander des heures (vérifié le 31 octobre 2026). Avec le script par défaut, un facteur d’échelle inférieur au nombre de clients mesure surtout la contention des updates, car pgbench_branches n’a que -s lignes et chaque transaction en modifie une. Les lignes mortes et l’autovacuum font varier les résultats d’une exécution à l’autre. Avec beaucoup de sessions, pgbench peut saturer sa propre machine : lancez-le sur une machine séparée avec une faible latence réseau, ou répartissez plusieurs instances sur plusieurs machines.

Quand pgbench n’est-il pas le bon outil ?

Quand la question porte sur les utilisateurs, sur une autre base de données ou sur un mélange OLTP standard. pgbench mesure PostgreSQL seul, sans votre pool de connexions, votre ORM, votre cache ni votre couche HTTP.

Pour voir ce que vivent les utilisateurs, mettez sous charge la couche HTTP ou API placée devant. LoadFocus, qui publie ce site, n’exécute pas pgbench et ne peut pas se connecter directement à PostgreSQL : LoadFocus exécute des plans de test JMeter et des scripts k6 depuis 25 régions cloud contre des endpoints web et API, et son modèle pour les endpoints derrière les requêtes lourdes offre un point de départ.

Choisissez plutôt sysbench pour MySQL : son dépôt décrit un outil de benchmark scriptable et multithread, avec des tests de base de données de type OLTP. Choisissez HammerDB pour un mélange de type TPC-C : sa documentation décrit TPROC-C, une charge dérivée de TPC-C, qu’il exécute sur PostgreSQL et d’autres moteurs. Choisissez JMeter avec son sampler JDBC Request pour mêler SQL et HTTP dans un même plan de test sur vos propres machines (le tout vérifié le 31 octobre 2026).

FAQ

À quoi sert l’option -s de pgbench ? Elle fixe le facteur d’échelle à l’initialisation. Chaque unité ajoute 100 000 lignes à pgbench_accounts, donc -s 100 crée 10 000 000 de lignes. Avec le script par défaut, gardez-le au moins égal à votre nombre de clients.

Quelle est la différence entre -c et -j dans pgbench ? L’option -c fixe le nombre de clients simulés, chacun étant une session de base de données simultanée. L’option -j fixe le nombre de threads de travail de pgbench qui se partagent ces clients.

LoadFocus peut-il exécuter pgbench ? Non. LoadFocus exécute des plans de test JMeter et des scripts k6 et n’a pas de connexion directe à PostgreSQL : avec lui, vous mettez sous charge la couche web ou API placée devant la base de données.

À lire aussi


Les affirmations techniques de cet article n'ont pas été relues de façon indépendante.

LoadFocus team
Écrit par l'équipe LoadFocus, qui fait tourner un service de test de charge dans le cloud.