Sitemap

Xcode 16.3 Build Time Optimization

3 min readMay 14, 2025

--

Xcode 16.3 Build Times: The Sneaky Run Script That Slowed Me Down

Two years ago, I shared my journey of optimizing Xcode 14 build times in this article. Unfortunatelly in each new version of Xcode we face similar performance issues. With Xcode 16.3, I revisited this challenge — and found new pitfalls and tricks worth sharing.

🧠 Background

Build times aren’t just annoying — they slow down iteration speed, drain developer focus, and cost teams real money. With Apple’s continued changes in Xcode’s build system, it’s important to stay up to date. While many fundamentals still apply (e.g., reducing module interdependencies, minimizing Swift compile time), Xcode 16.3 introduces subtle behaviors that can silently wreck incremental builds.

🔍 The Mystery of the Persistent Run Script

While profiling a project recently, I noticed something strange: even with no code changes, some modules were being rebuilt on every build. After some digging (and a bit of frustration), I discovered the culprit in this thread in Apple forums, a `Run Script` phase with no specified output files.

Xcode’s build system, especially with the module verifier introduced in recent versions, becomes defensive when it sees such a script.

If there is a Run Script build phase with no specified output files that runs on every incremental build, the module verifier will defensively recompile that module, just in case the script modified its outputs.

This essentially breaks incremental builds, even if the script doesn’t touch any files at all.

✅ The Fix: Specify Output Files

To prevent unnecessary rebuilds, always define output files in every Run Script phase. This allows Xcode to cache and verify script execution correctly.

How to fix it

1. Open your target’s Build Phases.
2. Find your Run Script phase.
3. Expand the ”Output Files” section.
4. Add any files your script generates (e.g., `${SRCROOT}/MyProject/Generated/Config.swift`).

💡 If your script doesn’t generate anything, consider moving it outside of the build phase or have it touch a dummy cache file. For my case, I realize the scripts we us in our projects at AutoScout24 doesn’t do anything important. So decided to clean them all.

Keep in mind, this fix improves incremental (concurrent) builds. Clean builds will remain unaffected and take longer as usual.

📊 Real-World Results

These changes didn’t just sound good on paper, they made a huge difference in practice. The project we have in AutoScout24 has internal SPM modules.

  • Changing a single string in an SPM module used to trigger a ~66-second build 🐌
  • Now it takes ~12 seconds 🚀
  • Running tests used to require a 115-second build 💀
  • Now it’s down to ~31 seconds 🚀🚀🚀

That means it is an 80% less time spend on a single concurrent build. That’s not a minor tweak ,it’s the difference between staying focused or being tempted to scroll Instagram between test runs.

📚 Need More Context?

If you’re looking for a deeper understanding of what’s happening behind the scenes, my previous article Xcode Build Time Optimization includes two in-depth sections that are still relevant today:

🔧 Understanding How Xcode Builds a Project

A step-by-step explanation of how Xcode compiles Swift and Objective-C files, resolves dependencies, and links outputs. Great if you’re wondering why your project rebuilds more often than it should.

🔍 Investigation of Current Build Time

In this part, I walk through how to profile build steps using the build timeline and how I started my optimization journey.
It was during this investigation that I discovered the unexpected impact of `Run Script` phases with no output files.

✨ If you’re struggling with slow builds and not sure where to start — that’s where I’d begin.

💬 Final Thoughts

The Xcode build system has new challenges with each new version. Minor misconfigurations like an undefined Run Script output can cost you minutes on every build.

So if your project still feels slow despite having an M2 chip and SSDs, take a look at your Run Script phases. You might just be one output file away from saving hours each week.

🙏 Thanks for reading! If you found this helpful, feel free to follow me on Medium or share it with your team.

--

--

Emin DENİZ
Emin DENİZ

Written by Emin DENİZ

Mobile Team Lead at AutoScout24

Responses (1)