Aller au contenu
Contactez-nous
  1. Accueil
  2. /
  3. Blog
  4. /
  5. PostgreSQL 18 et l'I/O asynchrone

Base de données
Performance

PostgreSQL 18 et l'I/O asynchrone

10 septembre 2026

8 min de lecture

Sommaire
Ce que le modèle synchrone coûtait réellement
Le paramètre central : io_method
Le vrai déterminant : ce qu'il y a sous PostgreSQL
Paramètres et valeurs de départ
La méthode : mesurer avant de migrer, pas après
Le verdict côté ops
Sources

PostgreSQL 18 est sorti fin septembre 2025. Sa nouveauté la plus commentée n'est ni un opérateur SQL ni un index inédit, c'est un changement de mécanique interne : un sous-système d'I/O asynchrone. Depuis PostgreSQL 6.4, un backend qui lisait une page en attendait la fin avant de continuer. Ça change en version 18, et c'est le changement le plus lourd de conséquences sur les I/O depuis l'introduction du buffer cache partagé.

Ce que le modèle synchrone coûtait réellement

Avant la 18, un scan séquentiel émettait ses lectures une par une. Le noyau Linux compensait partiellement via posix_fadvise() pour déclencher du read-ahead, mais chaque backend restait bloqué en attente d'E/S sur chaque page manquante du cache. Sur du stockage à latence élevée, réseau ou mécanique, ce blocage se payait cash : le CPU du backend restait inactif pendant que le disque travaillait, un cycle par page, sans recouvrement.

Le nouveau sous-système permet à un backend de soumettre plusieurs demandes de lecture en une fois, sans attendre la fin de chacune avant de soumettre la suivante. Le gain ne vient pas d'un disque plus rapide, il vient du recouvrement : pendant que le noyau ou le contrôleur traite une lecture, le backend peut avoir déjà soumis les suivantes, au lieu de rester les bras croisés.

Le paramètre central : io_method

PostgreSQL 18 introduit io_method, un paramètre qui nécessite un redémarrage du serveur et qui accepte trois valeurs.

sync reproduit le comportement pré-18 : lectures bloquantes, avec le read-ahead du noyau comme seul recouvrement. C'est la valeur de repli, utile en diagnostic pour isoler si un problème vient du nouveau sous-système.

worker, la valeur par défaut, délègue les lectures à des processus workers d'I/O dédiés. Le backend qui exécute la requête empile ses demandes de lecture dans une file, et des processus séparés les exécutent pour son compte pendant qu'il continue son travail. Le nombre de ces processus est contrôlé par io_workers, avec une valeur de départ de 3.

io_uring, disponible uniquement sur Linux avec un noyau récent, s'appuie sur l'interface io_uring introduite dans la branche 5.1 du noyau. Elle établit un anneau de mémoire partagée entre PostgreSQL et le noyau, sans passer par des processus workers intermédiaires. C'est la méthode la plus efficace sur le papier, à condition que le noyau et la configuration système l'autorisent (io_uring est parfois désactivé par des politiques de durcissement, ce qui mérite vérification avant de compter dessus).

Un second paramètre gouverne la taille des lectures groupées : io_combine_limit, par défaut 256 Ko, qui fusionne plusieurs pages contiguës en une seule opération d'E/S plutôt que d'en émettre une par page.

Le vrai déterminant : ce qu'il y a sous PostgreSQL

L'ampleur du gain dépend presque entièrement du stockage sous-jacent, bien plus que du choix entre worker et io_uring.

Sur du NVMe local, la latence par opération est déjà de l'ordre de la dizaine de microsecondes, et la bande passante du bus PCIe encaisse un grand nombre d'opérations en parallèle sans broncher. Le recouvrement apporté par l'I/O asynchrone reste utile, particulièrement sur VACUUM et les scans bitmap qui lisent beaucoup de pages non contiguës, mais l'écart entre sync et io_uring reste mesuré en dizaines de pourcents, pas en multiples.

