27 points par GN⁺ 2025-12-03 | 2 commentaires | Partager sur WhatsApp
  • Des expriences montrent que la structure  writer unique et la nature embarque de SQLite peuvent au contraire amliorer la monte en charge et les performances
  • Dans les mames conditions, Postgres tombait  348 TPS avec la latence reseau, tandis que SQLite atteignait 44a0096 TPS en supprimant le reseau
  • En exploitant le modle  writer unique avec du batch processing et des transactions granulaires bases sur SAVEPOINT, le syst8me a atteint jusqu 186a0157 TPS, et 102a0545 TPS dans une configuration stable
  • La loi dAmdahl explique le goulot de9tranglement des bases de donnes en reseau, que SQLite 9vite, ce qui lui permet de conserver une grande efficacit
  • Ces rsultats soulignent le potentiel de SQLite en environnement local et limportance de9liminer les goulots de9tranglement reseau

Structure de SQLite et environnement dexpe9rimentation

  • SQLite nutilise pas MVCC et nautorise quun seul writer, mais cette structure permet paradoxalement une forte monte en charge
    • En tant que base de donnes embarque, elle na aucun surcofbt reseau
  • Les benchmarks ont e9te9 effectue9s sur un MacBook Pro (2021) Apple M1 Pro avec 16 Go de me9moire
  • Lobjectif ne9tait pas une optimisation parfaite, mais de montrer queil est possible dobtenir un haut de9bit de9criture dans des conditions ordinaires

De9finition du TPS et exemple de transaction

  • Le TPS ne de9signe pas une simple vitesse de9criture, mais une transaction interactive (Interactive Transaction)
    • Exemple : lors deun virement entre comptes, plusieurs requeates et du code applicatif se9exe9cutent dans une meame transaction
  • En cas deerreur, une transaction peut revenir en arrie8re, ce qui joue un rf4le essentiel dans le maintien de la cohe9rence

Configuration du benchmark

  • Des virtual threads base9s sur Clojure ont e9te9 utilise9s pour simuler un grand volume de requeates concurrentes
  • Postgres a e9te9 configure9 avec un pool de connexions base9 sur HikariCP, tandis que SQLite utilisait un writer unique et autant de connexions de lecture que de c53urs
  • Les deux bases de donne9es utilisent une table account simple avec les champs id, balance, et un milliard de lignes y ont e9te9 inse9re9es
  • Leactivite9 utilisateur suit une distribution en loi de puissance (0.9995), avec environ 100a0000 utilisateurs actifs

Performances deune base de donne9es en re9seau (Postgres)

  • Sur le meame serveur, Postgres a atteint 13a0756 TPS
  • Avec 5 ms de latence re9seau ajoute9e, il tombe e0 1a0214 TPS, puis e0 702 TPS avec 10 ms
  • Apre8s application du niveau deisolement se9rialisable, le de9bit chute e0 660 TPS, puis e0 348 TPS en ajoutant des requeates supple9mentaires
  • Cela montre, conforme9ment e0 la loi deAmdahl, que le goulot dee9tranglement re9seau limite les performances globales
    • Quand la latence re9seau augmente, la contention sur les verrous transactionnels se9aggrave, ce qui empeache toute monte9e en charge

Les avantages du mode embarque9 de SQLite

  • Une fois le re9seau supprime9, SQLite atteint 44a0096 TPS
    • La disparition du goulot dee9tranglement re9seau minimise leimpact de la loi deAmdahl
  • En exploitant sa structure e0 writer unique avec du batch processing, le de9bit monte jusque0 186a0157 TPS
    • Un ajustement dynamique de la taille des batchs optimise automatiquement la latence et le throughput

Transactions granulaires avec SAVEPOINT

  • Pour e9viter que9un e9chec individuel neannule tout un batch, des transactions imbrique9es avec SAVEPOINT ont e9te9 utilise9es
    • En cas dee9chec, seule la transaction concerne9e est annule9e, tandis que le batch complet est conserve9
  • Meame avec cette approche, le syste8me maintient 121a0922 TPS

