2 points par GN⁺ 2026-01-24 | 1 commentaires | Partager sur WhatsApp
  • OpenAI a massivement étendu son infrastructure PostgreSQL pour faire face à la forte hausse du trafic de ChatGPT et de l’API, en traitant plusieurs millions de QPS avec un serveur flexible Azure PostgreSQL unique et environ 50 réplicas de lecture
  • Tout en conservant une architecture optimisée pour les workloads centrés sur la lecture, une partie des workloads a été migrée vers Azure Cosmos DB afin de réduire la charge d’écriture
  • Diverses optimisations, comme le pooling de connexions avec PgBouncer, le verrouillage de cache, le rate limiting et l’isolation des workloads, ont permis d’améliorer la stabilité et la latence
  • Pour dépasser les limites d’une architecture à primaire unique, des tests ont été menés en parallèle sur une configuration de haute disponibilité (HA), le hot standby et la réplication en cascade (cascading replication)
  • Cette approche a permis d’atteindre une disponibilité de 99,999 % et une latence p99 de l’ordre de quelques dizaines de millisecondes, tout en ouvrant la voie à une future extension vers un PostgreSQL shardé ou des systèmes distribués

Vue d’ensemble de l’extension de PostgreSQL

  • PostgreSQL est le système de données central de ChatGPT et de l’API OpenAI, avec une charge multipliée par plus de 10 au cours de l’année écoulée
    • Une instance primaire unique et environ 50 réplicas de lecture répartis dans le monde traitent les requêtes de 800 millions d’utilisateurs
  • Tout en conservant une architecture centrée sur la lecture, une partie des workloads a été déplacée vers Azure Cosmos DB pour alléger la charge d’écriture
  • L’ajout de nouvelles tables est interdit, et les nouveaux workloads sont par défaut placés sur un système shardé

Défis de l’architecture à primaire unique et réponses apportées

  • Une architecture à rédacteur unique pose des limites de scalabilité en écriture et un problème de point unique de défaillance (SPOF)
    • Le trafic de lecture est réparti sur les réplicas, tandis que le trafic d’écriture pour les workloads shardables est déplacé vers Cosmos DB
    • Une configuration de haute disponibilité via hot standby permet une promotion rapide en cas de panne (failover)
  • Lors de pics soudains de charge en lecture, des ratés de cache ont provoqué une saturation CPU
    • Un mécanisme de verrouillage du cache a été introduit pour éviter les requêtes dupliquées sur une même clé
Publicité

Optimisation des requêtes et des ressources

  • Des requêtes complexes à multiples jointures monopolisaient excessivement le CPU et provoquaient de la latence
    • Les SQL inefficaces générées par l’ORM ont été revues, et les logiques de jointure complexes ont été déplacées vers la couche applicative
    • Le paramètre idle_in_transaction_session_timeout a été utilisé pour éviter les requêtes inactives de longue durée
  • Pour résoudre le problème du "noisy neighbor", le trafic a été séparé sur des instances selon le niveau de priorité
    • Cette isolation empêche les requêtes de faible priorité d’affecter les services à haute priorité

Gestion des connexions et contrôle de charge

  • Pour contourner la limite de 5 000 connexions d’Azure PostgreSQL, PgBouncer a été introduit comme couche proxy
    • La réutilisation des connexions a réduit le temps moyen de connexion de 50 ms à 5 ms
    • Afin de réduire la latence réseau interrégionale, le proxy, les clients et les réplicas ont été placés dans la même région
  • Le rate limiting a été appliqué aux niveaux application, proxy et requête afin d’éviter les brusques explosions de trafic
    • La couche ORM a également été améliorée pour pouvoir bloquer certains digest de requêtes spécifiques
    Publicité

Gestion de la réplication et des changements de schéma

  • Comme le primaire doit streamer les logs WAL à tous les réplicas, l’augmentation de leur nombre accroît la charge réseau
    • La réplication en cascade (cascading replication) est actuellement testée en collaboration avec l’équipe Azure
    • Des réplicas intermédiaires transmettent le WAL à des réplicas en aval, ouvrant la possibilité de dépasser 100 réplicas
  • Les changements de schéma qui provoquent une réécriture complète de table (full table rewrite) sont interdits
    • Seuls des changements légers sont autorisés dans une fenêtre de timeout de 5 secondes, et la création ou suppression d’index peut être effectuée de manière concurrente
    • Même lors des backfills, des limites de débit strictes sont appliquées

Résultats et feuille de route

  • PostgreSQL traite plusieurs millions de QPS, avec une latence de quelques dizaines de millisecondes (p99) et une disponibilité de 99,999 %
    • Au cours des 12 derniers mois, un seul incident SEV-0 a été enregistré (lors du lancement de ChatGPT ImageGen)
  • Les workloads restants centrés sur l’écriture sont eux aussi migrés progressivement vers Cosmos DB
  • Une fois la réplication en cascade finalisée, l’objectif est de renforcer encore la scalabilité et la stabilité des réplicas
  • À plus long terme, l’adoption d’un PostgreSQL shardé ou d’un autre système distribué est à l’étude