Sur du stockage réseau, SAN iSCSI, NVMe-oF ou volumes cloud du type EBS ou Cinder, la latence par requête est nettement plus haute, et c'est justement le terrain où le modèle bloquant coûtait le plus cher : chaque attente immobilisait un backend entier pendant un aller-retour réseau. C'est sur ce type de stockage que les gains rapportés, de l'ordre de deux à trois fois sur certains scans séquentiels et bitmap, se rapprochent le plus de ce qu'annoncent les benchmarks publiés autour de la sortie de la version. Un tuning NVMe déjà solide côté cible réseau profite directement de ce recouvrement, les deux couches ne se contredisent pas, elles s'additionnent.

Sur du stockage mécanique, la latence de recherche domine tout, et l'I/O asynchrone aide sans changer la donne fondamentale : un disque à plateaux reste un disque à plateaux.

Paramètres et valeurs de départ

Trois réglages à connaître avant toute migration vers PostgreSQL 18.

io_method : partir de worker par défaut, c'est le choix conservateur et portable. Sur du Linux récent (noyau 5.1 et au-delà, idéalement 6.x pour la maturité des correctifs io_uring), tester io_uring en environnement de pré-production avant de le pousser en production, en vérifiant d'abord que rien ne le bloque au niveau du conteneur ou du hardening système.

io_workers : la valeur de départ de 3 convient à une charge modeste. Sur une instance qui pousse beaucoup de scans parallèles avec io_method = worker, la documentation invite à l'augmenter progressivement en observant la file d'attente plutôt qu'en fixant une valeur arbitraire élevée d'entrée.

effective_io_concurrency : la valeur par défaut est passée de 1 en version 17 à 16 en version 18, une reconnaissance explicite que le nouveau sous-système sait tirer parti d'un plus grand nombre de lectures en vol. La profondeur de lecture anticipée effective se calcule approximativement en multipliant effective_io_concurrency par io_combine_limit : sur un stockage réseau à haute latence mais haut débit, il est cohérent de monter cette valeur au-delà du défaut, en le mesurant plutôt qu'en le supposant.

La méthode : mesurer avant de migrer, pas après

La règle qu'on applique sur toute montée de version majeure de Postgres, et particulièrement sur celle-ci : caractériser la charge avant de toucher io_method, pas après avoir constaté un problème en production.

Concrètement, ça veut dire tourner un pgbench représentatif de votre charge réelle (pas le scénario TPC-B par défaut si votre workload est majoritairement en lecture analytique) sur les trois valeurs de io_method, sur un environnement dont le stockage est identique à la production, et comparer la latence p99 et le débit, pas seulement la moyenne. EXPLAIN (ANALYZE, BUFFERS) sur les requêtes les plus coûteuses du plan de production révèle si les opérations concernées (scans séquentiels, scans bitmap, VACUUM) sont bien celles qui bénéficient du nouveau chemin ; une base dominée par des accès par index sur des données déjà en cache verra un gain marginal, quel que soit le stockage en dessous.

Sur un cluster en haute disponibilité, la bascule pilotée par Patroni impose une contrainte supplémentaire : io_method doit être identique sur le primaire et les répliques avant tout basculement automatique, sous peine de changer brutalement de profil de performance au moment où on en a le moins besoin, pendant un failover. Testez le changement de paramètre en incluant un scénario de bascule, pas seulement en régime stable.

Pour qui a déjà mis en oeuvre les réglages avancés classiques, au-delà du tuning de base (shared_buffers, work_mem, checkpoint_completion_target), l'I/O asynchrone est un chantier complémentaire, pas un substitut. Un shared_buffers mal dimensionné continue de faire mal en version 18 exactement comme avant : le nouveau sous-système accélère l'accès au disque, il ne compense pas un cache mémoire insuffisant.

Le verdict côté ops