Test de charge mixte lecture/e9criture

  • 75 % des requeates e9taient des lectures et 25 % des e9critures
  • Un pool de threads de lecture distinct a permis de se9parer les lectures pour queelles ne perturbent pas les e9critures
  • Le re9sultat final atteint 102a0545 TPS

Re9sume9 comparatif des performances

Condition Postgres SQLite
Sans re9seau 13a0756 44a0096
Latence 5 ms 1a0214 n/a
Latence 10 ms 702 n/a
10 ms + se9rialisation 660 n/a
Batch processing n/a 186a0157
Batch + SAVEPOINT n/a 121a0922
Batch + SAVEPOINT + lecture n/a 102a0545

Conclusion

  • SQLite atteint un TPS nettement supe9rieur e0 celui des bases de donne9es en re9seau gre2ce e0 son mode8le e0 writer unique et sa structure embarque9e
  • En e9vitant les limites de goulot dee9tranglement re9seau mises en avant par la loi deAmdahl, il maximise son efficacite9
  • Le code complet est publie9 sur GitHub, avec des ressources associe9es sur la loi deAmdahl, les lois de puissance et des cas de monte9e en charge de SQLite
  • SQLite constitue un choix tre8s efficace pour le traitement transactionnel haute performance en environnement local

2 commentaires

 
ppp123 2025-12-10

