Skip to content
compiler.dev

macOS Runners for iOS CI: Costs and Speed-Ups

iOS and macOS builds need Apple hardware, and Apple hardware is the most expensive thing you can rent in CI. Teams are often surprised that a Mac minute costs about ten Linux minutes. This guide covers the prices, the options, and the changes that cut both the bill and the wait.

What macOS minutes cost on GitHub

From GitHub's runner pricing page, per minute:

RunnerLabel examplesPer minute
macOS 3-core or 4-core (M1 or Intel)macos-latest, macos-15$0.062
macOS 12-core (Intel, larger runner)macos-latest-large$0.077
macOS 5-core M2 Pro (larger runner)macos-latest-xlarge$0.102

Compare: Linux 2-core is $0.006 a minute. A 30-minute iOS pipeline on the standard Mac runner is $1.86, against $0.18 for the same minutes on Linux. At 200 runs a month that is $372.

Included free minutes are consumed at a 10x multiplier for macOS, so the 2,000 free minutes of a Free plan are 200 macOS minutes; 3,000 on Team are 300. Larger runners are never covered by the free minutes.

You can model your numbers in the Actions cost calculator and see all labels in the runner specs.

Where the time goes in an iOS pipeline

Open a slow run and measure these phases:

  1. Runner startup and checkout.
  2. Dependency resolution (Swift Package Manager, CocoaPods, Carthage).
  3. Compile.
  4. Simulator boot and test run.
  5. Archive, signing and upload.

Most teams find that compile and test dominate, with dependency resolution a close third. The Xcode build speed-up guide covers each of these with commands.

Run less on the Mac

The biggest cost cut: do not run Linux-capable work on macOS.

  • Lint (SwiftLint runs on Linux), formatting, docs generation, backend tests and JSON schema checks belong on Linux runners.
  • Use a quick Linux job as a gate (for example, lint and a danger check) and start the Mac job only if it passes, with needs:.
  • Split by changed paths. A change to only a README or backend folder should not start an Xcode build.
jobs:
  lint:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: swiftlint --strict
  test:
    needs: lint
    runs-on: macos-15
    timeout-minutes: 40
    steps: [...]

Always set timeout-minutes. A hung simulator can otherwise run for the default 360 minutes: $22 on the standard Mac runner.

Cancel superseded runs

Use concurrency with cancel-in-progress on PR workflows. A Mac run that gets cancelled after 3 minutes costs $0.19; one that finishes pointlessly costs $1.86 or more.

Build and test once

If you run unit and UI tests as separate jobs, each one compiles the app again. Build once with build-for-testing, upload the .xctestrun and products as an artifact, then run test-without-building in several parallel jobs. Parallel jobs shorten wall time, but each job still bills a full minute at the Mac rate. Do this only when the test time is long enough to be worth it.

Choose the runner by cost per run

The 5-core M2 Pro at $0.102 is 65 percent more per minute than the standard runner at $0.062. If a clean build drops from 18 minutes to 9, the larger runner costs $0.92 against $1.12 and returns results in half the time. If it only drops to 14 minutes, it costs $1.43 and is worse on both counts. Measure on your project; do not guess. The numbers above are examples that show the arithmetic.

Other ways to run macOS jobs

  • Third-party Mac runners from CI vendors, often on newer chips and billed per second. Prices vary; check the vendor's pricing pages and compare cost per workflow run.
  • Your own Mac minis or Mac Studios as self-hosted runners. Apple's licence allows two macOS VMs per host. The cost is hardware plus the effort to keep machines patched, reset between jobs and secured. See self-hosted vs GitHub-hosted runners.
  • AWS EC2 Mac dedicated hosts, with a 24-hour minimum allocation per host. They suit steady load, not bursty load.

Signing and secrets

Do not store signing certificates on a persistent runner. Use an ephemeral keychain created at the start of the job, import certificates from secrets, and delete it at the end. Prefer fastlane match or App Store Connect API keys over personal Apple IDs.

FAQ

Why is macOS so much more expensive than Linux?

Mac runners run on Apple hardware that GitHub has to buy and host, and Apple's licence limits virtualization. That makes capacity costly.

Do free minutes cover macOS?

Yes for standard runners, at 10 minutes charged per minute used. Larger macOS runners are billed from the first minute.

What macOS image should I use?

Pin an explicit version such as macos-15 rather than macos-latest, so a new default image does not change your Xcode version unexpectedly.

Can I cut cost by running tests only on PRs to main?

Often, yes. Run a fast subset on every PR and the full suite on merges and nightly.

Test it on your project

compiler.dev's macOS runners are in early access, priced at $0.028 a minute for a 7-core M4 Pro VM. Because per-minute prices are easy to misread, use the comparison mode on one real workflow and compare cost per run against your current setup.

Made by compiler.dev. Free tools · Pricing