<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Concurrency on DuckDB Lab</title><link>https://duckdblab.org/en/tags/concurrency/</link><description>Recent content in Concurrency on DuckDB Lab</description><generator>Hugo -- gohugo.io</generator><language>en-US</language><lastBuildDate>Fri, 15 May 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://duckdblab.org/en/tags/concurrency/index.xml" rel="self" type="application/rss+xml"/><item><title>DuckDB Quack Protocol: Native Client-Server Architecture Deep Dive</title><link>https://duckdblab.org/en/post/duckdb-quack-protocol/</link><pubDate>Fri, 15 May 2026 00:00:00 +0000</pubDate><guid>https://duckdblab.org/en/post/duckdb-quack-protocol/</guid><description>&lt;h2 id="introduction"&gt;Introduction
&lt;/h2&gt;&lt;p&gt;Ever since its inception, DuckDB has been known as an &amp;ldquo;embedded analytical database&amp;rdquo; — it embeds itself into the host process like SQLite, requiring no separate server deployment. This design brings undeniable advantages: zero operations, zero configuration, and millisecond startup times. But it also comes with a hard limitation: &lt;strong&gt;no multi-process concurrent access to the same database file.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;If your scenario involves:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;10 data collectors writing to the same database simultaneously&lt;/li&gt;
&lt;li&gt;A Dashboard running real-time queries while a batch ETL runs in the background&lt;/li&gt;
&lt;li&gt;Multiple microservices sharing a single analytical data source&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Then sorry, DuckDB&amp;rsquo;s native mode won&amp;rsquo;t work. Multiple processes writing to the same &lt;code&gt;.db&lt;/code&gt; file simultaneously will result in data corruption at best, and process crashes at worst.&lt;/p&gt;
&lt;p&gt;What were your options before?&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;pg_duckdb&lt;/strong&gt; — Wrap the DuckDB execution engine inside PostgreSQL, a workaround at best&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;MotherDuck&lt;/strong&gt; — Move data to the cloud and pay for a SaaS&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Switch to PostgreSQL/ClickHouse&lt;/strong&gt; — Change your entire tech stack just for concurrent access&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Build your own proxy layer&lt;/strong&gt; — Use Redis or message queues as a write buffer and handle conflicts yourself&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;All of these are either expensive, complex, or introduce significant operational overhead.&lt;/p&gt;
&lt;p&gt;In May 2026, the DuckDB team delivered a completely new answer — &lt;strong&gt;the Quack protocol&lt;/strong&gt;. A native remote communication protocol built on top of HTTP that allows DuckDB instances to communicate like a PostgreSQL client-server architecture. This is not a third-party plugin; it&amp;rsquo;s an official extension developed by the core DuckDB team.&lt;/p&gt;
&lt;h2 id="quack-protocol-architecture"&gt;Quack Protocol Architecture
&lt;/h2&gt;&lt;h3 id="design-philosophy"&gt;Design Philosophy
&lt;/h3&gt;&lt;p&gt;The Quack design can be summarized in three principles:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Native Integration&lt;/strong&gt; — Not an external proxy, but a DuckDB extension. Enable it with a single &lt;code&gt;INSTALL quack&lt;/code&gt; command.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Single Round-Trip&lt;/strong&gt; — One query requires exactly 1 network round trip, far more efficient than Arrow Flight SQL (at least 2 round trips).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;HTTP-Based&lt;/strong&gt; — Built on top of HTTP, compatible with existing network infrastructure. No special ports or protocols needed.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="architecture-diagram"&gt;Architecture Diagram
&lt;/h3&gt;&lt;pre tabindex="0"&gt;&lt;code&gt;┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ DuckDB │ │ DuckDB │ │ DuckDB │
│ Client A │ │ Client B │ │ Client C │
│ (Collector) │ │ (Collector) │ │ (Dashboard) │
└──────┬──────┘ └──────┬──────┘ └──────┬──────┘
 │ │ │
 └───────────────────┼───────────────────┘
 │ HTTP
 ▼
 ┌─────────────┐
 │ DuckDB │
 │ Server │
 │ (Data Store)│
 └─────────────┘
 │
 ▼
 ┌─────────────┐
 │ .db File │
 │ (Single Wtr)│
 └─────────────┘
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Key insight: The Quack server itself accesses the &lt;code&gt;.db&lt;/code&gt; file as a single process. But it can accept requests from multiple clients and serialize them internally. This achieves &amp;ldquo;external concurrency, internal serialization&amp;rdquo; — maintaining data consistency while providing multi-client access.&lt;/p&gt;
&lt;h2 id="quick-start-guide"&gt;Quick Start Guide
&lt;/h2&gt;&lt;h3 id="starting-the-server"&gt;Starting the Server
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;-- On your server machine, launch DuckDB and run:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;INSTALL&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;quack&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;core_nightly&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;LOAD&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;quack&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;-- Start the Quack server listening on localhost:8338
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;-- The token is used for client authentication
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;CALL&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;quack_serve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;quack:localhost&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;super_secret&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;-- Create some test data
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;TABLE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;events&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;AS&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;read_csv_auto&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;events.csv&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="connecting-from-a-client"&gt;Connecting from a Client
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;-- On the client machine
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;INSTALL&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;quack&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;core_nightly&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;LOAD&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;quack&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;-- Create authentication secret
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;SECRET&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;TYPE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;quack&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;TOKEN&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;super_secret&amp;#39;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;-- Attach the remote database
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;ATTACH&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;quack:localhost&amp;#39;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;AS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;remote_db&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;-- Query remote tables
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;count&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;event_type&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;remote_db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;events&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;GROUP&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;BY&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;event_type&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;-- Write data to the remote server
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;INSERT&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;INTO&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;remote_db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;events&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;read_csv_auto&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;new_events.csv&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="the-one-round-trip-secret"&gt;The One Round-Trip Secret
&lt;/h3&gt;&lt;p&gt;Quack packs query metadata (schema, statistics) into the same response as the query results. Traditional protocols like Arrow Flight SQL require a metadata request first, then a data request — at least 2 round trips. Quack serializes the query plan into the HTTP request body, executes it server-side, and returns the complete result in one shot.&lt;/p&gt;
&lt;p&gt;This means Quack&amp;rsquo;s advantage grows in high-latency network environments (cross-region deployments, satellite offices, etc.).&lt;/p&gt;
&lt;h2 id="performance-benchmarks"&gt;Performance Benchmarks
&lt;/h2&gt;&lt;p&gt;The DuckDB team conducted rigorous benchmarks on AWS Arm architecture. Here are the key results:&lt;/p&gt;
&lt;h3 id="batch-transfer-performance"&gt;Batch Transfer Performance
&lt;/h3&gt;&lt;p&gt;Test conditions: 60,000,000 rows, ~76GB CSV file&lt;/p&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;Protocol&lt;/th&gt;
 &lt;th style="text-align: center"&gt;Duration&lt;/th&gt;
 &lt;th style="text-align: center"&gt;Relative Performance&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;Quack&lt;/strong&gt;&lt;/td&gt;
 &lt;td style="text-align: center"&gt;&lt;strong&gt;&amp;lt; 5 seconds&lt;/strong&gt;&lt;/td&gt;
 &lt;td style="text-align: center"&gt;&lt;strong&gt;Baseline&lt;/strong&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Arrow Flight SQL&lt;/td&gt;
 &lt;td style="text-align: center"&gt;Slightly slower&lt;/td&gt;
 &lt;td style="text-align: center"&gt;~90-95%&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;PostgreSQL (COPY)&lt;/td&gt;
 &lt;td style="text-align: center"&gt;Orders of magnitude slower&lt;/td&gt;
 &lt;td style="text-align: center"&gt;&amp;lt;1%&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="small-transaction-concurrency"&gt;Small Transaction Concurrency