1 commentaires

 
GN⁺ 2026-01-24
Réactions sur Hacker News
  • Dans PostgreSQL, les requêtes idle de longue durée posent souvent problème
    Dans le code de notre entreprise, il y avait beaucoup de schémas du type « connexion → début de transaction → travail → commit en cas de succès »
    Cette méthode continuait à occuper des slots de connexion même sans utiliser réellement la DB, au point qu’il a fallu augmenter le nombre de connexions Postgres à plusieurs milliers
    Ils ont donc ajouté dans le code Rust une vérification à la compilation pour que le compilateur avertisse immédiatement si un .await est appelé dans une fonction async alors qu’une connexion est encore détenue
    Plus de 100 endroits ont été corrigés, mais grâce à cela, les tests de charge ne ralentissent plus avec un pool de 32 connexions au lieu de 10 000
    Réduire simplement le délai d’expiration idle est aussi une option, mais la vérification statique s’est révélée une solution bien plus fiable

    • Suggestion : ne vaudrait-il pas mieux inverser l’ordre en « effectuer d’abord le travail → récupérer une connexion dans le pool en cas de succès et démarrer la transaction → commit puis retour au pool »
    • Question sur cette vérification statique : s’agit-il d’une règle de lint ou d’une implémentation s’appuyant sur le système de types ?
  • L’article paraît trop superficiel et se contente de répéter des mots-clés du genre « on a shardé ! »
    Il n’y avait presque aucun détail, et cela donnait l’impression de phrases écrites pour le SEO

    • Certains y ont même vu une publicité pour un partenaire infrastructure
    • Le cache, le connection pooling, l’optimisation des jointures, etc., n’étaient eux aussi expliqués que de façon très générique
  • En résumé, le message de l’article semblait être : « un writer unique ne passe pas à l’échelle, donc on a réduit les écritures et séparé les lectures »
    Il n’y avait presque rien de nouveau, seulement des approches classiques comme l’optimisation des requêtes, le sharding et les read replicas

  • Ce que j’aime dans Postgres, c’est qu’il peut déjà encaisser une assez grande échelle simplement en ajoutant du CPU et du disque
    À ce stade, on a aussi les moyens d’embaucher un spécialiste du sharding

    • En réalité, PostgreSQL prend déjà en charge un sharding de base avec les FDW et le partitionnement
      Donc dire que « pour faire du sharding, il faut quitter Postgres » semble un peu étrange
    • En revanche, l’idée qu’on finit par avoir « les moyens d’embaucher un expert » suscite des doutes
      Par exemple, OpenAI affiche encore aujourd’hui des pertes massives, et certaines actualités disent même qu’il n’est pas certain que l’entreprise tienne jusqu’en 2027
  • Concernant les changements de schéma et les timeouts, il serait bien plus efficace de ne pas se limiter aux timeouts
    et d’exécuter en parallèle, pendant le déploiement du schéma, des scripts qui terminent automatiquement les transactions en conflit
    Ce serait bien que Postgres fournisse cela nativement — mieux vaut annuler certaines transactions que d’attendre sous un verrou lourd

    • Mais certains rétorquent que Postgres prend déjà en charge les changements de schéma transactionnels, donc qu’il n’est pas forcément nécessaire de tuer des opérations
  • Comme il s’agit du premier article du blog Engineering d’OpenAI, c’était intéressant
    J’aimerais voir davantage de retours d’expérience à l’avenir

    • Il y a aussi eu une réaction plus moqueuse, suggérant qu’en pratique ils ont probablement surtout tenu grâce à des pannes fréquentes et à des correctifs d’urgence à 2 heures du matin
  • La configuration de réplication m’intéressait
    Ils disent avoir déployé 50 read replicas avec presque aucune latence de réplication,
    mais en pratique il est fort probable que certaines réplicas prennent du retard à cause de pics de CPU ou de mémoire
    Dans ce cas, le primaire pourrait aussi ralentir à cause de l’attente de transmission du WAL

    • D’autres répondent toutefois que le primaire ne ralentit pas à cause de l’attente des TCP ACK, et qu’il s’agit surtout d’une augmentation du volume de conservation des segments WAL
  • Il y avait un passage disant que « lorsqu’une nouvelle fonctionnalité nécessite des tables supplémentaires, on la met non pas dans PostgreSQL mais dans Azure CosmosDB »
    Cela donnait l’impression qu’ils conservaient le système existant tout en déplaçant uniquement les nouvelles fonctionnalités vers une autre DB

    • Cela dit, CosmosDB est très coûteux, donc difficile à adopter hors d’une entreprise aussi bien financée qu’OpenAI
  • Ils disent avoir augmenté la taille des instances, mais on se demande jusqu’où
    Quels CPU et quelle RAM utilisent-ils ? Est-ce la même classe d’instances que pour les clients ordinaires, ou bien du matériel personnalisé ?

    • Les grands clouds proposent des SKU attribuant un serveur bi-socket entier à une seule VM
      Par exemple : Azure Standard_E192ibds_v6 (96 cœurs, 1,8 To de RAM, 10 To de SSD, 3M IOPS)
      Il existe encore plus grand, avec pour SAP HANA des modèles comme Standard_M896ixds_24_v3, offrant 896 cœurs, 32 To de mémoire et un réseau à 185 Gbps
      Ce type de machine coûte autour de 175 000 dollars par mois, mais OpenAI a probablement obtenu une forte remise
      Personnellement, je préfère utiliser pour un serveur DB les VM HPC HX176rs
      Grâce au cache HBM, le débit mémoire est bien supérieur, et les performances étaient bien meilleures que celles de VM généralistes de prix comparable
  • Utiliser Azure PostgreSQL et CosmosDB ensemble doit représenter un coût énorme
    Malgré cela, cet article faisait partie des exemples les plus réalistes de « PostgreSQL à l’échelle »
    L’approche consistant à opérer dans un environnement cloud standard, sans modifier le kernel ni bricoler le code source, paraissait crédible