Ops report

    OTA updates in production: EAS vs CodePush vs manual — 47 app cost & latency study

    With Microsoft App Center sunset done, every React Native team has to pick an OTA strategy. We pulled cost, adoption curves, and rollback data from 47 production apps.

    May 4, 2026Updated May 10, 202617 min readBy Ritesh
    OTA updates EAS CodePush manual cost study

    TL;DR

    • EAS Update is the cleanest answer for most teams. $99 per 100k MAU/mo, 3-hour median rollback, and 95% MAU on the new bundle within 72 hours. The pricing is real but the time savings dwarf it.
    • Manual store-only updates take a median 14 hours per rollback. Apple review delays make "just submit a hotfix" non-viable. Most production bugs that go through store review take 2-3 days to actually reach users.
    • Self-hosted OTA on S3 + CDN is the right pick at >500k MAU if the team has the operational capacity. Pricing flips below EAS at that scale, but ops cost runs at ~$1k/mo of engineer time.

    Microsoft App Center's CodePush retirement has forced every React Native team to pick a new OTA path in 2025-26. The choices are EAS Update (Expo's hosted), continuing CodePush via the community fork, self-hosting on S3 + CloudFront, or skipping OTA and shipping only through the stores.

    We have OTA telemetry on 47 production React Native apps across all four strategies. This report puts numbers on the trade-offs: cost per 100k MAU (OUC), adoption curve (AAR), and rollback cost (RBC).

    Methodology

    47 RN apps with at least 30k MAU each. Update events tracked over a 12-month window. Cost figures pulled from vendor invoices for hosted services, and from CloudWatch / S3 billing for self-hosted apps. Adoption curves measured via in-app version telemetry. Rollback cost is engineering hours from incident open to revert live.

    Finding 1: OUC ranges 3× across providers

    EAS Update is the most expensive at $99 per 100k MAU/mo (factoring metered downloads + manifest requests). Self-hosted on S3 + CloudFront runs ~$32 at 100k MAU. CodePush via the community fork is functionally free but the maintenance status is uncertain. Manual updates are free in cash but pay heavily on adoption (next chart).

    Finding 2: Adoption curves diverge by 5× at 24h

    The AAR curve is what most teams care about. EAS gets to 84% MAU at 24 hours; self-hosted to 72%; CodePush to 62%; manual via store update to 6%. The implication for hotfix workflows is sharp — a critical bug pushed via OTA reaches 90% of users in 2 days; the same bug pushed via the store reaches 90% of users in roughly 2 weeks.

    Finding 3: Rollback cost is where manual really hurts

    Median rollback hours: EAS 3, CodePush 6, self-hosted 8, manual 14. The rollback cost is what you actually pay when something breaks. EAS's built-in rollback to a previous channel is the cleanest version of this; manual involves a new App Store review unless you can fix forward in flight.

    How we measure each OTA strategy

    1. OTA Update Cost per 100k MAU (OUC)

    OUC = Provider cost ÷ MAU × 100,000

    The unit-economic number for OTA. Compute on monthly invoices; project against your MAU growth curve.

    2. Adoption-After-Release (AAR)

    AAR(t) = % of MAU on new release at hour t after publish

    The shape of the curve matters more than the steady-state percentage. Steeper-early curves are better for hotfix workflows.

    3. Rollback Cost (RBC)

    RBC = Median engineering hours from incident open to rollback live

    Track per provider. RBC over 8 hours means rollback is so painful that the team avoids using it, which is itself an operational risk.

    Findings from running OTA in production

    1. Channel-based gradual rollouts are the highest-leverage feature in this category. Teams that ship to 5% / 25% / 100% over 24 hours catch 70% of regressions before full rollout.
    2. JS-only changes can OTA; native changes still require store builds. The ratio of OTA-able vs store-required changes is ~80/20 across our sample. Architect new features as JS-only where possible.
    3. OTA introduces auditability problems in regulated verticals — fintech, healthtech. Three of our clients had to pause OTA after compliance reviews; current Apple policy allows it but only with explicit user notice for material logic changes.
    4. The slowest manual-update tail is actually long. 38% of MAU are still on a 30-day-old release on manual-update apps. The chart cuts at 336 hours; the curve never quite hits 100%.
    5. EAS Update's "branches" feature meaningfully reduces incident rate for teams with multiple environments. Catching the misconfigured staging branch before it hits production is the #1 incident-prevention move we've seen.

    Two patterns from companion studies show up directly in the OTA layer. Apps built on AI-generated scaffolds tend to ship JS bundles with unaudited dependencies — see the AI prototype codebase audit for the upstream cause and the rebuild cost. And once a team is running per-tenant or per-customer channels, OTA channel design is effectively a multi-tenant architecture decision — the same isolation, blast-radius and cost tradeoffs apply to update fan-out as to data partitioning.

    Recommendations

    For RN teams <500k MAU

    Use EAS Update. The cost is real but the operational wins are bigger than the savings on a self-host. Almost every RN engagement we ship runs on EAS, configured for gradual channel rollouts and beta channels. Our React Native app development engagement bakes this in.

    For RN teams >500k MAU

    Run the math. Self-hosted on S3 + CloudFront with a proper update server (expo-updates self-host or a custom one) flips below EAS pricing past ~500k MAU. The maintenance overhead is real — usually around an engineer-day per month plus on-call coverage. Our maintenance & support engagement covers this for teams that don't want to absorb the ops cost themselves.

    For RN teams in regulated verticals

    Check the OTA policy for the vertical first. HIPAA-relevant changes need to go through formal validation; fintech features may need attestation. The cost of OTA is "free" to the engineering team but the compliance team will have an opinion. Plan accordingly.

    Limitations

    47-app sample biased toward English-market B2B and DTC; consumer apps with very high update frequency may behave differently. Cost figures use vendor pricing as of May 2026; both EAS and AWS adjust pricing periodically.

    The OTA decision that matters most

    For most RN teams, EAS Update is the right answer and the pricing is much smaller than the operational cost it prevents. Stop debating self-hosted vs hosted unless you're past 500k MAU — below that, the answer is EAS by a clear margin.

    ■ Related research

    Related research

    The launch-side companion — how often React Native apps get rejected and why:

    ■ Related services

    Get OTA shipped properly

    The mobile build, the submission/launch discipline that lives alongside OTA, and the API layer where the OTA manifest server actually lives:

    Ritesh — Founding Partner, Appycodes

    About the author

    RiteshFounding Partner, Appycodes

    LinkedIn

    Co-authored with Prince Sharma, Lead React Native Engineer

    Ritesh leads mobile engineering at Appycodes. The 47-app OTA dataset draws on apps we ship and maintain in production. He led the migration of three high-MAU apps off CodePush ahead of the App Center sunset, including a delivery-driver app where channel-based gradual rollout caught a regression at 5% of MAU before it reached the rest of the user base. The companion war-stories from our React Native rejection study cover the launch-side of the same operations.

    Last reviewed: May 10, 2026

    Full stack web and mobile tech company

    Taking the first step is the hardest. We make everything after that simple.

    Let's talk today