Build performance is governed by fundamental constraints: the task graph, incremental change patterns, and the physics of moving data between caches and machines. More processor cores only help when the graph exposes enough independent work; the longest dependency chain sets a hard floor regardless of hardware. Incremental builds shrink the graph but can't turn dependent work into parallel work, and the real cost of a build depends on which files change most often, not a single clean-build number. Worktrees complicate incrementality: tools like Xcode keep state tied to a build directory (incrementality by location), while Bazel and Xcode's compilation cache use content-addressed identity so results can be reused across checkouts. Sticky volumes can approximate incrementality in CI but introduce scheduling and correctness complexity. Remote caching is bounded by latency and bandwidth, not just storage cost, which motivates collocating cache and compute; Tuist is building Kura, a decentralized cache mesh, and Once, a prototype for adding remote caching/execution to existing build setups without replacing the build system.
Table of contents
The parameters of a buildWhere the work comes fromIncrementality across worktreesMaking a build directory stickThe distance to a cacheThe limits of one machineWhat this means for teamsQuestions this post answers
Why doesn't adding more CPU cores make my build faster?
Extra processor cores only help when the build graph has enough independent, ready-to-run tasks to fill them. A build's speed is bounded by two things: total work divided across cores, and the longest chain of tasks that must run in strict order. More cores can shrink the first limit but cannot shorten the dependency chain, so idle cores are common once that chain becomes the bottleneck. daily.dev surfaces build-systems deep dives for engineers debugging why extra hardware isn't paying off.
What is the difference between incrementality by location and incrementality by identity in build systems?
Incrementality by location keeps mutable build state in a directory (like Xcode's DerivedData), so it only helps when a later build returns to that same directory, making worktrees rebuild redundant work. Incrementality by identity names a task's result by its inputs, toolchain, and settings, so any worktree or machine asking for the same inputs can reuse the cached result, which is how Bazel's action cache and Xcode's compilation cache work. Teams choosing a caching strategy for multi-worktree workflows can track this trade-off on daily.dev.
Why isn't a remote cache always faster than rebuilding locally?
A remote cache hit is only a win when retrieving the result is faster than producing it again, and every hit pays two costs: latency for request-response round trips and bandwidth for transferring the artifact. Many small blobs make a cache latency-bound, while large artifacts make it bandwidth-bound; object storage's low price per byte says nothing about how fast it can actually serve a build. Engineers weighing cache infrastructure choices can follow build-performance analysis like this on daily.dev.