diff --git a/src/main.rs b/src/main.rs
index 2459926..0bf7e86 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -58,10 +58,9 @@ fn run_daemon() -> anyhow::Result<()> {
tokio::runtime::Builder::new_multi_thread()
.enable_all()
// Tool handlers acquire std::sync::RwLock on the index, which blocks
- // the OS thread. With the default worker_threads (= num_cpus), 10+
- // concurrent subagent calls can starve the runtime. Scale to 4x CPU
- // cores (min 16, max 64) so blocked threads don't exhaust the pool.
- .worker_threads(std::thread::available_parallelism().map_or(16, |n| (n.get() * 4).clamp(16, 64)))
+ // the OS thread. Reserve 2 threads for the OS/system, use the rest
+ // for tokio workers so blocked threads don't exhaust the pool.
+ .worker_threads(std::thread::available_parallelism().map_or(4, |n| n.get().saturating_sub(2).max(4)))
.build()?
.block_on(async {
observability::init_tracing()?;