Your coding agent spends its day waiting on builds
Coding agents rebuild after nearly every change. Seven setup changes that make each build shorter, cheaper to read and less likely to start from zero.
Watch a coding agent work on an app for an hour and count the builds. It changes a file, builds, reads the errors, changes another file, builds again, launches the app, takes a screenshot, and builds again. A developer might build a few times while fixing a bug. An agent builds after nearly every step, because a build is how it finds out whether the step worked.
On a small app that’s fine. On a large app, where an incremental build takes minutes, the agent spends much of its session waiting on the compiler. And unlike a developer, it can’t think about the next step while it waits: the next step depends on what the build says.
Most of the advice below makes each build shorter, or makes sure the agent doesn’t throw away the work the last build already did. None of it needs new tools.
1. Give the agent one command
Agents guess. Left alone, an agent will try xcodebuild with a different scheme, destination or flag each time,
and some of those guesses rebuild from scratch. Write down one command that builds, installs and launches the app,
and put it in the file your agent reads at the start of every session (AGENTS.md, CLAUDE.md or your tool’s
equivalent).
# Build for one fixed Simulator, into a fixed folder
xcodebuild build \
-scheme MyApp \
-destination "platform=iOS Simulator,id=$SIMULATOR_ID" \
-derivedDataPath .build/derived \
-quiet
# Install and launch
xcrun simctl install "$SIMULATOR_ID" .build/derived/Build/Products/Debug-iphonesimulator/MyApp.app
xcrun simctl launch "$SIMULATOR_ID" com.example.MyApp
A script with these lines (call it scripts/run) is even better: the agent can’t get the flags wrong, and you can
change them in one place.
2. Keep the build output short
A full build log can run to thousands of lines, and an agent that reads it all spends tokens and context on lines
that say nothing. The -quiet flag above prints only warnings and errors. A formatter such as xcbeautify does the
same and makes errors easier to read. Either way, the agent sees the one line that matters.
3. Tell it never to clean
When a build fails in a way the agent doesn’t understand, its first instinct is often to clean and try again. A clean build deletes everything the build system knows about the project, and the next build starts from zero. Add a rule: don’t clean, don’t delete the build folder, ask first.
4. Pin one Simulator
An agent that picks a Simulator by name, or by “whatever is booted”, can end up on a different device from one run to the next, booting a second Simulator and installing the app from scratch on it. That costs time and memory, and the app’s state (a signed-in account, test data) is gone. Pick one Simulator, put its ID in the command, and have the script boot it only when needed:
xcrun simctl bootstatus "$SIMULATOR_ID" -b # boots it if it isn't already, then waits until it's ready
5. Mind your worktrees
Running several agents at once, each in its own git worktree, is a good way to get more done. But build state lives
per checkout: a new worktree has none, so its first build is a full build. Reuse worktrees between tasks instead of
creating a fresh one for each, and keep each one’s build folder inside it (the -derivedDataPath above) so they
never fight over the same files.
Also count your cores. Two agents building a large app at the same moment each get half the Mac, so both builds take longer. Sometimes two agents in a row finish sooner than two at once.
6. Let it check its work without a full rebuild
Not every check needs a build. The agent can take a screenshot of the running app and read its logs straight from the Simulator:
xcrun simctl io "$SIMULATOR_ID" screenshot /tmp/screen.png
xcrun simctl spawn "$SIMULATOR_ID" log stream --predicate 'subsystem == "com.example.MyApp"'
Telling the agent about these saves the builds it would otherwise start just to “see what happens”. For more on how an agent can see and use the app, see how a coding agent should drive the Simulator.
7. Measure the loop
Wrap the build in your script with a timer and log every run’s duration. After a day of agent work you’ll know how many builds it ran and how long it waited, which is the number that tells you whether build time is worth fixing for your project.
For a first answer before that day is over, the free
build_baseline.py script
times the builds an agent makes again and again: one with no changes, one after a one-line edit inside a function,
and one after a change to a type that many files use. It makes the edits itself, puts the files back, and with
--json prints results your agent can read. It runs eleven builds, longer than many agents let a command run, so
ask yours to run it in the background:
Run
python3 path/to/faster-builds/scripts/build_baseline.py --json > baseline.jsonfrom the project folder in the background, wait for it to finish, then tell me the three medians and what the timing summaries show.
If most builds take seconds, build time isn’t worth fixing. If they take minutes, read on.
What’s left
These steps stop the agent from wasting builds. They don’t make a necessary build of a large app any shorter, and that’s the part we’re working on with Quickfire: faster everyday builds of large apps, from the command line, on the project you already have. Early access opens in early 2027.