io_method = worker en valeur de départ, sur toute nouvelle instance PostgreSQL 18, sans discussion : c'est le choix sûr et déjà activé par défaut. Le passage à io_uring mérite un test dédié sur stockage réseau ou NVMe où la charge est dominée par des scans, avec une bascule en pré-production avant tout déploiement, jamais un changement à l'aveugle sur une base existante en modifiant simplement le paramètre un vendredi soir.

Sur du stockage réseau à latence significative, c'est le terrain où l'investissement de test paie le plus, avec des gains qui peuvent justifier une migration anticipée depuis une version antérieure. Sur du NVMe local avec une base déjà bien réglée côté mémoire, le gain existe mais reste secondaire face aux réglages classiques qui, eux, n'ont pas changé.

Caractériser un changement de version majeure avant de le pousser en production, avec un scénario de bascule inclus, c'est le travail qu'on fait systématiquement sur les instances PostgreSQL qu'on opère. Si une montée vers la version 18 est au calendrier et que le stockage sous-jacent n'a jamais été benché face à ce nouveau sous-système, on peut mesurer l'impact réel avant la migration plutôt que de le découvrir après.

Sources

  • PostgreSQL 18.0 Release Notes : notes de version officielles, description du sous-système d'I/O asynchrone.
  • PostgreSQL 18 Asynchronous I/O - Improve Read Performance (Neon) : détail des trois valeurs de io_method et de leur mécanique respective.
  • Waiting for Postgres 18: Accelerating Disk Reads with Asynchronous I/O (pganalyze) : analyse technique du recouvrement des lectures et des opérations concernées (scans, VACUUM).
  • All Your GUCs in a Row: effective_io_concurrency (The Build) : explication du changement de valeur par défaut de effective_io_concurrency et de son interaction avec io_combine_limit.
Besoin d'aide sur ce sujet ?

Notre équipe d'experts est là pour vous accompagner dans vos projets d'infrastructure et d'infogérance.

Contactez-nous

Articles similaires

DragonflyDB : un seul gros nœud plutôt qu'un cluster Redis shardé
Base de données
Performance

DragonflyDB : un seul gros nœud plutôt qu'un cluster Redis shardé

DragonflyDB exploite tous les cœurs d'une machine avec une architecture shared-nothing et un snapshot sans fork. Quand une instance verticale remplace un cluster Redis, et où sont les limites.

27 juin 2026

Lire plus

Valkey ou Redis : faut-il migrer après le feuilleton des licences ?
Base de données
Performance

Valkey ou Redis : faut-il migrer après le feuilleton des licences ?

Redis a changé trois fois de licence en deux ans, Valkey est devenu le paquet par défaut de la plupart des distributions. Ce qui change vraiment en production et quand basculer.

22 juin 2026

Lire plus

PgBouncer : optimiser les connexions PostgreSQL en production
Base de données
Performance
Infrastructure

PgBouncer : optimiser les connexions PostgreSQL en production

Guide complet PgBouncer : configuration du connection pooling PostgreSQL, modes transaction/session/statement, monitoring et bonnes pratiques production.

23 févr. 2026

Lire plus


SHPV, votre partenaire de confiance en infrastructure et infogérance informatique en France.

SHPV
Contactez-nousNous contacter
Expertise
InfrastructureDatacenterInfogéranceCloudHébergementTransit IP
Légales
Conditions Générales de VenteCPS - Contrat de ServicesCPS - Hébergement CloudCPS - Microsoft 365Accord sous-traitance RGPDTarifs interventions

SHPV © 2026 - Tous droits réservés

Mentions légalesPolitiques de confidentialité
SHPV FRANCE - SAS au capital de 16 000 € - 52 Rue Romain Rolland, 71230 Saint-Vallier - SIRET n°80886287400035 - R.C.S. Chalon-sur-Saône. Par téléphone 09 72 310 818 - Email: support@shpv.fr