In this article

To estimate mobile CI cost, split work by runner type and multiply the actual billable duration by your account's current rates. Android checks that can run on Linux should not automatically occupy the same macOS job as an iOS archive. Measure before restructuring the pipeline.

GitHub's Actions billing documentation explains included usage, billable runner use and storage. Prices and allowances depend on the current account and runner; this article supplies a worksheet, not a universal price list.

Account for jobs, not just workflow runs#

One workflow may start several jobs, matrix combinations and retries. Inventory each separately:

text
Job:
Runner label and size:
Runs per month:
Billable minutes per run:
Retry frequency:
Current rate or allowance treatment:
Artifact retention and size:

Read job timing from representative successful and failed runs. Queue time, wall-clock workflow duration and billable job time are not interchangeable. Use the billing view's definitions when reconciling an invoice.

Do not extrapolate from your fastest warm-cache run alone. Include clean builds, dependency changes and the failures your team actually experiences.

A transparent hypothetical worksheet#

Suppose, purely for planning, a team runs 120 workflows per month. Each has one 6-minute Linux job and one 14-minute macOS job. Before considering retries or account allowances, that produces 720 Linux job-minutes and 1,680 macOS job-minutes.

Let L and M be the applicable per-minute rates from the team's billing view. The modeled compute charge is:

text
720 × L + 1,680 × M

This is not a quote or a measured CascadeCI customer result. Substitute your rates, apply the actual included-usage rules, and add applicable storage. If a matrix adds two more macOS jobs per run, include those jobs; do not keep using the original estimate.

Put each check where it can run correctly#

Candidates for an independent Linux job include compatible static analysis, Dart tests and Android builds. iOS archiving relies on Apple's toolchain, so its requirements deserve a dedicated macOS path. Confirm platform dependencies before moving a test: a test using an Apple-specific plugin may not be portable.

A useful job split creates a small, explicit handoff: source revision, dependency lockfile, generated inputs where needed and test result. Passing a Linux check does not imply the iOS archive will compile or sign.

Make expensive release jobs conditional on the event and release policy. Cancellation of obsolete PR runs may reduce wasted work, but decide carefully for deployments or jobs that mutate an external service.

Optimize the largest verified waste#

Classify wasted time: unnecessary triggers, repeated dependency downloads, redundant matrices, slow signing setup or retries caused by flaky tests. Change one cause and compare several representative runs.

Caching saves work only when restoring a valid cache is faster than recreating it. An oversized or incompatible cache can add time and produce confusing failures. Avoid claiming a percentage saving without before-and-after observations.

Reconcile the estimate with actual charges#

At month-end, compare modeled job-minutes with billed usage and storage. Investigate the difference by runner, repository and trigger. Update the model with observed retry rates rather than adjusting a guessed global multiplier.

For alerting, remember that a budget notification is not automatically a hard spending cap. Our AWS budget guide discusses that distinction in another provider context; GitHub's own controls and billing rules must be checked separately.