Mobile pipelines are slower than backend ones for structural reasons: builds are expensive, signing is stateful, and the tooling assumes a developer's machine rather than an ephemeral runner. An hour per build is common and is usually three or four fixable problems rather than an inherent cost.
01Where the time goes
Profile before optimising, because the intuitive answer is usually wrong. The compile step is rarely the largest slice.
Dependency resolution and cold caches typically dominate. A pipeline that reinstalls dependencies from scratch on every run spends more time downloading than compiling. Simulator or emulator boot is the second big block, and it is often paid multiple times because test jobs do not share a booted instance.
Signing and provisioning add both time and flakiness. Fetching certificates on every run means network dependency in the critical path and a failure mode that looks like a build error but is an expiry.
02What is worth caching
Not everything should be cached; a stale cache that produces a working build with wrong contents is worse than a slow pipeline.
- Dependency caches keyed on the lockfile hash. Safe, high value, and the single biggest win in most pipelines.
- Build artefacts across incremental builds on the same branch. Real gains, but invalidate on toolchain version changes or you will chase phantom failures.
- Pre-booted simulators reused across test jobs rather than booted per job.
- Do not cache signing material in a way that survives credential rotation - fetch it, but fetch it once per pipeline rather than once per job.
03Splitting the pipeline by intent
Not every push needs a full release build. The most effective change in most mobile pipelines is running different work at different triggers.
On pull requests, compile and run unit tests only - no signing, no store upload, no full device matrix. On merge to main, produce a signed internal build. On tag, run the full release path including store submission. This alone typically halves the feedback time developers actually experience.
Device testing is the exception worth paying for, but run it on a schedule or on release candidates rather than on every commit. A comprehensive device matrix on every push is expensive and rarely catches anything a nightly run would miss by more than a few hours.
04The parts that break at the worst time
Certificate and provisioning expiry is the classic release-day failure. Both expire on a fixed date and neither warns you in the pipeline. Monitor expiry dates as infrastructure and alert weeks ahead, the same way you would for a TLS certificate.
Store submission APIs change and deprecate. A release path that has not run in two months is not a working release path; run the full pipeline against an internal track regularly so the first time you exercise it is not during an incident.
Topics
Priya Iyer
Staff Engineer · SyncTrix
Writes about the engineering decisions behind production systems - architecture, delivery and the trade-offs that only show up at scale.
Building something like this?
SyncTrix engineers AI, SaaS, platform and cloud systems for enterprises and high-growth teams. Tell us what you're shipping and we'll scope it with you.
Talk to an engineer