Loading... Search articles

Search for articles

Sorry, but we couldn't find any matches...

But perhaps we can interest you in one of our more popular articles?
Self-hosted OTA for an hour a month

Self-hosted OTA for an hour a month

Aug 27, 2026 - 5 min read

This article is written by Zach Goldie

If you are a React Native engineer, your job isn’t typically about maintaining infrastructure. So “self-hosted OTA” can sound like a trap. Even if your Expo Update bill is hitting six figures, it’s easy to assume that self-hosting isn’t worth the potentially huge time sink.

That fear is understandable, but it doesn’t have to play out that way.

With Codemagic Patch, standing a server up takes about an hour, and keeping it running stays around an hour a month even for huge user bases.

What people imagine

You might guess that keeping an OTA server running in production involves lots of complex parts, such as:

  • provisioning and autoscaling servers
  • wiring up load balancers and Redis caching
  • constant health checks and multi-step server updates
  • responding to on-call when updates fail at 2am
  • becoming the person who “runs OTA" for the whole company

In other words, a DevOps project with some mobile development attached.

While some OTA services are less tidy than others, running Patch is far more minimal and hands-off than the above list.

What you actually stand up

Patch’s supported path is Docker Compose on one Linux host. The installer is scripts/selfhost/install.sh, which creates:

  • API server for publishing releases
  • Postgres for release data and metrics
  • MinIO for artifacts
  • Caddy for TLS and the dashboard

These are all the pieces for a working service, already connected for you. It can run on any machine with at least 2 GB RAM.

Finishing the setup takes a small bit of external wiring:

  • DNS records for two subdomains
  • Registering a new OAuth App in GitHub
  • Copying cache rules into Cloudflare

This is all outlined in the install guide and should take under an hour.

There is also a local evaluation stack you can run on your machine to get a feel for Patch without even touching a server.

Avoiding scaling headaches

The time sink people worry about is rarely a working release. It is the bad week when traffic spikes and you are debugging Redis, autoscaling, and cache invalidation instead of doing mobile development.

Codemagic Patch is specifically designed to avoid that class of scaling headache.

When someone opens your app, it will usually send a request to ask if it’s on the latest bundle version. With most other tools, this is a request to the server that then makes a few database queries.

Typical OTA architecture: update checks hit the API and database on every poll
Typical OTA architecture: update checks hit the API and database on every poll

For apps with millions of users, self-hosting with services such as CodePush forks means adding extra infrastructure to stop the API and database from struggling with this load. You can end up lost in response caching with Redis and autoscaling servers.

Patch was redesigned to avoid this bottleneck, based on our experience running billions of update check requests.

Instead, each time you do a release, a small manifest.json is created saying what bundle each binary version should have. These manifests are stored on the CDN, so your machine never gets slammed with thousands of requests per second.

CDN-first OTA architecture: clients fetch pre-generated manifests from object storage and the CDN
CDN-first OTA architecture: clients fetch pre-generated manifests from object storage and the CDN

It’s like posting information on a bulletin board, instead of running a call center, which means the infrastructure can stay minimal regardless of the number of users.

Your machine uploads releases and collects metrics; devices read manifests from the CDN. That avoids the scaling failures that tend to turn into multi-day server debugging.

Keeping the machine running

Once Patch is up, ongoing care is mostly four occasional tasks:

  • A quick look that disk still has headroom (artifacts and metrics accumulate over time)
  • backup.sh on a schedule you trust, with copies stored off the host
  • upgrade.sh when a new Patch release ships; it handles the backup step for you
  • Linux OS updates when your provider or distro prompts you

See Ongoing maintenance and Operations for the command reference.

Self-hosting risk assessment

The last aspect to consider is the impact if the server does go down.

Fundamentally, the app will still keep working for users. They won’t even notice something has gone wrong.

With manifests and bundles on the CDN, devices will still be able to discover and install the latest release, even if your server goes down.

The only real risk is wanting to release an OTA update and being unable to, because the service isn’t working. That isn’t ideal, but it won’t bring in an influx of one-star reviews.

When something does go wrong, it is usually a host problem (disk, DNS, a bad upgrade), not a day spent debugging a custom platform. With off-box backups, restore.sh and a fresh install are the recovery path.

The hour-a-month tally

Put together, the work looks like this.

First-time setup, once you have a small Linux VM:

  • Provision a small Linux VM and install Docker: about 10–15 minutes
  • Two DNS records (plus waiting for them to resolve): about 5–15 minutes
  • GitHub OAuth App: about 5–10 minutes
  • install.sh (image build and Let’s Encrypt): about 10–20 minutes
  • Cloudflare on the storage domain: about 10–15 minutes
  • Sign in and a quick health check: about 5 minutes

That is usually about an hour end-to-end, longer if DNS is slow to propagate.

To keep the service running:

  • Quick check that disk has headroom: a few minutes
  • OS updates when needed: about 15–20 minutes
  • Off-box backup with backup.sh: about 10–15 minutes
  • upgrade.sh when a Patch release drops: about 15–30 minutes

A quiet month stays well under an hour. A month with an upgrade still fits without turning into a DevOps project, regardless of how many users you’re serving.

Patch is maintained by Codemagic’s product team, not a side project you are left to interpret alone. If install or self-hosting throws something unexpected, Discord and GitHub issues reach the people building the server and docs.

So if you’ve ever wanted to avoid the huge bills of a hosted OTA service, but were uncertain about the burden of self-hosting, go ahead and give Patch a try.

Try Patch

Related articles

Latest articles

Show more posts