HEAVY_OPS_SEMAPHORE in Worktrunk: Throttling Heavy Git Operations for Better Performance
Worktrunk's HEAVY_OPS_SEMAPHORE is a global async semaphore that limits concurrent heavy Git operations to four permits, preventing memory-mapped I/O thrashing when accessing large pack files.
The max-sixty/worktrunk repository implements HEAVY_OPS_SEMAPHORE to solve performance bottlenecks caused by parallel Git commands. When multiple worktrees or background tasks run intensive operations like git rev-list --count or git diff --shortstat simultaneously, they compete for memory-mapped file access, causing significant CPU pressure and throughput degradation.
Why Git Operations Need Concurrency Control
Heavy Git operations read large commit-graph and pack files via memory-mapped I/O (mmap). When many of these operations execute in parallel across multiple worktrees, they trigger excessive mmap thrashing as the system repeatedly maps and unmaps the same large Git indices.
This thrashing creates two specific problems:
- CPU contention – The kernel spends cycles managing page tables instead of executing Git logic
- Unpredictable latency – Background status checks and diff calculations slow down unpredictably as worktree count increases
According to the source code analysis, profiling on typical developer machines (4–8 cores) revealed that unthrottled parallel access to pack files degraded performance by approximately 25% when working with four concurrent worktrees.
How HEAVY_OPS_SEMAPHORE Works
The semaphore uses a permit-based concurrency model with four available slots. This limit was chosen after measuring real-world performance on multi-worktree repositories, balancing parallelism against mmap overhead.
The implementation follows the RAII (Resource Acquisition Is Initialization) pattern:
- A task acquires a permit before invoking a heavy Git command
- The permit holder (
_guard) automatically releases the slot when it goes out of scope - Other tasks block until a permit becomes available
This ensures that only a handful of heavy Git processes run simultaneously, keeping memory pressure stable and throughput predictable.
Implementation in the Codebase
Declaration in src/git/mod.rs
The semaphore is declared as a global static in src/git/mod.rs (lines 23–34). This location centralizes the concurrency limiter alongside other process-wide Git configurations, making it accessible throughout the repository layer.
Usage in Commit Counting and Diff Operations
The primary consumers reside in src/git/repository/diff.rs, specifically within Repository::count_commits and related diff functions. Before executing commands that read large pack files, the code acquires a guard:
// Acquire a permit before a heavy rev-list operation
let _guard = super::super::HEAVY_OPS_SEMAPHORE.acquire();
let stdout = self.run_command(&["rev-list", "--count", "--end-of-options", &range])?;
Similarly, diff operations follow the same pattern:
// Acquire a permit before a heavy diff operation
let _guard = super::super::HEAVY_OPS_SEMAPHORE.acquire();
let stdout = self.run_command(&["diff", "--shortstat", "--end-of-options", &range])?;
The _guard variable ensures the permit releases automatically via Rust's drop mechanics, preventing resource leaks even if the Git command fails or panics.
Performance Impact
Limiting concurrency to four permits yielded measurable improvements in the Worktrunk codebase:
- ~25% speed-up on repositories with four worktrees compared to unthrottled execution
- Controlled parallelism that scales appropriately with typical 4–8 core developer machines
- Reduced mmap contention by serializing access to large pack files without blocking lightweight Git operations
This approach distinguishes between heavy I/O operations (which use the semaphore) and lightweight commands that can run unthrottled, maximizing overall throughput.
Summary
- HEAVY_OPS_SEMAPHORE limits heavy Git operations to four concurrent executions across the Worktrunk process.
- It prevents mmap thrashing on large pack files by serializing access to memory-mapped Git indices.
- The semaphore is defined in
src/git/mod.rsand utilized insrc/git/repository/diff.rsfor commit counting and diff calculations. - The four-permit limit was determined through profiling on typical 4–8 core development machines.
Frequently Asked Questions
What specific Git operations does HEAVY_OPS_SEMAPHORE control?
The semaphore throttles commands that perform heavy I/O on pack files, specifically git rev-list --count and git diff --shortstat. These operations access large commit-graph structures via memory-mapped I/O, making them prone to contention when run in parallel across multiple worktrees.
Why was the concurrency limit set to four permits?
The limit of four permits was chosen after profiling typical developer machines with 4–8 CPU cores. Testing showed that four concurrent heavy Git operations provided optimal throughput on multi-worktree repositories while preventing the mmap thrashing that occurs with higher parallelism.
How does acquiring a semaphore permit improve performance?
By acquiring a permit before executing heavy Git commands, Worktrunk ensures that only a bounded number of processes simultaneously memory-map large pack files. This reduces kernel page table churn and prevents the CPU overhead associated with repeatedly mapping and unmapping the same Git indices, resulting in more predictable execution times.
Where is HEAVY_OPS_SEMAPHORE defined in the Worktrunk source code?
The semaphore is declared as a global static in src/git/mod.rs (lines 23–34) and is referenced in src/git/repository/diff.rs (lines 54–56) and related files. It appears alongside other process-wide singletons in the repository module structure.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →