Parallel agents are cheap until they all discover the same expensive tool. Xcode, Gradle, emulators and simulators do not behave like text searches. They reserve memory, warm caches, hold file locks, talk to background services and produce failures that often look like project defects. When three app projects decide to build at once, the machine is not three times faster. It is one unlucky scheduler tick away from a false diagnosis.
The practical fix is not philosophical. Put a lease in front of mobile builds. Default it to one. Make the number configurable. Require every supervised project to acquire that lease before starting an iOS archive, Android bundle, simulator boot, emulator-heavy integration test or store artifact cut. If the lease is unavailable, the project should do useful non-build work or wait with a durable reason. It should not spin, retry or invent smaller build-like tasks that hit the same bottleneck.
This is especially important for supervised tmux fleets because their failure mode is noisy. One project runs out of simulator destinations and asks for a host reboot. Another sees Gradle timeout and starts deleting caches. A third holds an emulator while doing nothing visible. From the user's seat those are three separate issues. From the machine's seat they are one missing capacity contract.
A build lease is also a quality mechanism. It forces the agent to answer whether a build is necessary right now. UI copy changes, static policy pages, changelog entries, source audits and small unit tests should not be blocked behind an archive. Conversely, release claims should not be made without the lease-backed artifact that proves them. The lease creates a clean boundary between thinking, editing, testing and cutting a binary.
The controller needs to log both sides of the lease: who holds it and who is waiting. A silent wait is just another idle pane. A useful wait says, for example, Boardlore is waiting for the iOS build lane held by Sudoku since 14:22, while continuing settings-copy cleanup. That is enough for a watcher to decide whether the queue is healthy or whether somebody is sleeping on a scarce resource.
The default of one is conservative on purpose. It can be raised on a stronger host, or lowered to zero during a reserve window, but the system should make that an explicit setting instead of a habit in prompts. The value can change; the existence of the gate should not.
The outcome we want is boring: one build uses the machine, the others keep doing high-value non-build work, and nobody asks the user to repair a host state that the scheduler created. Concurrency is not a badge. Delivered artifacts are.
Notes
This post is part of the recovered daily-publisher backlog after the site publication service drifted and stopped producing dated blog results. It is intentionally written as an engineering note, not as a legal, financial, or store-policy guarantee.
Keep reading: all posts on the WizusLabs Engineering blog.