# Optimizing Swift Build Times: A Field Guide for Debug and Release Settings

> A practical collection of Xcode and Swift compiler flags and strategies to reduce compile times, aimed at iOS and macOS developers working on medium-to-large projects.

**fastred/Optimizing-Swift-Build-Times** — GitHub describes it as Collection of advice on optimizing compile times of Swift projects.. The repository metadata lists Swift as its primary language. The metadata lists the MIT license. This article stays within the project description and details documented in the GitHub repository README.

- Repository: https://github.com/fastred/Optimizing-Swift-Build-Times
- Stars: 3,584 · Forks: 140
- Language: Swift
- License: MIT
- Published: 2026-08-13 · Updated: 2026-08-18 · Language: en
- Canonical page: https://hysenlabs.com/projects/fastred-optimizing-swift-build-times

## Why Build Times Matter and Who This Guide Serves

Long compile times are a known pain for Swift developers, especially as projects grow beyond a few files. This repository, maintained by Arek Holko, collects advice that is scattered across blog posts, WWDC sessions, and personal experiments. It targets developers who use Xcode and Swift and who are willing to tweak build settings rather than switch tools. The material is not a tutorial from Apple; it is a community-curated list with sources. If you are on a small project, the suggestions may be overkill. For medium-to-large apps, the difference between a 30-second and a 3-minute build is real, and this guide gives you concrete levers to pull.

## Incremental Compilation Mode: The Xcode 10 Shift

The first piece of advice is about compilation mode. Before Xcode 10, developers often enabled Whole Module Optimization in Debug builds to speed things up. That was a workaround. The README states that with Xcode 10, the recommended setup is Incremental Compilation Mode for Debug and Whole Module for Release, with No Optimization for the Debug Optimization Level. This is a direct correction to older habits. The reasoning is that Incremental mode compiles only changed files, which is what you want during development. Whole Module Optimization is better for Release because it lets the compiler see the entire module and optimize across file boundaries. If you are still on Xcode 9 or earlier, this advice does not apply. The repository does not discuss the trade-offs of Whole Module in terms of build time versus runtime performance, so you should treat that as a Release-only setting.

## Finding Slow Code with Compiler Warnings

The core problem with Swift build times is type checking. The compiler has to infer types for expressions and functions, and some constructs are pathologically slow. Xcode does not show you which code is slow by default. The repository tells you to add two flags to Other Swift Flags: -Xfrontend -warn-long-function-bodies=100 and -Xfrontend -warn-long-expression-type-checking=100. The 100 means 100 milliseconds. You should experiment with that threshold. After building, Xcode emits warnings for functions or expressions that take longer than the threshold. This is a cheap way to find the worst offenders. The README links to posts by John Sundell and Robert Gummesson that describe how to fix such code, but the repository itself does not give examples of slow code. That is a gap. You get the detector, not the cure. Still, the flags are the most actionable item in the whole guide.

## Profiling Whole Files from the Command Line

Function-level warnings are fine, but sometimes you need to see which files take the longest. Xcode has no UI for that. The repository provides a full xcodebuild command that builds your project with extra flags to record compilation times. The command uses -driver-time-compilation, -debug-time-function-bodies, and -debug-time-compilation. You pipe the output to a log file and then run an awk pipeline to produce a sorted list of files with their compile times. The example output shows entries like 2.7288 (0.3%) {compile: Account.o <= Account.swift }. This is a real workflow, but it is not turnkey. You must replace the project name, scheme, and destination. The awk script is fragile; it depends on the exact output format of your Xcode version. If you are not comfortable with shell pipelines, this step may frustrate you. But it gives you a concrete ranking of files, which is more useful than guessing.

## Build Active Architecture Only and dSYM Generation

Two settings are quick wins. Build Active Architecture Only is a default, but the README says you should double-check it. It ensures Debug builds only compile for the architecture of the connected device or simulator, not all architectures. This reduces compile time and link time. The second is dSYM generation. New projects do not generate dSYM files for Debug builds by default. That is fine for simulator builds, but if you run on a device and want to analyze crashes without a debugger, you need dSYMs. The repository links to a post about conditional dSYM generation. The trade-off is that generating dSYMs takes time. The advice is to enable them only when you need them, for example in a special configuration. This is a classic settings optimization: you trade a bit of convenience for faster builds. Neither of these is a silver bullet, but they are easy to apply.

## Third-Party Dependencies: CocoaPods vs. Carthage

