DuckDB publie son protocole client-serveur officiel. Ce n'est pas un "PostGIS killer" — c'est la séparation transactionnel / analytique qui arrive enfin en géomatique.
Pour qui ? Géomaticiens, data engineers, architectes SI et consultants SIG qui doivent positionner (ou défendre) leur serveur de données spatiales en 2026.
Le 12 mai 2026, l'équipe DuckDB a publié Quack, son protocole client-serveur officiel. Pour mesurer l'événement, il faut se rappeler que DuckDB s'est construit sur le refus exact de ce modèle : une base in-process, embarquée dans votre script Python ou votre notebook, sans serveur, sans DBA, sans port à ouvrir.
Cette doctrine reste valide pour l'analytique interactive. Mais elle se heurtait à un mur dès que plusieurs processus devaient lire et écrire la même base. L'écosystème avait répondu par une accumulation de contournements — RPC maison, Arrow Flight, MotherDuck, pg_duckdb — dont la prolifération a fini par convaincre l'équipe : le besoin était légitime.
La trajectoire devient limpide quand on la met bout à bout :
ST_* inspirées de PostGIS)💡 Insight #1 — Ce qui se joue vraiment
La question n'est pas "DuckDB va-t-il tuer PostGIS ?". C'est la séparation OLTP / OLAP — tranchée il y a vingt ans dans le monde des bases de données — qui arrive enfin en géomatique. Le transactionnel d'un côté, l'analytique de l'autre, et un protocole pour servir le second.
Pas de protocole binaire propriétaire sur TCP : Quack roule sur HTTP. Choix pragmatique et revendiqué — "HTTP has become a de-facto protocol layer on top of TCP". Conséquences concrètes :
Les données circulent avec un type MIME dédié, application/duckdb, qui réutilise les primitives de sérialisation internes de DuckDB — les mêmes qui font tourner le Write-Ahead Log depuis des années. Pas de conversion vers un format d'échange neutre, donc pas de coût de traduction. C'est un choix assumé contre l'interopérabilité d'Arrow, au profit de la performance et de la liberté d'évolution.
C'est l'argument architectural central. Arrow Flight SQL impose au minimum deux round-trips par requête (CommandStatementQuery puis DoGet). Quack traite une requête complète en un seul échange. Sur des petites requêtes fréquentes — le quotidien d'un dashboard — la latence réseau domine le temps de réponse : diviser les allers-retours par deux est décisif.
| Critère | Quack | Arrow Flight SQL | PostgreSQL wire |
|---|---|---|---|
| Transport | HTTP | gRPC | TCP propriétaire |
| Round-trips minimum / requête | 1 | 2 | 1 |
| Format de données | Sérialisation DuckDB native | Arrow (interchange universel) | Lignes texte/binaire |
| Accès navigateur (Wasm) | Oui, natif | Limité | Non |
| Écosystème clients | DuckDB uniquement | Multi-langages | Universel (QGIS, ETL, BI…) |
Scénario : une VM modeste héberge vos référentiels convertis en tables DuckDB (un GeoPackage de parcelles, les bâtiments Overture en GeoParquet). Les agents, scripts et notebooks s'y connectent à distance.
-- Extensions spatiale + serveur
INSTALL spatial; LOAD spatial;
-- Démarrer le serveur Quack (binding réseau + token)
CALL quack_serve(
'quack:0.0.0.0',
token = 'super_secret'
);
-- Charger les référentiels une fois, côté serveur
CREATE TABLE parcelles AS
FROM ST_Read('parcelles_saclay.gpkg');
CREATE TABLE batiments AS
FROM 'overture/buildings/*.parquet'; -- GeoParquet lu tel quel
-- Déclarer le secret d'authentification
CREATE SECRET (
TYPE quack,
TOKEN 'super_secret'
);
-- Attacher la base distante comme une base locale
ATTACH 'quack:srv-geo.mondomaine.local' AS remote;
-- Interroger les tables distantes
FROM remote.parcelles LIMIT 10;
import duckdb
con = duckdb.connect()
con.sql("CREATE SECRET (TYPE quack, TOKEN 'super_secret')")
con.sql("ATTACH 'quack:srv-geo.mondomaine.local' AS remote")
df = con.sql("""
SELECT b.id, ST_Area(b.geometry) AS surface
FROM remote.batiments b
JOIN remote.parcelles p ON ST_Intersects(b.geometry, p.geom)
WHERE p.commune = 'Palaiseau'
""").df()
La fonction query() envoie du SQL verbatim exécuté côté serveur. Le calcul lourd se fait près des données, seul le résultat traverse le réseau :
-- Agrégation exécutée sur le serveur, résultat seul transféré
FROM remote.query('
SELECT commune, COUNT(*) AS nb, SUM(ST_Area(geometry)) AS surface_totale
FROM batiments GROUP BY commune
');
💡 Insight #2 — Le pattern qui change la donne
Serveur Quack + GeoParquet + clients Wasm = un dashboard cartographique sans backend, interrogeant en SQL spatial une instance centrale, pour le coût d'une petite VM. Là où la réponse classique était "il faut monter un GeoServer et une base PostGIS".
Mesures publiées dans l'annonce DuckDB (instances EC2 m8g.2xlarge, latence réseau 0,28 ms).
| Protocole | Temps | Débit |
|---|---|---|
| Quack | 4,94 s | ~12 millions de lignes/s |
| Arrow Flight | 17,40 s | 3,5× plus lent |
| PostgreSQL | 158,37 s | ~32× plus lent |
| Threads parallèles | Quack | PostgreSQL | Arrow Flight |
|---|---|---|---|
| 1 | 1 038 tx/s | 839 tx/s | 469 tx/s |
| 8 | 5 434 tx/s | 4 320 tx/s | 1 358 tx/s |
Deux lectures honnêtes de ces chiffres :
Posez ces questions pour chaque flux de données géospatiales de votre SI. Le pattern général : PostGIS garde la transaction, la pile GeoParquet + DuckDB prend l'analyse.
pg_duckdb / Crunchy Bridge..prj pas toujours chargés). Gérez les reprojections explicitement, ou gardez cette étape dans PostGIS.ST_* incomplète face à 20 ans de PostGIS.duckdb.org/2026/05/12/quack-remote-protocolcrunchydata.com/blog/postgis-meets-duckdb-crunchy-bridge-for-analytics-goes-spatialnews.ycombinator.com/item?id=43881468duckdb.org/docs/extensions/spatial