J'ai vu passer beaucoup d'articles sur DuckDB qui expliquent que c'est rapide, colonne, embarqué, MIT.
Très bien.
Mais concrètement, on s'en sert pour quoi, et à la place de quoi ?
Voici les cas d'usage réels, puis la liste de ce que ça vire de votre stack, puis la liste de ce que ça ne remplace pas.
DuckDB en une phrase
C'est un moteur SQL analytique qui tourne dans votre process sur les projets Python. Pas de serveur, pas de daemon, pas de connection string, pas de docker-compose.
Vous faites un
pip install duckdb
ou vous téléchargez un binaire de quelques dizaines de mégas, et vous avez un moteur OLAP complet.
La comparaison qui marche le mieux, c'est SQLite.
Même philosophie : un fichier, une lib, zéro infra.
Sauf que SQLite est orienté ligne et conçu pour du transactionnel (lire et écrire des enregistrements un par un), là où DuckDB est orienté colonne et conçu pour agréger des millions de lignes d'un coup.
En pratique : SQLite pour stocker les données de votre application, DuckDB pour les analyser.
Le truc qui m'a fait basculer
DuckDB sait faire du SQL directement sur un fichier. Pas d'import, pas de schéma à déclarer, pas de CREATE TABLE.
duckdb -c "SELECT * FROM 'export.csv' LIMIT 5"
C'est tout. Il détecte le délimiteur, l'encodage, la présence d'un header et le type de chaque colonne tout seul.
Et ça marche pareil sur du Parquet, du JSON, du xlsx, et sur des motifs glob :
SELECT status, count(*) AS n
FROM 'logs/2026-*.csv'
GROUP BY status
ORDER BY n DESC;
Vous venez d'agréger douze fichiers sans écrire une ligne de Python.
Les cas où je m'en sers vraiment
Le fichier client que rien n'arrive à ouvrir
Un client vous envoie un export de 3Go. Excel plafonne à 1 048 576 lignes et refuse.
Votre éditeur de texte rame, un import PostgreSQL prend 20 minutes de setup.
duckdb -c "SELECT count(*), min(date), max(date) FROM 'export.csv'"
30 secondes, vous savez ce qu'il y a dedans. C'est le cas d'usage le plus bête et c'est celui que j'utilise le plus souvent.
Convertir en Parquet pour arrêter de souffrir
COPY (FROM 'export.csv') TO 'export.parquet' (FORMAT parquet);
Le fichier passe typiquement de 3 Go à quelques centaines de mégas, et toutes les requêtes suivantes sont plusieurs fois plus rapides parce que le format est colonne et compressé.
Si vous manipulez régulièrement les mêmes gros CSV, c'est le premier réflexe à prendre.
Faire de l'analytique sans toucher à la prod
Vous attachez la base PostgreSQL de prod en lecture seule, vous rapatriez ce dont vous avez besoin, et vous travaillez en local.
ATTACH 'host=db.prod dbname=app user=readonly' AS prod (TYPE postgres, READ_ONLY);
CREATE TABLE commandes AS
FROM prod.public.commandes;
Plus de requête analytique lourde qui part sur le serveur applicatif un mardi à 15h. Le même mécanisme existe pour MySQL et SQLite.
Joindre des sources qui n'ont rien à voir entre elles
Celle-là, c'est ma préférée. Vous avez vos utilisateurs dans PostgreSQL et vos événements en Parquet sur S3. Normalement, c'est un pipeline.
CREATE SECRET (
TYPE s3,
KEY_ID '...',
SECRET '...',
REGION 'eu-west-3'
);
ATTACH 'host=localhost dbname=app' AS pg (TYPE postgres, READ_ONLY);
SELECT u.email, sum(e.montant) AS total
FROM pg.public.users u
JOIN 's3://mon-bucket/events/*.parquet' e
ON e.user_id = u.id
GROUP BY u.email
ORDER BY total DESC
LIMIT 20;
En 1 requête. Sans ETL, pas d'orchestrateur, pas de staging.
Et DuckDB ne télécharge que les colonnes et les blocs Parquet dont il a besoin, pas le bucket entier.
Ça marche aussi avec Cloudflare R2, Google Cloud Storage, Azure et Hugging Face.
Remplacer pandas dans les scripts
DuckDB requête directement un DataFrame pandas, sans copie explicite.
import duckdb
import pandas as pd
ventes = pd.read_csv('ventes.csv')
duckdb.sql("""
SELECT region, sum(ca) AS total
FROM ventes
GROUP BY region
""").df()
L'intérêt n'est pas seulement la performance. C'est que du SQL d'agrégation reste lisible 6 mois plus tard, ce qui n'est pas toujours le cas d'un enchaînement de groupby, merge et apply.
Et DuckDB déborde sur disque quand ça ne tient plus en mémoire, là où pandas vous jette avec une MemoryError.
Rendre un livrable en xlsx
Parce que dans la vraie vie, le client veut son Excel.
COPY (SELECT * FROM resultats)
TO 'rapport.xlsx' WITH (FORMAT xlsx);
Alors ça remplace quoi ?
Voilà la partie qui vous intéresse.
- pandas et polars, pour tout ce qui est agrégation, jointure et filtrage. Vous gardez pandas pour le reste de l'écosystème scientifique.
- SQLite, dès que vous faites de l'analytique et non du transactionnel. Comptages, agrégations, fenêtres glissantes, jointures sur plusieurs millions de lignes.
- Un PostgreSQL monté juste pour analyser, celui que vous installez uniquement parce que vous vouliez faire du SQL sur des fichiers. Celui-là, vous pouvez le supprimer.
- Spark et PySpark, sur tout ce qui tient sur une machine. Ce qui, honnêtement, couvre l'écrasante majorité des projets sur lesquels on intervient.
- BigQuery, Snowflake, Redshift, Athena, tant que vos volumes ne justifient pas un entrepôt facturé à la requête. Sur quelques dizaines de gigas, DuckDB sur un VPS fait le travail pour le prix du VPS.
- ClickHouse, quand vous n'avez pas besoin du multi-utilisateur ni du temps réel, et que vous ne voulez pas exploiter un serveur de plus.
- Excel, sur tout fichier qui dépasse le million de lignes.
- Vos scripts Python de parsing maison. Le module csv, les boucles de nettoyage, les conversions de types faites à la main.
- Une API REST écrite uniquement pour requêter une base depuis un front, si vous partez sur DuckDB-Wasm dans le navigateur.
Il y a aussi un cas moins évident : DuckDB est une cible dbt à part entière via dbt-duckdb. Vous pouvez donc faire tourner une stack de transformation complète en local, sans entrepôt cloud, y compris en CI.
Ce que ça ne remplace pas
C'est important, parce que la moitié des déceptions viennent de là.
- Le backend de votre application. DuckDB n'est pas fait pour encaisser des milliers d'écritures concurrentes ligne à ligne. Votre API reste sur PostgreSQL.
- Une base multi-tenant. Pas de gestion de rôles et de permissions comparable à celle de PostgreSQL.
- Du vrai temps réel multi-utilisateur. Même avec les nouveautés dont je parle plus bas, on n'est pas sur le terrain de ClickHouse ou de Pinot.
- Un entrepôt à l'échelle pétaoctet. Si vous avez vraiment ces volumes, vous avez vraiment besoin d'autre chose. Mais posez-vous honnêtement la question de vos volumes réels avant de répondre.
- Un catalogue et une gouvernance d'entreprise. Lineage, data contracts, audit centralisé : ce n'est pas le périmètre.
La règle simple que j'applique : écriture transactionnelle intensive et concurrente, c'est PostgreSQL. Lecture et agrégation, c'est DuckDB.
Maintenant, les chiffres
Une fois qu'on a le cadre, les performances deviennent intéressantes.
Depuis mai 2026, DuckDB a un protocole client-serveur officiel qui s'appelle Quack. Deux instances DuckDB peuvent se parler sur le réseau, l'une jouant le serveur, l'autre le client. Ça débloque le multi-writer, qui était la limite historique du modèle in-process.
Les chiffres publiés par l'équipe, sur des machines AWS Arm dans la même zone de disponibilité :
- Transfert de 60 millions de lignes : 4.94s en Quack, 17.40s en Arrow Flight, 158.37s en protocole PostgreSQL
- Transfert de 10 millions de lignes : 0.89s contre 2.90s et 25.64s
- Petites écritures, 8 threads : 5 434 transactions/seconde en Quack, 4 320 en PostgreSQL
Précision qui compte : ce sont des benchmarks d'éditeur, publiés par l'équipe DuckDB sur son propre protocole. Les scripts sont sur GitHub, ce qui est déjà mieux que la moyenne du secteur, mais ce ne sont pas des mesures tierces.
À leur crédit, ils documentent aussi le point où ça décroche : au-delà de 8 threads, c'est DuckDB lui-même qui plafonne sur les insertions concurrentes dans une même table, et PostgreSQL repasse devant. C'est écrit noir sur blanc dans l'annonce. Un éditeur qui publie la limite de son produit, ça mérite d'être signalé.
Quack est en bêta. La version stable est annoncée avec DuckDB 2.0, prévu à l'automne 2026. Donc à tester, pas à mettre en prod critique aujourd'hui.
Et méfiez-vous des reprises de seconde main. J'en ai croisé au moins une qui décrit Quack comme du Protobuf avec TLS. C'est faux sur les deux points : la sérialisation est maison, et il n'y a pas de SSL par défaut. Allez lire la source.
Le point qui change tout et dont personne ne parle
DuckDB avait l'occasion parfaite de monétiser Quack.
Le client-serveur, c'est LA fonctionnalité entreprise.
Le genre de truc qu'on réserve à une édition commerciale ou à son offre cloud.
Le playbook est connu par cœur: vous construisez un projet open source, vous captez l'adoption, puis vous relicenciez sous BSL ou SSPL au moment où vos utilisateurs ne peuvent plus partir.
Même Redis l'a fait, Elastic et HashiCorp.
DuckDB a sorti Quack en MIT.
Ce n'est pas une question de vertu, c'est une question de structure.
La propriété intellectuelle appartient à la DuckDB Foundation, une entité à but non lucratif dont les statuts garantissent le maintien sous MIT.
La société commerciale derrière, DuckLabs (ex-DuckDB Labs, renommée fin mai), déclare une trentaine de salariés à Amsterdam et aucun financement par capital-risque, avec un chiffre d'affaires basé sur le support et la priorisation de fonctionnalités.
Pas de VC, donc pas de sortie à provoquer à 5 ans, donc pas de relicenciement défensif quand la courbe plafonne.
Quand je choisis une brique qui va rester dans un projet client pendant cinq ans, c'est ce genre de chose que je regarde avant les benchmarks.
Par où commencer
Trois commandes, et vous saurez en dix minutes si ça sert votre cas.
curl https://install.duckdb.org | sh
Ou en Python :
pip install duckdb
Puis prenez le plus gros CSV qui traîne sur votre disque :
duckdb -c "DESCRIBE FROM 'votre_fichier.csv'"
duckdb -c "SELECT count(*) FROM 'votre_fichier.csv'"
La version courante est la 1.5.4, sortie le 17 juin 2026, avec une branche 1.4.5 en LTS si vous préférez la stabilité.
La question que ça pose
Sur les 5 dernières années, combien de fois avez-vous monté une infrastructure data pour des volumes qui tenaient sur un SSD ?
Moi, je l'ai fait 2 ou 3 fois.
Et à chaque fois, le coût réel n'était pas la facture cloud, c'était le temps passé à maintenir tout le bousin.