&lt;/h3&gt;&lt;p&gt;Test conditions: Single row INSERT, 5-second duration&lt;/p&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;Protocol&lt;/th&gt;
 &lt;th style="text-align: center"&gt;Peak TPS&lt;/th&gt;
 &lt;th style="text-align: left"&gt;Notes&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;Quack&lt;/strong&gt;&lt;/td&gt;
 &lt;td style="text-align: center"&gt;&lt;strong&gt;~5,500&lt;/strong&gt;&lt;/td&gt;
 &lt;td style="text-align: left"&gt;8 threads concurrent&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Arrow Flight SQL&lt;/td&gt;
 &lt;td style="text-align: center"&gt;~2,500&lt;/td&gt;
 &lt;td style="text-align: left"&gt;~50% of Quack&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;PostgreSQL&lt;/td&gt;
 &lt;td style="text-align: center"&gt;Higher (10,000+)&lt;/td&gt;
 &lt;td style="text-align: left"&gt;But fundamentally different architecture&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="understanding-the-numbers"&gt;Understanding the Numbers
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;5,500 TPS&lt;/strong&gt; means Quack can handle 5,500 independent INSERT transactions per second. For log collection, if you generate 5,000 log entries per second, a single Quack server is sufficient.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&amp;lt; 5 seconds for 60M rows&lt;/strong&gt; means Quack is viable for large-scale data synchronization, not just OLTP-style small transactions.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="quack-vs-traditional-solutions"&gt;Quack vs. Traditional Solutions
&lt;/h2&gt;&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;Dimension&lt;/th&gt;
 &lt;th style="text-align: center"&gt;Quack&lt;/th&gt;
 &lt;th style="text-align: center"&gt;PostgreSQL&lt;/th&gt;
 &lt;th style="text-align: center"&gt;MotherDuck&lt;/th&gt;
 &lt;th style="text-align: center"&gt;Custom Proxy&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;Deployment Complexity&lt;/td&gt;
 &lt;td style="text-align: center"&gt;🔥 Minimal (one command)&lt;/td&gt;
 &lt;td style="text-align: center"&gt;⚠️ Moderate (master-slave config)&lt;/td&gt;
 &lt;td style="text-align: center"&gt;❌ High (data migration to cloud)&lt;/td&gt;
 &lt;td style="text-align: center"&gt;❌ High (development + ops)&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Operational Cost&lt;/td&gt;
 &lt;td style="text-align: center"&gt;✅ Near zero&lt;/td&gt;
 &lt;td style="text-align: center"&gt;⚠️ Needs DBA&lt;/td&gt;
 &lt;td style="text-align: center"&gt;❌ Pay-as-you-go&lt;/td&gt;
 &lt;td style="text-align: center"&gt;❌ Self-maintained&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Query Latency&lt;/td&gt;
 &lt;td style="text-align: center"&gt;🔥 1 round trip&lt;/td&gt;
 &lt;td style="text-align: center"&gt;✅ 2-3 round trips&lt;/td&gt;
 &lt;td style="text-align: center"&gt;⚠️ Network overhead&lt;/td&gt;
 &lt;td style="text-align: center"&gt;⚠️ Depends on proxy logic&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Small Transaction TPS&lt;/td&gt;
 &lt;td style="text-align: center"&gt;~5,500&lt;/td&gt;
 &lt;td style="text-align: center"&gt;10,000+&lt;/td&gt;
 &lt;td style="text-align: center"&gt;Limited by network&lt;/td&gt;
 &lt;td style="text-align: center"&gt;Depends on buffering&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Batch Transfer (60M rows)&lt;/td&gt;
 &lt;td style="text-align: center"&gt;&amp;lt; 5 seconds&lt;/td&gt;
 &lt;td style="text-align: center"&gt;Extremely slow&lt;/td&gt;
 &lt;td style="text-align: center"&gt;Bandwidth-limited&lt;/td&gt;
 &lt;td style="text-align: center"&gt;Bandwidth-limited&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Data Locality&lt;/td&gt;
 &lt;td style="text-align: center"&gt;✅ Local&lt;/td&gt;
 &lt;td style="text-align: center"&gt;✅ Local&lt;/td&gt;
 &lt;td style="text-align: center"&gt;❌ Cloud&lt;/td&gt;
 &lt;td style="text-align: center"&gt;✅ Local&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Cost&lt;/td&gt;
 &lt;td style="text-align: center"&gt;💰 &lt;strong&gt;Completely Free&lt;/strong&gt;&lt;/td&gt;
 &lt;td style="text-align: center"&gt;💰 Free (self-hosted)&lt;/td&gt;
 &lt;td style="text-align: center"&gt;💸 $20+/month&lt;/td&gt;
 &lt;td style="text-align: center"&gt;💰 Development cost&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;DuckDB API Compatibility&lt;/td&gt;
 &lt;td style="text-align: center"&gt;🔥 &lt;strong&gt;100%&lt;/strong&gt;&lt;/td&gt;
 &lt;td style="text-align: center"&gt;⚠️ Requires pg adaptation&lt;/td&gt;
 &lt;td style="text-align: center"&gt;✅ Compatible&lt;/td&gt;
 &lt;td style="text-align: center"&gt;✅ Compatible&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="real-world-deployment-scenarios"&gt;Real-World Deployment Scenarios