Dependency management has a big impact on build times. The README distinguishes two ways to embed dependencies: as source that gets compiled on every clean build, or as prebuilt frameworks. CocoaPods is the most popular but compiles source each time. Carthage builds frameworks once and you only rebuild when you change the dependency list. That can take 5 to 15 minutes initially, but you do it rarely. The README even mentions Rome, a tool that caches Carthage builds. This is a clear recommendation: if you care about build times, Carthage is better. However, Carthage is harder to use. The repository does not discuss Swift Package Manager, which is a notable omission. For new projects, SPM is increasingly common, but this guide predates its wide adoption. So the advice is dated but still relevant for existing projects that already use CocoaPods or Carthage.

## Modularization and Its Limits

The last major topic is modularization. The README starts by saying incremental compilation in Swift is not perfect. Changing one string can cause large recompilations. The idea is to split your project into modules so that changes in one module do not force recompilation of the whole app. This is a structural change, not a setting. It requires you to design your code into frameworks or libraries. The README is truncated here, so the full advice is missing. That is a limitation of this repository: it points to the concept but does not give a step-by-step modularization guide. You would need to look at the linked sources. Modularization is the most effective long-term solution, but it is also the most expensive to implement. You should only attempt it after you have tried the compiler flags and dependency changes.

## Maintenance, License, and What This Repository Is Not

This is a Markdown file in a GitHub repository, not a tool or a library. There is no code to install, no package to update. The maintenance cost is low: you just read it. The license is MIT, so you can reuse the text freely, but the advice is tied to specific Xcode versions. The repository has not had a release, and the last push is unknown. That means some content, like the Xcode 10 advice, may be stale. For example, Xcode 15 and 16 have different build systems and default settings. The README does not mention the new build system in the sections you see, though the table of contents lists it. The lack of updates is a real concern. You should cross-check the flags against your current Xcode documentation. The repository is a starting point, not a definitive reference. The MIT license gives you freedom, but the content is opinionated and community-sourced.

## Conclusion

Adopt this guide if you work on a medium-to-large Swift project in Xcode and you are tired of waiting for Debug builds. Skip it if you are on a small project or already use Carthage and incremental builds. Before applying anything, verify your Xcode version (the Incremental Compilation Mode advice targets Xcode 10 and later) and measure your current build times with the provided xcodebuild command. Then start with the -warn-long-function-bodies flag to find the worst code, and only move to modularization once you have exhausted the simpler settings. This repository is a curated set of links and commands, not a tool, so your real work is to test each change against your own project.

## FAQ

### What does Optimizing-Swift-Build-Times actually contain?

A written collection of advice in about eleven sections: build settings for debug builds, surfacing slow type checking, measuring per-file times from the command line, building only the active architecture, debug symbol generation, dependency strategy, modularisation, interface files, schemes, the build system and showing build times in the editor. The repository holds a readme, a licence and an assets directory, and no Swift source.

### How do I find which Swift files compile slowly?

The editor has no interface for per-file times, so the guide builds from the command line with timing flags passed through the Swift flags setting, writes the output to a log, and then filters that log with awk, grep, cut, sed and sort into a sorted list of the slowest files. The filter includes a fixed column offset, so its output depends on the log layout.

### Should I use whole module optimization for Swift debug builds?

The guide says no. It describes that setting as a workaround that stopped being needed in a later version of the tool, and recommends incremental compilation for Debug with optimisation turned off, keeping whole module for Release only.

### What does the guide say about CocoaPods and Carthage build times?

It splits dependencies into source compiled on every clean build and prebuilt frameworks. It names the popular package manager as slow by design because third-party source is recompiled each clean build, and calls the binary alternative harder to use but better for build times, since it rebuilds only when the dependency list changes, at a cost of five to fifteen minutes. It also points at a separate project as a way to skip that rebuild.

### Is Optimizing-Swift-Build-Times still current?

It was last pushed on 2019-02-01 and is not archived. Its examples are version specific: the timing command names an iPhone 8 simulator, one table of contents entry is about the new build system from an earlier generation, and the sources include an article about measuring times in Xcode 9 next to advice for the version after it.

## Sources

- [Official README](https://github.com/fastred/Optimizing-Swift-Build-Times#readme)
- [Project repository](https://github.com/fastred/Optimizing-Swift-Build-Times)
- [README](https://github.com/fastred/Optimizing-Swift-Build-Times/blob/master/README.md)
- [Releases](https://github.com/fastred/Optimizing-Swift-Build-Times/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/fastred-optimizing-swift-build-times