Donc, si l’on ne compte utiliser ça qu’en local sans passer par un serveur externe, pas besoin de payer la « taxe réseau », c’est ça ? (VFS vs Socket)

 
GN⁺ 2025-12-03
Avis Hacker News
  • Je suis en train de construire un serveur ORM/CRUD hybride protobuf basé sur SQLite
    Le code et les explications sont sur GitHub - accretional/collector
    Il permet des sauvegardes en temps réel avec 5 à 15 ms d'indisponibilité, la mise en file de centaines de requêtes de lecture/écriture, une latence CRUD globale d'environ 1 ms, et même des sauvegardes en streaming basées sur le WAL
    Avant, je n'utilisais que Postgres et Spanner, mais si j'ajoute juste le partitionnement à Collector, je pense que je ne reviendrai plus à Postgres

    • Je me demande si vous avez envisagé d'utiliser un système de fichiers à instantanés atomiques comme BTRFS pour faire des sauvegardes sans interruption avec SQLite + WAL. Il suffirait de prendre un snapshot, de sauvegarder tranquillement, puis de le supprimer
  • L'inconvénient, c'est que toutes les données et tous les traitements doivent tenir sur une seule machine
    Avec une instance AWS u-24tb1.112xlarge (448 vCPU, 24 To de RAM, 64 To d'EBS), il y a déjà une belle marge

    • Mais si on loue un serveur bare metal chez Hetzner, on obtient des performances par cœur 2 à 3 fois supérieures pour 90 % de coût en moins
    • La taille maximale théorique de la base SQLite est indiquée à 281 To dans la documentation officielle. En pratique, la limite du système de fichiers est plus basse, mais ça fonctionne
    • Le scale-up sur machine unique est fiable, mais manque d'élasticité. En cas de pic de trafic, il faut soit surprovisionner, soit accepter le risque de panne
    • En regardant le lien yourdatafitsinram.net qui pose la question « est-ce que vos données tiennent en RAM ? », je pense qu'avec un nœud unique performant, un serveur dédié est préférable à EC2
  • L'article mettait l'accent sur l'efficacité de SQLite, mais j'ai trouvé que la base de comparaison manquait de clarté
    À l'origine, il partait d'une architecture à serveurs séparés, puis il a mesuré les performances d'une base embarquée locale
    À conditions égales, on pourrait probablement obtenir des performances similaires avec un Postgres local bien optimisé

    • SQLite est plus rapide que Postgres sur la même machine. Il est logique de tester selon une configuration représentative d'un vrai déploiement
    • On peut aussi placer SQLite derrière un gestionnaire de requêtes et l'exécuter depuis un autre serveur. Au fond, une base de données n'est qu'une combinaison entre un traitement des requêtes et un stockage
    • Sur une seule machine, c'est le débit brut (raw throughput) qui compte. SQLite est 10 fois plus rapide que PG, et PG ralentit à mesure que la complexité transactionnelle augmente
    • Dire que « SQLite n'est donc pas un point de comparaison valable » est beaucoup trop simpliste. L'article deviendrait trop court
    • SQLite convient non seulement au mobile ou à l'embarqué, mais aussi aux applications serveur à faible concurrence. Ce n'est pas une base réservée aux serveurs web
  • Limiter Postgres à 8 connexions peut constituer un goulot d'étranglement
    Ce serait bien de publier aussi l'utilisation CPU et des threads, puis de refaire le test avec un pool de connexions plus large

    • Adapter le pool de connexions au nombre de cœurs (8) est défendable, mais s'il y a un sleep dans la transaction, cela crée un goulot d'étranglement
      En passant à 64 connexions, le débit pourrait être multiplié par 8. Il faut faire monter la configuration client jusqu'à atteindre la limite
    • J'ai du mal à croire à ces chiffres. J'obtiens des TPS bien plus élevés même avec MySQL sur le réseau
  • L'essentiel, c'est de reconnaître quand la latence réseau est le vrai goulot d'étranglement
    Pour beaucoup de charges de travail, une base locale ordinaire est plus rapide qu'une excellente base distante
    La vraie question n'est pas « quelle est la meilleure base ? », mais « a-t-on vraiment besoin de franchir la frontière réseau ? »

    • (Auteur) Exactement. Mon propos n'était pas d'alimenter le débat SQLite vs Postgres, mais de parler des limites des bases de données en réseau
    • Bien sûr, si tout tient en mémoire et qu'on utilise Redis ou Memcache, les performances montent facilement. Mais dans ce cas, on change les règles du jeu
  • Les bases de données en réseau ont l'avantage de faciliter le redéploiement d'une application
    On peut lancer une nouvelle instance puis arrêter l'ancienne, avec un déploiement presque sans interruption
    Si SQLite est sur la même instance, il faut redémarrer la base lors du remplacement, ce qui complique les choses. Je me demande si vous avez rencontré ce problème en production

    • Pour utiliser SQLite en production, il faut du stockage persistant et du NVMe. En général, on l'exploite sur un serveur bare metal unique
      Lors des migrations, il peut y avoir de l'indisponibilité. Grâce à Litestream, la réplication et les sauvegardes sont désormais plus simples
    • SQLite prend en charge l'accès multi-processus, donc on peut aussi faire un remplacement sans interruption en lançant un nouveau processus puis en arrêtant l'ancien
  • L'auteur a configuré PRAGMA synchronous="normal", ce qui signifie qu'il ne fait pas de fsync à chaque fois
    Pour une comparaison équitable, il faudrait utiliser "full"

    • Mais en mode WAL, "normal" reste acceptable. En cas de coupure de courant, on perd la durabilité, mais la cohérence transactionnelle est conservée
  • Je me demande à quoi ressemble une configuration HA (haute disponibilité) avec SQLite
    Il faudrait au minimum un niveau permettant un basculement automatique

    • SQLite étant une bibliothèque C, on peut l'étendre avec des projets comme rqlite, litestream ou litefs
      J'hésite en ce moment entre Postgres et SQLite (avec litestream).
      Mon application tolère un peu d'indisponibilité, donc faire du scale-up vertical sur une seule machine est plus simple et moins coûteux
    • Récemment, un projet multi-maître appelé Marmot a repris vie après deux ans.
      Un nouveau mécanisme de réplication basé sur gossip a été ajouté sur le GitHub de Marmot
  • Je me demande s'il existe des cas réels où SQLite a été poussé à ses limites en production

  • Dans un environnement de web app ou d'e-commerce classique, je me demande où se situe la limite en nombre d'utilisateurs entre SQLite et Postgres
    SQLite permet désormais, grâce à des mises à jour récentes, la lecture concurrente mais n'autorise toujours qu'une seule écriture
    J'aimerais savoir dans quels cas cela devient problématique et, si l'on prévoit de monter en charge, s'il vaut mieux partir directement sur Postgres