Repository navigation
feat(hotblocks): run each query task on its own thread behind a flag - #119
Merged
Merged
Conversation
mo4islona
force-pushed
the
feat/query-thread-per-task
branch
from
October 16, 2026 09:13
6dcd1b9 to
37bf225
Compare
In the shared query pool, the par_iter and join inside a task spread over every worker, and rayon takes injected jobs last, so a new task waits until a heavy query has no parallel work left. A worker that waits in join also runs whole tasks from the injector and finishes its own only after them. One-thread pools fed from a FIFO queue keep a task's parallel work on its thread; polars keeps its global pool, so its part stays shared. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
mo4islona
force-pushed
the
feat/query-thread-per-task
branch
from
October 16, 2026 09:26
63c3dbd to
59fb744
Compare
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.
Part of #118.
Problem
Every query task runs on the shared rayon pool. The
par_iterandjoininside a task spread over every worker, and rayon takes injected jobs (new tasks) last, so one heavy query holds the whole pool. A worker that waits injoinalso runs whole tasks from the injector, and its own task ends only after them.Change
--query-thread-per-task, alsoPATCH /settings {"query": {"threadPerTask": true}}, off by default. Each query task runs on one of--query-threadsone-thread rayon pools that take tasks from one FIFO queue, so itspar_iterandjoinstay on its thread. No change to the engine code.hotblocks_query_thread_per_taskshows it per replica.benches/query_pool.rs: an open-loop model of the pool that compares the shared pool, thread groups and a thread per task.Results (model)
With rare heavy tasks, the light-task latency mean / p99 / p99.9 is 61 / 1322 / 3726 ms on the shared pool and 11 / 187 / 608 ms with a thread per task, the same as with no heavy tasks at all. Heavy tasks need 3.6× more own time; their mean latency grows 1.7×. Details: #118 (comment)
benches/query_pool.rsin this PR gives the same picture (8 threads, 280 light tasks/s, 0.3 heavy tasks/s, 120 s per run): 39 / 912 / 2749 ms on the shared pool, 9.9 / 154 / 665 ms with a thread per task, and 9.8 / 154 / 660 ms with no heavy tasks. Heavy own time grows 4.2× and heavy mean latency 2.3× in this run.Results (production)
One replica in this mode against one on the shared pool, about an hour, with 1.4 times the tasks on the switched one: tasks that waited in the queue over 0.4 s fell from 2,070 to 29, tasks that ran over 3.3 s from 66 to 10, and streams over 80 ms from 3.8% to 1.7%. No client retries or errors. Details: #118 (comment)
Risk
A heavy step loses its parallelism and can get several times slower. Hence the flag and the per-replica switch at runtime.
Tests
parallel_work_inside_a_task_stays_on_its_threadanda_task_runs_while_another_holds_its_worker. Each fails on the defect it guards: the shared pool, and a queue lock held while a task runs.PATCH /settingsswitch the mode.🤖 Generated with Claude Code