Deux bases de données, deux philosophies
SQLite et PostgreSQL parlent tous les deux le SQL, stockent tous les deux des données relationnelles, et peuvent tous les deux faire tourner de vraies applications. Mais au-delà de ça, ils sont pensés pour des mondes très différents.
- SQLite est une bibliothèque. Elle s'exécute à l'intérieur du processus de votre application et lit un simple fichier
.dbsur le disque. Pas de serveur, pas de port réseau, aucun utilisateur à configurer. - PostgreSQL est un serveur. Il tourne dans son propre processus, écoute sur un port réseau, et votre application s'y connecte en tant que client.
Quasiment toutes les autres différences entre SQLite et PostgreSQL — concurrence, déploiement, rigueur du typage, performances — découlent directement de cette différence d'architecture. Gardez-la en tête tout au long de cet article.
Architecture : embarqué ou client/serveur
Ouvrir une base SQLite, c'est simplement ouvrir un fichier :
Pas de démon à démarrer, pas de pg_hba.conf à bricoler, pas de port à ouvrir. Votre application charge la bibliothèque SQLite, ouvre notes.db et exécute ses requêtes. Pour déployer ? Il suffit de copier le fichier.
Avec PostgreSQL, c'est une autre histoire :
# Démarrer le serveur (une seule fois, en tant qu'administrateur) :
sudo systemctl start postgresql
# Puis se connecter depuis votre application :
psql -h localhost -U alice -d mydb
Votre application discute avec un processus séparé — en général via TCP, parfois via une socket Unix. Cette couche supplémentaire vous coûte un peu de configuration et un aller-retour de connexion par requête, mais en échange vous obtenez l'accès réseau, l'authentification multi-utilisateurs et de vraies écritures concurrentes.
SQLite vs PostgreSQL : la concurrence avant tout
C'est souvent le critère qui tranche. SQLite sérialise les écritures : à un instant donné, un seul rédacteur détient un verrou sur le fichier de base de données, et les autres font la queue. Les lectures, elles, peuvent se faire en parallèle (surtout en mode WAL), mais les écritures s'enchaînent une par une.
PostgreSQL, lui, s'appuie sur MVCC (contrôle de concurrence multi-versions) et un verrouillage au niveau des lignes. Plusieurs transactions peuvent ainsi écrire sur des lignes différentes en même temps, sans se bloquer mutuellement.
Concrètement :
- Un blog avec 50 lecteurs par seconde et un auteur qui publie de temps en temps ? SQLite fait largement l'affaire.
- Un tunnel de paiement e-commerce où des centaines d'utilisateurs mettent à jour le stock simultanément ? PostgreSQL.
- Le cache local d'une app mobile ? SQLite, sans hésiter.
- Un backend SaaS multi-tenant avec des dizaines de workers en arrière-plan ? PostgreSQL.
Le mode WAL (PRAGMA journal_mode = WAL;) améliore nettement la concurrence côté SQLite — les lecteurs ne bloquent plus les rédacteurs — mais il ne change rien à la règle « un seul rédacteur à la fois ».
Système de types : permissif ou strict
PostgreSQL est strict. Une colonne déclarée en INTEGER refuse les chaînes, point final :
-- Postgres
CREATE TABLE t (n INTEGER);
INSERT INTO t (n) VALUES ('not a number');
-- ERREUR : syntaxe en entrée invalide pour le type integer
SQLite utilise par défaut ce qu'on appelle l'affinité de type — une suggestion plutôt qu'une vraie contrainte. Du coup, le même INSERT passe sans broncher :
La chaîne reste là, bien tranquille, dans une colonne INTEGER. SQLite l'a tout simplement stockée en texte. Cette souplesse n'est pas un bug, c'est un choix de conception assumé — pratique pour bricoler un prototype, mais risqué dès qu'on parle d'un schéma destiné à durer.
Depuis la version 3.37, SQLite propose les tables STRICT, dont le comportement se rapproche de celui de Postgres :
Si vous démarrez un nouveau projet SQLite, activez STRICT. Ça élimine d'un coup toute une catégorie de mauvaises surprises du genre « pourquoi j'ai une chaîne dans ma colonne numérique ».
Étendue des fonctionnalités
PostgreSQL en propose davantage sur presque tous les plans : types de données (tableaux, intervalles, types géométriques, réseau, enums personnalisés), langages procéduraux (PL/pgSQL, PL/Python), recherche plein texte avec scoring, vues matérialisées, partitionnement de tables, réplication, sécurité par rôles, et un écosystème d'extensions très riche (PostGIS, TimescaleDB, pgvector).
SQLite couvre l'essentiel et ajoute quelques bonus bienvenus pour son échelle d'usage : fonctions JSON, recherche plein texte via FTS5, index R-Tree, fonctions de fenêtrage, CTE, colonnes générées. Ce qu'il laisse de côté, c'est tout ce qui suppose un serveur : utilisateurs, rôles, réplication, accès réseau.
Un modèle mental rapide pour choisir :
- Besoin de SIG, de recherche vectorielle ou de réplication ? PostgreSQL.
- Besoin d'embarquer une base dans une app iOS ? SQLite.
- Besoin des deux ? Beaucoup d'équipes développent et testent sur SQLite, puis déploient sur PostgreSQL — sachant que ce mélange peut vous jouer des tours côté différences de syntaxe (voir ci-dessous).
Différences de syntaxe que vous allez vraiment rencontrer
Le SQL du quotidien est quasi identique entre les deux. Les différences se concentrent autour du schéma, des types, et de quelques fonctions intégrées :
-- Clé primaire auto-incrémentée
-- SQLite :
CREATE TABLE users (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT);
-- Postgres :
CREATE TABLE users (id SERIAL PRIMARY KEY, name TEXT);
-- ou, Postgres moderne :
CREATE TABLE users (id INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY, name TEXT);
-- Horodatage actuel
-- SQLite : CURRENT_TIMESTAMP (renvoie du texte)
-- Postgres : NOW() (renvoie un timestamp)
-- Type booléen
-- SQLite : pas de vrai BOOLEAN ; utiliser INTEGER 0/1
-- Postgres : BOOLEAN avec TRUE/FALSE
Si vous développez sur SQLite mais que vous déployez sur Postgres, garde un ORM ou un outil de migration entre vous et le SQL brut — sinon ces différences vont finir par polluer votre code applicatif.
Performances : parlons franchement
« Plus rapide » dépend de la question posée. Pour un processus unique qui fait des lectures et de petites écritures, SQLite est difficile à battre : pas d'aller-retour réseau, pas de protocole à parser, pas de connexion client. Sur des benchmarks mono-client, SQLite dépasse souvent Postgres sur des requêtes simples.
Mais dès qu'on ajoute des écritures concurrentes, de gros volumes qui profitent d'une exécution parallèle des requêtes, ou des plans complexes qui tirent parti du planificateur mature de Postgres, c'est Postgres qui prend l'avantage. Postgres passe aussi à l'échelle verticalement (machines plus puissantes, plus de cœurs) d'une manière pour laquelle SQLite n'a tout simplement pas été conçu.
Le résumé honnête : SQLite est rapide pour ce à quoi il est destiné. Postgres aussi. Le choix se fait en fonction de la nature de la charge, pas des titres accrocheurs des benchmarks.
SQLite ou PostgreSQL : quel SGBD choisir ?
Pars sur SQLite quand :
- Les données vivent à côté d'une seule application — desktop, mobile, embarqué, outil CLI.
- Les écritures viennent d'un seul processus ou d'un petit nombre de processus.
- Vous voulez un déploiement sans configuration.
- Tu prototypes et vous voulez te concentrer sur le schéma, pas sur l'infra.
Pars sur Postgres quand :
- Plusieurs serveurs applicatifs ou workers écrivent dans la base.
- Vous avez besoin d'un accès réseau depuis de nombreux clients.
- Il te faut des fonctionnalités avancées : rôles, réplication, GIS, types personnalisés, procédures stockées.
- Les données constituent le stockage central et durable d'un service en production.
Un parcours classique : démarrer un petit projet sur SQLite, puis migrer vers Postgres si et quand la charge l'exige. La migration n'est pas gratuite, mais c'est une opération bien balisée — et la plupart des projets n'en arrivent jamais là.
La suite : quand SQLite est le bon choix
La comparaison ci-dessus pose les compromis. La page suivante creuse les arguments en faveur de SQLite — les charges de travail où il n'est pas seulement suffisant mais bel et bien le meilleur outil, ainsi que les signaux qui indiquent que vous l'avez dépassé.
Questions fréquentes
Quelle est la vraie différence entre SQLite et PostgreSQL ?
SQLite est une bibliothèque embarquée qui lit et écrit dans un simple fichier, directement dans le processus de votre application. PostgreSQL, lui, est un serveur à part auquel on se connecte via le réseau. Cette seule différence d'architecture explique presque tout le reste : la concurrence, le déploiement, le typage, l'outillage… tout en découle.
SQLite est-il plus rapide que PostgreSQL ?
Pour des lectures mono-processus et de petites écritures, souvent oui : SQLite n'a ni aller-retour réseau, ni protocole client/serveur à gérer. Mais dès qu'on parle d'écritures concurrentes depuis plusieurs clients, Postgres prend l'avantage grâce au verrouillage au niveau de la ligne et au MVCC. Bref, la « rapidité » dépend surtout de la charge, pas du moteur.
Peut-on utiliser SQLite en production ?
Oui, à condition que la charge s'y prête. SQLite fait tourner sans souci des sites web, des applis desktop ou des objets connectés en production. La vraie limite, ce sont les écritures concurrentes : si plusieurs processus doivent écrire en même temps, Postgres gère ça nativement, alors que SQLite sérialise les écritures. Le mode WAL aide, mais ne supprime pas cette contrainte.
Comment migrer de SQLite vers PostgreSQL ?
Commencez par exporter votre schéma et vos données avec sqlite3 mydb.db .dump, puis ajustez le SQL : AUTOINCREMENT devient SERIAL ou GENERATED AS IDENTITY, certains noms de types changent, et il faut nettoyer les particularités de SQLite comme le typage souple. Des outils comme pgloader automatisent l'essentiel. Prévoyez de réécrire tout ce qui s'appuyait sur le typage flexible de SQLite.