On-Demand Mobile Releases: How We Got There and Why You Should Too
How we got to continuous deployment on mobile to ship like a web team — on demand, to 100% of users. You don’t really need phased rollout!
Every few weeks, one of our iOS engineers lost a day to a checklist.
Not a metaphorical checklist. A real one — a Confluence doc with 25 steps, every box ticked manually, every tool opened in sequence. GitHub to cut the branch. Tuist to bump the version. Jira to create the release, find every ticket in “ready to deploy” state, tag each one with the release version. App Store Connect to create the new version, write release notes in every supported language, configure the rollout settings, select the build, submit. Slack to ping testers, post in the deploy channel. Then wait for regression sign-off, then back to App Store Connect to push to production. Then merge the release branch, create the sync PR back to develop, update the Confluence doc title from “Deploying” to “Released.”
Best case: 1–2 hours if everything went smoothly and you had no interruptions. Average: 3 hours. Bad day: 5 hours.
And we rotated. Nobody owned releases permanently — that would be too cruel. So every couple of weeks, a different engineer drew the short straw.
This is not a unique problem. Most mobile teams I’ve talked to have some version of it. You’re context-switching between half a dozen tools, the App Store submission process has steps that can’t be skipped, and over time the checklist grows because the app grows and so does the complexity — there’s just more to do.
Engineer time is expensive, we need to save it. This was pure overhead — not a feature, not a bug fix, not a code review. Just ceremony.
What we set out to do
We didn’t set out to reinvent how we deploy mobile apps. The goal was modest: automate the checklist. Get as close to one-click as possible. Get this off our engineers’ plates.
We adopted Runway, a mobile release management platform. It replaces a lot! Runway cuts the release branch, bumps the version and raises the PR, calculates the diff between this release and the last one, auto-tags every Jira ticket with the release version, creates the Jira release page, generates the build, and handles App Store and Play Store submission. The steps that used to require a human navigating six tools in sequence now happen automatically.
The release engineer’s job went from running a 25-step checklist to: kick off the release, verify your tickets work, approve the build, submit. Runway handles the rest.
That alone was worth it.
Sponsored
Join One of the Top Consumer App Teams in San Francisco
Triumph builds two #1 App Store apps: Triumph Arcade, a casual skill gaming platform, and Rips, the best way to discover and buy trading cards. Hundreds of thousands of MAUs, a tiny mobile team of three, and some of the best engineers you'll ever work with. Salary: $200-400k
The question we didn’t expect to ask
Once releasing was cheap, we started asking questions we hadn’t asked before.
The obvious one: why are we still releasing every two weeks?
If a release takes a few clicks instead of half a day, there’s no reason to batch changes. You can ship as things are ready. So we did. We moved to on-demand releases — ship when there’s something worth shipping, not on a calendar. Effectively, we got as close to continuous deployment as possible on mobile. Just like a good web or backend team would.
The less obvious question came next: why are we doing 7-day phased rollouts?
Phased rollout is standard practice on iOS — 7 days is the default. You ship to 1% of users, then slowly ramp up over the week, watching your crash rate and reviews as you go. The idea is that if something goes wrong, you pause the rollout before it reaches everyone. You fix it, submit a new version, and start over — back to day one, back to 1%. Then the new version rolls out over another 7 days.
We had been following this without question. It’s a dogma of the iOS community — a sacred cow. Everyone is scared of shipping a bug. OMG what if it crashes for someone! So you roll out slowly, keep your finger on the pause button, and feel safe.
But then we actually looked at our numbers, and they didn’t support the fear.
The phased rollout probably isn’t helping you as much as you think it does
Phased rollout protects you from client-side bugs — code you shipped that breaks something for users. For it to be worth the delay, two things need to be true:
1. You ship crappy code regularly — crashes, broken flows, bugs that make it through to production. If your defect rate is low, there’s nothing much to catch.
2. You have the monitoring tools to get an early warning signal in that first 1%, and the discipline to actually watch them and act. Without that, the rollout is just delay with no feedback loop.
For us, neither was really true.
Our crash rate from client-side changes is low — super low, something like 3.6x less than our web team’s. We’re a careful team, and our architecture — we use RIBs — gives us a structure that’s easy to reason about, easy to code review, and hard to break in ways that don’t surface during development. The QA gate before every release means engineers verify their own tickets before anything ships.
If RIBs is new to you: I’ve written about our full architecture at UpKeep and I’m also the primary iOS maintainer of the repo.
What actually goes wrong for our users mostly comes from the backend — API contract changes, service issues, things the mobile app has no control over and that a phased rollout does nothing to address. If the backend breaks something, it breaks it for 1% of users and 100% of users equally.
On top of that, phased rollout creates a queuing problem. Start a 7-day rollout on Monday. By Wednesday, there’s a fix ready to ship. Now you either wait out the rollout — so your fix doesn’t reach users for days — or you submit a new release and restart the clock from 1% again. Neither option is good.
So we stopped. We switched to releasing directly to 100% of users.
The only thing we can’t control is Apple’s review process, which normally takes less than a day. After that, users get the update immediately.
What actually makes this safe
This isn’t reckless. You have to have your shit together to deploy continuously.
For us, that comes from three things.
Architecture. RIBs gives us a structure that’s easy to develop in and easy to code review. Features are isolated. Changes are contained. The codebase is large, but it’s navigable. This keeps our client-side defect rate low.
If you want to understand why architecture is important, I’ve written about clean architecture and why it matters
Feature flags. Anything risky goes behind a flag. You can merge and deploy the code before the feature is visible to users. If something goes wrong after you flip the flag, you turn it off — no new release needed.
Ownership. Engineers test their own tickets before every release. Regression isn’t a separate team’s job — it’s yours. You know what you built. You verify it works.
This is part of a broader shift I’ve been thinking about — mobile engineers owning far more of the stack than they used to.
These three together mean that by the time a release ships, we’re genuinely confident in it. Not because we’re lucky, but because we built a process that we can trust.
What about when you do ship a bug?
You will eventually. Everyone does.
With on-demand deployment, a hotfix is just the next release. Same pipeline, same process. Fix it, merge it, kick off a release, ship it. Users get the fix quickly — often faster than they would have under a phased rollout cycle where you’d have to wait for the current rollout to complete before starting another.
No special hotfix process. No war room. Just another release.
This isn’t for everyone
Large teams need different tools. At companies like Uber, there’s a weekly release train. Your code either makes it through the CI queue before the cut or waits for next week. That structure exists because there are many engineers, many features, and the coordination overhead alone is significant. A release train makes that manageable.
If you’re at a company with dozens of engineers all committing to the same mobile app, a release train is reasonable. But most mobile teams aren’t that. Most mobile teams are small, working on a focused product, and operating with far more ceremony than needed.
If you ship clean code and your defect rate is low, you probably don’t need bi-weekly releases. You don’t need 7-day rollouts. You’re just slowing yourself down for no good reason — or out of fear.
Where to start
The tools are out there. Runway is what we use and it works well for us. You could also wire something similar yourself with GitHub Actions and the App Store Connect API — the automation isn’t magic, it’s scripting the steps you currently do by hand.
The harder part is the philosophy. Phased rollout feels safe. Frequent releases feel risky. That intuition is backwards if your team has good architecture and a low defect rate.
Start with the checklist. Automate the parts that don’t need a human. Once releasing is cheap, the rest of the questions answer themselves.

