Perf/live ingest throughput - #10
Merged
Merged
Conversation
Bash + Python session driver with host-side timing, cold-then-warm in one DuckDB process, warm schema-stability gate, and a main-level 100k baseline.
…f a fixed low cap. AUTO_POOL_THREAD_CAP=4 and AUTO_PIPELINE_THREAD_CAP=8 clamped the append-pool and parse-pipeline auto-scaling below the box's own hardware_concurrency()/2 and *2/3 formulas, leaving cores idle on many-core machines. Reusing the existing MAX_POOL_THREADS/ MAX_PIPELINE_THREADS=16 ceiling lets defaults scale with the machine; verified with the full sqllogictest suite (663 assertions) and back-to-back A/B ingest runs showing ~20-30% higher cold-ingest throughput on a 20-core box with no regressions.
Re-measured ingest and query benchmarks on DuckDB v1.5.5 with the scaled thread defaults: 1.35M/1.26M/970k records/s for traces/logs/ metrics (3M records in 2.6s), and 27-63x query speedup with 6x smaller storage vs the JSON baseline.
httplib defaults TCP_NODELAY off, so Nagle's algorithm interacting with delayed ACKs added tens of milliseconds of pure socket latency to every request/response round trip -- devastating for live OTEL ingestion, where each collector export is its own small POST. Isolated with a controlled A/B: even the trivial /health endpoint (zero DB work) was capped at ~428 req/s with the default off; enabling nodelay took it to ~10,000 req/s (24x) under the same 20-connection concurrent load. On the real OTLP/HTTP ingestion path (traces envelopes, 1M records) this took live throughput from ~33k records/s to ~300k records/s synchronous, and ~625k records/s with async ingestion enabled -- a pure transport fix, no ingestion or transaction logic touched. Also widened the kernel accept-queue backlog from httplib's default of 5 to 512, sized for interactive use rather than a fleet of collectors reconnecting concurrently (e.g. after a network blip). Verified with the full sqllogictest suite (663 assertions, including raw_api.test's server-lifecycle coverage) -- no regressions.
…r worker. Researched ClickHouse's async_insert design for this. Its AsynchronousInsertQueue uses a shared thread pool (async_insert_threads) so multiple buffers flush concurrently; RawDuck's flusher was a single dedicated thread, serializing every table's flush through it regardless of table count. ClickHouse's MergeTree lets many concurrent writers coexist (each write is a new immutable part, merged later); DuckDB's optimistic appends serialize badly across concurrent transactions on the SAME table (AGENTS.md: "this was v0.1's mistake"). So this only parallelizes across the table dimension -- different tables' due buffers flush concurrently on separate connections (zero contention, independent DataTable objects), while each table's own flush stays single-connection/single-transaction/sequential, exactly as before. A single due table takes the same inline path as today, no thread spin-up. New rawduck_async_flush_threads setting (0 = auto from hardware concurrency, capped at 16) controls the pool size; applies to the periodic flush loop, raw_flush(), and the shutdown drain. Verified: full sqllogictest suite (663 assertions) passes unchanged. Correctness check -- 90,000 rows enqueued interleaved across 3 tables, flushed concurrently, landed exactly once each with zero loss/duplication. Concurrency check -- 3-table concurrent flush (0.246s) vs. 3x the measured single-table serial cost (3 x 0.150s = 0.450s): ~1.8x from true fan-out, while the single-table path is untouched (same inline route, no regression).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.