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 44�a0096 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 186�a0157 TPS, et 102�a0545 TPS dans une configuration stable
  • La loi dAmdahl explique le goulot d�e9tranglement 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 d�e9liminer les goulots d�e9tranglement reseau

Structure de SQLite et environnement dexp�e9rimentation

  • 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 surco�fbt reseau
  • Les benchmarks ont �e9t�e9 effectu�e9s sur un MacBook Pro (2021) Apple M1 Pro avec 16 Go de m�e9moire
  • Lobjectif n�e9tait pas une optimisation parfaite, mais de montrer qu�eil est possible dobtenir un haut d�e9bit d�e9criture dans des conditions ordinaires

D�e9finition du TPS et exemple de transaction

  • Le TPS ne d�e9signe pas une simple vitesse d�e9criture, mais une transaction interactive (Interactive Transaction)
    • Exemple : lors d�eun virement entre comptes, plusieurs requ�eates et du code applicatif s�e9ex�e9cutent dans une m�eame transaction
  • En cas d�eerreur, une transaction peut revenir en arri�e8re, ce qui joue un r�f4le essentiel dans le maintien de la coh�e9rence

Configuration du benchmark

  • Des virtual threads bas�e9s sur Clojure ont �e9t�e9 utilis�e9s pour simuler un grand volume de requ�eates concurrentes
  • Postgres a �e9t�e9 configur�e9 avec un pool de connexions bas�e9 sur HikariCP, tandis que SQLite utilisait un writer unique et autant de connexions de lecture que de c53urs
  • Les deux bases de donn�e9es utilisent une table account simple avec les champs id, balance, et un milliard de lignes y ont �e9t�e9 ins�e9r�e9es
  • L�eactivit�e9 utilisateur suit une distribution en loi de puissance (0.9995), avec environ 100�a0000 utilisateurs actifs

Performances d�eune base de donn�e9es en r�e9seau (Postgres)

  • Sur le m�eame serveur, Postgres a atteint 13�a0756 TPS
  • Avec 5 ms de latence r�e9seau ajout�e9e, il tombe �e0 1�a0214 TPS, puis �e0 702 TPS avec 10 ms
  • Apr�e8s application du niveau d�eisolement s�e9rialisable, le d�e9bit chute �e0 660 TPS, puis �e0 348 TPS en ajoutant des requ�eates suppl�e9mentaires
  • Cela montre, conform�e9ment �e0 la loi d�eAmdahl, que le goulot d�e�e9tranglement r�e9seau limite les performances globales
    • Quand la latence r�e9seau augmente, la contention sur les verrous transactionnels s�e9aggrave, ce qui emp�eache toute mont�e9e en charge

Les avantages du mode embarqu�e9 de SQLite

  • Une fois le r�e9seau supprim�e9, SQLite atteint 44�a0096 TPS
    • La disparition du goulot d�e�e9tranglement r�e9seau minimise l�eimpact de la loi d�eAmdahl
  • En exploitant sa structure �e0 writer unique avec du batch processing, le d�e9bit monte jusqu�e0 186�a0157 TPS
    • Un ajustement dynamique de la taille des batchs optimise automatiquement la latence et le throughput

Transactions granulaires avec SAVEPOINT

  • Pour �e9viter qu�e9un �e9chec individuel n�eannule tout un batch, des transactions imbriqu�e9es avec SAVEPOINT ont �e9t�e9 utilis�e9es
    • En cas d�e�e9chec, seule la transaction concern�e9e est annul�e9e, tandis que le batch complet est conserv�e9
  • M�eame avec cette approche, le syst�e8me maintient 121�a0922 TPS

Test de charge mixte lecture/�e9criture

  • 75 % des requ�eates �e9taient des lectures et 25 % des �e9critures
  • Un pool de threads de lecture distinct a permis de s�e9parer les lectures pour qu�eelles ne perturbent pas les �e9critures
  • Le r�e9sultat final atteint 102�a0545 TPS

R�e9sum�e9 comparatif des performances

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

Conclusion

  • SQLite atteint un TPS nettement sup�e9rieur �e0 celui des bases de donn�e9es en r�e9seau gr�e2ce �e0 son mod�e8le �e0 writer unique et sa structure embarqu�e9e
  • En �e9vitant les limites de goulot d�e�e9tranglement r�e9seau mises en avant par la loi d�eAmdahl, il maximise son efficacit�e9
  • Le code complet est publi�e9 sur GitHub, avec des ressources associ�e9es sur la loi d�eAmdahl, les lois de puissance et des cas de mont�e9e en charge de SQLite
  • SQLite constitue un choix tr�e8s 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