&lt;/h2&gt;&lt;h3 id="scenario-1-multi-collector-log-aggregation"&gt;Scenario 1: Multi-Collector Log Aggregation
&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;Requirement:&lt;/strong&gt; 10 servers running collection programs need to write access logs to the same database, while data analysts need real-time query capability.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Architecture:&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Server (one 4C8G machine)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;duckdb -c &lt;span class="s2"&gt;&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt;INSTALL quack FROM core_nightly;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt;LOAD quack;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt;CALL quack_serve(&amp;#39;quack:0.0.0.0&amp;#39;, token = &amp;#39;my-token&amp;#39;);
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# On each collector machine&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;while&lt;/span&gt; true&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; duckdb -c &lt;span class="s2"&gt;&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; INSTALL quack FROM core_nightly;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; LOAD quack;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; CREATE SECRET (TYPE quack, TOKEN &amp;#39;my-token&amp;#39;);
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; ATTACH &amp;#39;quack:server-ip:8338&amp;#39; AS remote;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; INSERT INTO remote.access_logs
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; SELECT * FROM read_csv_auto(&amp;#39;/var/log/access/&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;date +%H&lt;span class="k"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;.csv&amp;#39;);
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; &amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; sleep &lt;span class="m"&gt;60&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;done&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="scenario-2-lightweight-olap-service"&gt;Scenario 2: Lightweight OLAP Service
&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;Requirement:&lt;/strong&gt; Provide a SQL query interface for 20 internal users. Everyone can query all data without interfering with each other.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;-- Server pre-loads data
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;ATTACH&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;./warehouse.db&amp;#39;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;AS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;warehouse&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;-- Client simply attaches
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;duckdb&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="k"&gt;c&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt;INSTALL quack FROM core_nightly;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt;LOAD quack;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt;CREATE SECRET (TYPE quack, TOKEN &amp;#39;analytics-token&amp;#39;);
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt;ATTACH &amp;#39;quack:analytics.internal:8338&amp;#39; AS warehouse;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt;-- Query as if it were a local table
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt;SELECT department, sum(revenue)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt;FROM warehouse.sales
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt;WHERE sale_date &amp;gt;= &amp;#39;2026-01-01&amp;#39;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt;GROUP BY department
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt;ORDER BY sum(revenue) DESC;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="scenario-3-lightweight-elk-alternative"&gt;Scenario 3: Lightweight ELK Alternative
&lt;/h3&gt;&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;Solution&lt;/th&gt;
 &lt;th&gt;Components&lt;/th&gt;
 &lt;th style="text-align: center"&gt;Resource Usage&lt;/th&gt;
 &lt;th style="text-align: center"&gt;Ops Complexity&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;ELK Stack&lt;/td&gt;
 &lt;td&gt;Elasticsearch + Logstash + Kibana + Filebeat&lt;/td&gt;
 &lt;td style="text-align: center"&gt;16GB+ RAM&lt;/td&gt;
 &lt;td style="text-align: center"&gt;High&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;DuckDB + Quack&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;DuckDB + Collection Script&lt;/strong&gt;&lt;/td&gt;
 &lt;td style="text-align: center"&gt;&lt;strong&gt;&amp;lt; 2GB RAM&lt;/strong&gt;&lt;/td&gt;
 &lt;td style="text-align: center"&gt;&lt;strong&gt;Very Low&lt;/strong&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;For small and medium businesses, ELK is too heavy. With Quack + DuckDB, a single 4C8G server can easily handle hundreds of millions of log entries per day for both writes and queries.&lt;/p&gt;
&lt;h2 id="limitations"&gt;Limitations
&lt;/h2&gt;&lt;p&gt;Every technology has trade-offs, and Quack is no exception:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Single Writer Bottleneck&lt;/strong&gt; — The Quack server internally still writes to the &lt;code&gt;.db&lt;/code&gt; file as a single thread. Write performance is bounded by DuckDB&amp;rsquo;s write throughput. If you need 50,000+ TPS, look elsewhere.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Simple Security Model&lt;/strong&gt; — Currently token-based authentication only. No user permission management. SSL/TLS must be handled by a reverse proxy (nginx/caddy) in front of Quack.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Network Sensitivity&lt;/strong&gt; — While 1 round trip is excellent, if client-server latency exceeds 100ms, query experience will still suffer.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Nightly Status&lt;/strong&gt; — Quack is currently installed from the &lt;code&gt;core_nightly&lt;/code&gt; repository and hasn&amp;rsquo;t reached the stable release channel yet. Thorough testing before production deployment is strongly recommended.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="monetization-ideas"&gt;Monetization Ideas
&lt;/h2&gt;&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Lightweight Log Analytics SaaS&lt;/strong&gt; — Use Quack as the backend to offer SMEs an ELK alternative. $29/month per tenant. A single server can serve 50-100 customers.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Data Architecture Consulting&lt;/strong&gt; — Help clients migrate from PostgreSQL/MySQL to DuckDB + Quack architecture. Quote ¥5,000-¥20,000 per project in the Chinese market ($1,000-$3,000 globally).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Multi-Tenant Reporting Platform&lt;/strong&gt; — Each tenant gets their own DuckDB instance, with Quack providing query services. Charge ¥299-¥999/month or $29-$99/month.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Training and Tutorials&lt;/strong&gt; — Create paid content around Quack deployment, tuning, and disaster recovery. Sell for $29-$99 per course.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="conclusion"&gt;Conclusion
&lt;/h2&gt;&lt;p&gt;Quack is not just a new protocol — it&amp;rsquo;s a pivotal step in DuckDB&amp;rsquo;s evolution from a &amp;ldquo;single-node analytical tool&amp;rdquo; to a &amp;ldquo;production-grade data processing engine.&amp;rdquo; It solves DuckDB&amp;rsquo;s longest-standing pain point — multi-process concurrent access — while maintaining DuckDB&amp;rsquo;s signature &amp;ldquo;zero-config, high-performance&amp;rdquo; DNA.&lt;/p&gt;
&lt;p&gt;For teams using or considering DuckDB, Quack deserves your attention and testing right now. By the time it reaches stable release, you&amp;rsquo;ll already have your architecture ready.&lt;/p&gt;
&lt;h3 id="references"&gt;References
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;DuckDB Quack Extension Docs: &lt;a class="link" href="https://duckdb.org/docs/current/extensions/quack" target="_blank" rel="noopener"
 &gt;https://duckdb.org/docs/current/extensions/quack&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;DuckDB Official Blog: &lt;a class="link" href="https://duckdb.org/news/" target="_blank" rel="noopener"
 &gt;https://duckdb.org/news/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;GitHub Discussion: &lt;a class="link" href="https://github.com/duckdb/duckdb/discussions" target="_blank" rel="noopener"
 &gt;https://github.com/duckdb/duckdb/discussions&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item></channel></rss>