- はじめに — インプロセスDBがサーバーを持つということ
- 事実関係から
- どんな見た目か
- プロトコル設計 — なぜHTTPか
- なぜArrow Flight SQLではなかったか
- ベンチマーク — まずベンダー自己測定だという点から
- セキュリティのデフォルト — ここが一番注意すべき場所
- Quackがしないこと
- Quack vs DuckLake — 混同しやすい点
- で、あなたは使うべきか
- おわりに
- 参考資料
はじめに — インプロセスDBがサーバーを持つということ
DuckDBのアイデンティティは、長らく一文で言い表せるものでした — クライアントもサーバーもなく、プロトコルもなく、ただ低レベルのAPI呼び出しがあるだけ。2019年の最初のリリース以来、DuckDBチームはこのインプロセス(in-process)構造をかなり大きな声で誇ってきましたし、実際にそれは価値を発揮しました。Pythonノートブックの中でアナリストが自分のデータをいじるワークロード、既存アプリケーションにSQL機能を追加するワークロードでは、プロトコルオーバーヘッドがゼロであることは圧倒的な利点だからです。
ところが2026年5月12日、同じチームがQuack: The DuckDB Client-Server Protocolを発表しました。DuckDBインスタンス2つがネットワーク越しに互いに話すプロトコルです。片方がサーバーに、片方がクライアントになります。
これが興味深いのはパフォーマンスの数字のためではありません。7年間「私たちはクライアント・サーバーではない」をアーキテクチャ上の信念として掲げてきたプロジェクトが、自らそれを取り付けたという事実のためです。発表記事の文章はこの転換をかなり率直に説明しています — "In the end we care deeply about user experience and perhaps less about having the last word on architecture."
そこで本稿は「DuckDBがついにサーバーになった!」を繰り返す代わりに、実際に何が可能になり、何が依然としてできないままなのかを見ます。後者のほうがはるかに長いリストです。
事実関係から
ハイプを取り除くには、日付とバージョンから固定しておくのがいいでしょう。
- 2026年5月12日 — Quack発表。この時点では
core_nightlyリポジトリにあり、当時の最新リリースであるDuckDB v1.5.2で使えました。 - 2026年5月20日 — DuckDB v1.5.3でQuackがコア拡張機能に昇格しました。これで初回使用時に透過的に自動インストール・自動ロードされます。同リリースでDuckLakeがQuackをカタログデータベースとして使えるようになりました。
- 状態: ベータ。 1.5.3リリース記事の表現そのままに — "Quack is still in beta state and breaking changes may happen in the protocol, in function names, etc."
- 安定化目標: DuckDB v2.0。 Quack FAQは「as part of DuckDB v2.0 in September 2026」と書いており、リリースカレンダーは2.0.0を「Fall 2026」と表記しつつ、これらの日付が暫定(tentative)であると明記しています。2つのページの表現が微妙に違うので、9月を確定として読まないでください。
つまり、今この記事を読んでいる時点(2026年7月)でQuackはプロトタイピング用です。FAQの「Is Quack production-ready?」への答えは、単に「Not yet」です。
どんな見た目か
ユーザー視点での形は驚くほどシンプルです。DuckDBインスタンスを2つ立ち上げ、片方でサーバーを起動します。
-- DuckDB #1 (サーバー)
CALL quack_serve('quack:localhost', token = 'super_secret');
CREATE TABLE hello AS FROM VALUES ('world') v (s);
-- DuckDB #2 (クライアント)
CREATE SECRET (TYPE quack, TOKEN 'super_secret');
ATTACH 'quack:localhost' AS remote;
FROM remote.hello;
アタッチすれば、リモートテーブルはローカルテーブルのように見えます。DDLも、書き込みも、トランザクションもそのまま伝わります。
CREATE TABLE remote_db.t AS FROM range(10) r (i); -- リモートDDL
INSERT INTO remote_db.t VALUES (42); -- リモート書き込み
FROM remote_db.t WHERE i = 42; -- フィルタもリモート実行
BEGIN; ...; COMMIT; -- トランザクション伝播
アタッチせず一発で投げる方法もあります。
FROM quack_query('quack:localhost', 'SELECT 42', token = 'MY_TOKEN');
プロトコル設計 — なぜHTTPか
設計上の選択がいくつか目を引きます。すべて公式ドキュメントのOverviewにまとまっています。
HTTPベース。 発表記事のロジックは防御的というより実用的です — "It would be rather misguided not to build a database protocol on top of HTTP in 2026." 理由も明快です。ロードバランシング、認証、ファイアウォール、侵入検知 — HTTPはこのインフラ全部がすでに扱い方を知っている層だからです。カスタムのワイヤー転送を新たに運用する必要がありません。副次効果も一つあります。DuckDB-Wasm配布版がQuackをネイティブに話せるので、ブラウザの中のDuckDBがEC2上のDuckDBに直接アタッチできます。
application/duckdbシリアライゼーション。 新しいMIMEタイプを作り、エンコーディングはDuckDB内部のシリアライゼーション基盤をそのまま使います — WALファイルに書くのと同じコードパスです。ドキュメントの説明では、こうすることで交換フォーマットを経由する必要がなく、ネストされた型・decimal・intervalのような複雑な型が無損失で渡ります。
クライアント主導のリクエスト・レスポンス。 すべてのやり取りはクライアントが開始します。サーバー側からのプッシュ動作はありません。
クエリごとに往復1回。 接続ハンドシェイクのあと、クエリ1つはリクエスト・レスポンスのペア1つで完結します。大きな結果は後続のFETCHリクエストでチャンク単位に流れてきて、これは複数スレッドで並列化できます。
デフォルトポート9494。 94はネットスケープ・ナビゲーターが出た年なので覚えやすい、というのがチームの説明です。
ここでDuckDBチームが自分たちの経歴を活かしている点がおもしろいところです。この人たちは2017年にDon't Hold My Data Hostage — A Case for Client Protocol Redesign(Raasveldt・Mühleisen、VLDB 2017)という論文を書いています。大きな結果セットをDBからクライアントに移すのがどれだけ高コストか、既存プロトコルがなぜ非効率なのかを実測した論文です。9年後、その論文の著者たちがプロトコルをゼロから設計する機会を得たわけです。
なぜArrow Flight SQLではなかったか
当然の疑問であり、発表記事も付録を別途つけて答えています。理由は二筋に分かれます。
一つは技術的です。 Arrow Flight SQLには「one fateful design decision」があるというのがチームの指摘です — "every single query requires at least two protocol round trips, CommandStatementQuery and DoGet." 往復2回は小さな更新、特にレイテンシの大きい環境で不利です。Quackが往復1回にこだわった理由がここにあります。
もう一つは政治的です。 そしてこちらのほうが率直です — "We feel that in order to be able to keep innovating in data systems, we cannot allow ourselves to be restricted by formats that are controlled externally." つまり、外部が管理するフォーマットに縛られたくないということです。新しいデータ型やプロトコルメッセージを追加したければ、明日にでもリリースできるべきだ、と。
これは技術的優劣の問題というより、ガバナンス上の好みです。チームもArrowとADBCの価値は認めています — ODBC・JDBCの後継として、システム間のデータ交換の摩擦を減らすインターチェンジAPIとしては「works pretty well」だと書いています。ただしDuckDB内部で交換フォーマットを使うことには警戒があるということで、FAQはこれを「clean slate implementation from the core DuckDB team」であり「does not have any third-party dependencies」だとまとめています。
読み手としては、この説明をそのまま受け止めつつ、含意は計算しておく必要があります。QuackはDuckDB専用です。クライアントもサーバーもDuckDBでなければなりません。Arrow Flight SQLの利点 — 異種システムが同じプロトコルで話せる — をQuackは設計上放棄しています。その穴を埋めるサードパーティの代替として、airport拡張とGizmoSQLが依然として存在し、発表記事はGizmoSQLのPhilip Mooreに「この道を先に切り開いてくれた」ことへの謝辞を述べています。
ベンチマーク — まずベンダー自己測定だという点から
さて数字です。まず釘を刺しておきます。以下のベンチマークはすべて、DuckDBチーム自身が設計し自ら実行したベンダー自己測定です。 自分のプロトコルを発表する記事で、自分が作ったプロトコルが勝つ。驚くことではありませんし、それ自体が不誠実というわけでもありません — ただし、どこを測ってどこを測っていないかは見ておく必要があります。
測定環境は明記されています。AWS m8g.2xlarge(vCPU 8、RAM 32GB、ネットワーク「up to 15 Gbps」)、ArmのUbuntu、クライアントとサーバーは同じアベイラビリティゾーンの別マシン、インスタンス間の平均pingは約0.280 ms。5回測定の中央値。ベンチマークスクリプトも公開されています。ベンダーベンチマークとしてはかなり丁寧なほうです。
バルク転送 — TPC-Hのlineitemテーブルの行数を増やしながら転送した壁時計時間(低いほど良い)。
| 行数 | DuckDB Quack | Arrow Flight | PostgreSQL |
|---|---|---|---|
| 100k | 0.07 s | 0.07 s | 0.20 s |
| 1M | 0.24 s | 0.38 s | 2.20 s |
| 10M | 0.89 s | 2.90 s | 25.64 s |
| 60M | 4.94 s | 17.40 s | 158.37 s |
小さな書き込み — lineitemと同じ構造の空テーブルに1行ずつ、それぞれ個別のINSERTトランザクションとして5秒間挿入し、並列スレッド数を増やしながら測った秒間トランザクション数(高いほど良い)。
| スレッド | DuckDB Quack | Arrow Flight | PostgreSQL |
|---|---|---|---|
| 1 | 1,038 tx/s | 469 tx/s | 839 tx/s |
| 2 | 1,956 tx/s | 799 tx/s | 1,094 tx/s |
| 4 | 3,504 tx/s | 1,224 tx/s | 2,180 tx/s |
| 8 | 5,434 tx/s | 1,358 tx/s | 4,320 tx/s |
この数字をどこまで信じるか
チーム自身が明かしたキャビエットが一つあります。 バルク転送の表の下にこう書かれています — "In fairness we have to mention that the standard PostgreSQL clients do not parallelize reads over multiple threads, but Quack and Arrow can." つまりPostgreSQLの158秒には「標準クライアントがシングルスレッドで読む」というハンディキャップが混じっています。これを発表記事が自ら書き記しているのは評価に値します。
Arrow Flight側の条件も見る必要があります。 比較対象のArrow FlightはGizmoSQLサーバーが提供したもので、そのサーバーは内部的にDuckDBを使っています。つまりこれは「Arrow Flightプロトコルの理論上の最善」ではなく「特定の実装一つ」です。プロトコル比較というより実装比較に近いものです。
書き込みベンチマークのフレーミングは甘めに設定されています。 1行ずつ個別トランザクションでINSERTするワークロードは、PostgreSQLが生まれた目的そのものであり、列指向の分析エンジンが得意である理由はありません。それでも8スレッドまではQuackが勝ちます。ここでチームは自分の足を自分で撃っています — "Beyond that, we hit a current limitation of DuckDB itself in concurrent insertions per second into the same table. PostgreSQL scales better here, which is something to look into for us in the near future." 最大で約5,500 tx/sで天井にぶつかり、その先はPostgreSQLのほうがうまくスケールすると、自分の口で言っているわけです。ベンチマーク表が8スレッドで終わっている理由がこれです。
ちょっとした計算。 発表記事は60M行を「76 GB in CSV format!」と紹介しています。ですが76GBを4.94秒で転送したなら、秒間15.4GB、約123Gbpsです。明記された回線は「up to 15 Gbps」、つまり秒間約1.9GBなので、物理的に不可能です。76GBをその回線にそのまま流せば最低でも40秒はかかります。結論は難しくありません — 76GBはデータセットのCSV換算サイズを実感させるための表現であって、回線を流れたバイト数ではないのです。Quackのバイナリ表現はCSVよりはるかにコンパクトです。発表記事が嘘をついたわけではありませんが、2つの数字を並べて「秒間15GB」を思い浮かべたなら、それは読者が誤解させられたということです。
何を測っていないか。 すべて同一アベイラビリティゾーン、ping 0.280msです。WAN越しやレイテンシの大きい環境の数字はありません。これは地味に重要で、Quackが往復1回に力を入れた理由がまさに「latency-sensitive environments」だったからです。その設計が実際に価値を発揮する高レイテンシ環境の測定値が、まさに欠けています。TLSを有効にしたときのコストもありません(デフォルトが平文なので、ベンチマークも平文である可能性が高いです)。読み書きが混在する混合ワークロードもありません。
まとめると — バルク転送が速いという主張は再現スクリプトまであり信頼できますし、方向性も驚くものではありません(列指向のバイナリ転送がPostgresの行ベースプロトコルを圧倒するのは、2017年の論文の結論でもあります)。ただし「QuackはPostgreSQLより速いDB」というふうに読んではいけません。あの表はプロトコル転送のベンチマークであり、クエリエンジンのベンチマークではありません。
セキュリティのデフォルト — ここが一番注意すべき場所
セキュリティドキュメントの最初の一文が恐ろしいです。QuackサーバーはベースとなるDuckDBインスタンスのSQL表面全体を露出します — そのセッションが見られるすべてのテーブルへの読み書きを含めて。
だからデフォルト値は保守的に設定されています。
- サーバーは起動時にランダムな認証トークンを生成し、クライアントは接続のたびにそれを提示しなければなりません。
- サーバーはlocalhostにのみバインドします。外部から届くアドレスで開くには
allow_other_hostname => trueを明示的に渡す必要があります。 - TLSはサーバー自身では処理しません。 localhost通信にTLSインフラを持ち込んでも依存関係が増えるだけで実益がない、というのが理由です。
そして発表記事の勧告は断固としています — "We do not recommend opening up a DuckDB Quack endpoint directly to the Internet." 代わりに、nginxのような実績あるHTTPリバースプロキシを前段に置き、そこでTLSを終端せよと言っています。クライアント側は非ローカルURIに対してデフォルトでHTTPSを前提とします(上書き可能)。
認証・認可モデルは、いかにもDuckDBらしく拡張機能に押し出されています。発表記事の表現は正直です — "We are likely unable to capture everyone's use case, certainly not in a first release. The smart thing is therefore not to try." そこでデフォルトの認証関数と「全部許可」のデフォルト認可関数を提供しつつ、どちらもユーザーコードで差し替えられるようにしています。LDAPを問い合わせるのも、テキストファイルを読むのも、サイコロを振るのも、勝手にどうぞということです。コールバックは単なるSQLマクロとして書いても構いません。
実務的に訳すと: デフォルト設定では安全ですが、便利にした瞬間に安全装置を一つずつ切っていくことになります。 allow_other_hostname => trueを入れた瞬間、あなたは「そのDuckDBセッションが見えるすべてのテーブルへの読み書き権限がついた平文HTTPエンドポイント」を開くことになり、認可関数はデフォルトですべてのクエリに「はい」と答えます。プロキシと認可コールバックは選択ではなく必須だと読むのが正しいでしょう。
Quackがしないこと
ここが本稿の核心です。FAQがありがたく明示的に答えている項目です。
分散クエリ処理はしません。 FAQの原文そのまま — "Does DuckDB with Quack support distributed query processing? Currently, DuckDB with Quack does not support distributed query processing." Quackは複数のクライアントが一台のサーバーにアタッチする構造です。複数ノードが一つのクエリを分担処理するわけではありません。「クエリが1台に収まらない」という問題はQuackでは解決しません。発表直後にコミュニティで「水平スケーリングの問題が解決した」という反応が出ましたが(InfoQの報道で引用された反応の一つです)、ドキュメントが言っているのはそれではありません。Quackはアクセスをスケールさせるのであって、計算をスケールさせるわけではありません。
容量に天井があります。 FAQのDuckLake比較項目に数字があります — QuackサーバーはDuckDBネイティブのDBフォーマットを使い、これは「scale up to a few terabytes」の水準です。ペタバイト級が必要なら、それはDuckLake(あるいはIcebergの類)の領域だとドキュメントが直接案内しています。
書き込み同時実行性に天井があります。 上で見た約5,500 tx/s、8スレッドを超えるとDuckDB自体の限界に。チームは改善すると書いていますが("we plan to work on greatly increasing the transactions per second achievable")、それは未来形です。今すぐ秒間数万件の書き込みが必要なら、これは答えになりません。FAQは「OLTPワークロードに使えるか」に「Yes」と答えてはいますが、付いている注釈は「a few thousand writes per second on a server with 8 CPUs and 32 GB RAM」です。「数千」があなたの数字と合うかは、あなたにしかわかりません。
まだベータです。 プロトコル、関数名、デフォルト設定、すべて壊れる可能性があります。
そして反対側で重要なことが一つ。インプロセスモデルは死にません。 FAQはこれも釘を刺しています — "Yes, DuckDB as an in-process database will continue working just as it did before, and we will treat the in-process deployment model as a first-class citizen in the DuckDB ecosystem." Quackは方向転換ではなく足し算です。ノートブックでParquetを流し読みしている人は、この記事を読む必要はありません。
Quack vs DuckLake — 混同しやすい点
どちらも「マルチプレイヤーDuckDB」を標榜し、どちらも拡張機能で、どちらも複数のwriterを許します。だから混同しやすいのです。FAQが整理した違いはこうです。
| Quack | DuckLake | |
|---|---|---|
| DuckDB専用? | はい(DuckDB同士が通信) | いいえ(Spark、DataFusion、Trinoなども対応) |
| ストレージ | DuckDBネイティブDBフォーマット | オブジェクトストレージ + Parquet |
| 規模 | 数テラバイト | ペタバイト級も可能 |
| セットアップ | 両側に拡張機能をインストール | 中央カタログDB + オブジェクトストレージ |
発表記事は「part of this could also already be achieved with DuckLake, Quack makes this far simpler and provides far higher performance」と書いています。ただしこれは同時書き込みアクセスという狭い軸での話であり、2つのものの目的は同じではありません。
そして2つは排他的ではありません。v1.5.3以降、DuckLakeはQuackをカタログデータベースとして使えます。FAQの勧告は明快です — データが巨大か、タイムトラベルが必要なら、DuckLakeを使いつつ、それをQuackで提供されるDuckDBインスタンス経由でアクセスせよ、と。発表記事が予告している次のステップもこの方向です。DuckDBサーバー自体がリモートアクセス可能なDuckLakeのカタログサーバーになること。データインライニングのパフォーマンスで利得が期待できると書かれています。
DuckLakeの基本的な発想 — メタデータを大量のJSON・Avroファイルではなく、SQLデータベースに置くという考え方 — はDuckDB実践ですでに扱いました。
で、あなたは使うべきか
価値がある場合
- 複数のプロセスが同じDuckDBデータベースに同時に読み書きする必要がある。 FAQが最初に挙げるシナリオです。発表記事の例が具体的です — テレメトリを収集する複数のプロセスが同じDBに挿入する一方で、ダッシュボードが同じテーブルを照会している状況。これまでこれはDuckDBでは単純にできないことで、人々はカスタムRPCを書くか、Postgresに乗り換えていました。
- データがサーバーにあり、計算をデータの近くに寄せたい。 大きなサーバーが処理し、結果だけをノートブックで見る。
- 大きな結果セットをクライアントに頻繁に引き出す。あのバルク転送の数字が実際に価値を発揮する場面です。
- ブラウザ(Wasm)からリモートDuckDBにアタッチする必要がある。HTTPベースを選んだことの直接的な配当です。
- これまでDuckDBにクライアント・サーバーを付けようと手でRPCを書いていた。そのコードを消せます。
まだの場合
- プロダクション。 ベータです。チーム自身がそう言っています。
- 分散クエリ処理が必要。 設計上、ありません。
- 本物のOLTP。 秒間数万トランザクション、高い書き込み同時実行性 — Postgresを使ってください。DuckDBチーム自身、8スレッドを超えるとPostgresのほうが良いと書いています。
- ペタバイト級。 DuckLakeかIcebergの領域です。
- インプロセスで十分。 大半のDuckDBユーザーはここに該当します。プロトコルオーバーヘッドゼロをあえて捨てる理由はありません。
- 異種クライアントがアタッチする必要がある。 Quackは両側ともDuckDBでなければなりません。JavaアプリやGoサービスが直接話しかけるわけにはいきません。
おわりに
Quackで一番興味深いのはプロトコル設計そのものではなく、その裏にある判断です。DuckDBチームはインプロセスアーキテクチャをブランドにしてきたチームです。ところが人々がその上にクライアント・サーバーを無理やり取り付けるワークアラウンドをあまりに多く作ったので — カスタムRPC、Arrow Flightを乗せたGizmoSQL、MotherDuck独自のプロトコル、さらにはPostgresの中にDuckDBを入れるpg_duckdbまで — 結局「これは人々が本当に望んでいるものだ」と認めました。発表記事はこの過程を「we bit the bullet, eventually, finally」と表現しています。アーキテクチャの純粋性よりユーザー体験を選んだという自己説明が、そのまま添えられています。
その結果を正直に言えば範囲は狭いです。 DuckDBは分散クエリエンジンにもなっていませんし、Postgresの代替にもなっていません。数テラバイト級の単一サーバーに複数のDuckDBクライアントがアタッチして同時に読み書きできるようになった、ただそれだけです。ただ「それだけ」と言うには、それこそがまさに人々が7年間ワークアラウンドを作り続けてきた理由でもあります。
そしていつものように — ベンダーベンチマークではなく、あなたのワークロードで判断してください。あの表は、同一アベイラビリティゾーン、ping 0.280ms、平文HTTP、再現スクリプト公開という条件下で得られた、DuckDBチーム自身の測定です。丁寧に測定されたベンダーベンチマークも、やはりベンダーベンチマークです。あなたのレイテンシ、あなたのTLS、あなたの混合ワークロードで同じ絵が出るかは、v2.0が出たあとに自分で測り直すのが正しいでしょう。
参考資料
- Quack: The DuckDB Client-Server Protocol (DuckDBチーム、2026-05-12) — 発表記事。設計根拠、ベンチマーク、Arrow Flight SQLを使わなかった理由(付録)
- Quackプロジェクトページ — 概要とアーキテクチャ図
- Frequently Asked Questions for Quack — 分散クエリ非対応、ベータ状態、DuckLakeとの違いなど、核心的な限界がここにあります
- Quack Remote Protocol — 公式ドキュメントOverview — プロトコルの要約とクライアント・サーバーの使い方
- Quackドキュメント — Security — 露出モデルと認証・認可コールバック
- DuckDB 1.5.3: Not an Ordinary Patch Release (2026-05-20) — Quackのコア拡張機能への昇格、DuckLakeカタログ連携
- Announcing DuckDB 1.5.0 (2026-03-09) — Variegataリリース
- DuckDBリリースカレンダー — v2.0.0の予定(暫定)
- Don't Hold My Data Hostage — A Case for Client Protocol Redesign (Raasveldt・Mühleisen、VLDB 2017) — このプロトコル設計の知的なルーツ
- Quackベンチマークスクリプト
- DuckDB Quack: Client/Server Protocol over HTTP for Multi-User Analytics (InfoQ, Renato Losio, 2026-05-31) — 外部報道とコミュニティの反応
- DuckDB実践 — ノートPCで完結する組み込み分析の時代 (関連記事)
현재 단락 (1/111)
DuckDBのアイデンティティは、長らく一文で言い表せるものでした — クライアントもサーバーもなく、プロトコルもなく、ただ低レベルのAPI呼び出しがあるだけ。2019年の最初のリリース以来、Duck...