From 5a3519a5ab727b9ea1d07bcbd2a74393b425a9af Mon Sep 17 00:00:00 2001 From: Venkatesh Tumkur Date: Fri, 10 Oct 2025 15:34:08 +0100 Subject: [PATCH] fix: use single-threaded tokio runtime in sccache client MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The sccache client was using Runtime::new() which creates a multi-threaded tokio runtime with worker threads equal to the number of CPU cores. On high-core-count servers running many parallel builds, this created an excessive number of threads. For example: - 96 vCPU server - 10 concurrent make invocations - Each make using -j16 - Result: 96 × 10 × 16 = 15,360 threads created by sccache wrappers While these threads are short-lived, with continuous build pipelines this constant thread creation/destruction causes unnecessary overhead. The sccache client only performs simple I/O operations (connecting to server, sending requests, receiving responses) and doesn't need worker threads. This change replaces all client-side Runtime::new() calls with Builder::new_current_thread().enable_all().build() to use a single-threaded runtime, reducing thread count from num_cpus to 1 per client invocation. --- src/commands.rs | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/src/commands.rs b/src/commands.rs index 9d7a4ed57..535eec45e 100644 --- a/src/commands.rs +++ b/src/commands.rs @@ -92,7 +92,9 @@ fn run_server_process(startup_timeout: Option) -> Result) -> Result Result { // If there is no server, spawning a new server would start with zero stats // anyways, so we can just return (mostly) empty stats directly. Err(_) => { - let runtime = Runtime::new()?; + let runtime = tokio::runtime::Builder::new_current_thread() + .enable_all() + .build()?; let storage = storage_from_config(config, runtime.handle()).ok(); runtime.block_on(ServerInfo::new(ServerStats::default(), storage.as_deref()))? } @@ -763,7 +769,9 @@ pub fn run_command(cmd: Command) -> Result { use crate::compiler; trace!("Command::PackageToolchain({})", executable.display()); - let runtime = Runtime::new()?; + let runtime = tokio::runtime::Builder::new_current_thread() + .enable_all() + .build()?; let jobserver = Client::new(); let creator = ProcessCommandCreator::new(&jobserver); let args: Vec<_> = env::args_os().collect(); @@ -807,7 +815,9 @@ pub fn run_command(cmd: Command) -> Result { let jobserver = Client::new(); let conn = connect_or_start_server(&get_addr(), startup_timeout)?; - let mut runtime = Runtime::new()?; + let mut runtime = tokio::runtime::Builder::new_current_thread() + .enable_all() + .build()?; let res = do_compile( ProcessCommandCreator::new(&jobserver), &mut runtime,