Understand / How patches & deployments work

PatchForge Concepts

This is the conceptual reference for PatchForge — the multi-tenant Over-The-Air (OTA) update platform for React Native apps. It explains every entity you work with in the dashboard, how the pieces relate, and how an update travels from your build machine to a user's device.

If you want step-by-step instructions instead, see how-to.


Organization

An organization is the top-level tenant. Everything in PatchForge — applications, releases, devices, deployments, analytics, API tokens, notifications — is scoped to a single organization, and the dashboard only ever shows data for the organization you belong to.

  • Every member of an organization holds a role (for example Super Admin, Admin, or Viewer). Roles carry permissions (such as release.deploy, release.rollback, settings.manage, analytics.view), and the dashboard hides or disables actions you are not permitted to perform.
  • All resources beneath an organization are isolated from every other organization. There is no cross-organization visibility.

Relationship: an organization owns many applications and many members.


Application

An application is a single React Native app registered in PatchForge — for example your production mobile app. It belongs to one organization.

  • Each application has a name and at least one platform identifier: an Android package name and/or an iOS bundle identifier (reverse-DNS, e.g. com.company.app). You can register one or both platforms.
  • Each application has an appKey — a public, non-secret identifier that the React Native SDK uses to identify the app when it talks to the OTA server. The appKey is safe to embed in your shipped binary.
  • When an application is created, PatchForge automatically provisions a set of default channels (deployment environments) for it.

Relationship: an application belongs to one organization and owns many channels, releases, patches, deployments, and devices.


Channel

A channel is a named deployment environment within an application — for example production, staging, or development. Channels are how you keep a beta audience separate from your production audience while using the same app.

  • A channel belongs to one application and has an environment type (such as Production or a non-production environment).
  • One channel is marked the default for the application.
  • The React Native SDK is configured to connect to exactly one channel. A device on the staging channel only ever receives releases deployed to staging.

Relationship: a channel belongs to one application; releases and deployments are scoped to a channel.


Release

A release is a versioned JavaScript bundle uploaded for a specific channel of an application. It is the unit you build, upload, and deploy.

A release moves through these statuses:

StatusMeaning
DraftThe release record exists but no bundle has been uploaded yet.
UploadedThe bundle has been uploaded and is queued for processing.
ProcessingThe worker is hashing, signing, and building the manifest for the bundle.
ReadyProcessing succeeded — the release is verified, signed, and deployable.
FailedProcessing failed (see the failure reason on the release detail page).
ArchivedThe release has been retired.
  • During processing the platform computes a SHA-256 hash of the bundle, cryptographically signs the hash with an RSA-4096 signing key (recorded with a keyVersion), and builds a manifest. The SDK later verifies this checksum and signature on the device before installing, so a tampered bundle is rejected.
  • Bundles (and their generated patches) are stored in Cloudflare R2 or on the local filesystem, depending on how the server is configured. Storage is private — devices only ever receive short-lived, signed download URLs, never raw storage paths.
  • A release only becomes installable on devices once it is deployed (see Deployment). A release that is Ready but not deployed has not yet reached any device.

Relationship: a release belongs to one application and one channel, has a bundle version, and is the thing a deployment activates.


Ring

A ring is a rollout segment within a deployment. Rings let you stage an update by audience before going wide. The available rings are:

Internal · Beta · EarlyAccess (Early Access) · Production

  • You choose a ring when you deploy a release. It identifies which audience segment the deployment is targeting.
  • Rings are combined with a rollout percentage (see Rollout) to control how broadly an update reaches devices.

Relationship: a ring is one attribute of a deployment, set when you activate a release.


Rollout

A rollout is the active configuration of a deployment — the rollout percentage that controls what fraction of eligible devices receive the update. Available percentages are:

1% · 5% · 10% · 25% · 50% · 75% · 100%

  • Devices are bucketed deterministically: the OTA server hashes a stable device identifier into a 0–99 bucket, so the same device consistently falls inside or outside a given rollout percentage. A device that is "in" at 25% stays in as you raise the percentage; you never re-roll the dice on the same device.
  • You can adjust the rollout percentage of an active deployment from the deployment detail page to widen (or hold) the audience over time.

Relationship: a rollout is the percentage attribute of an active deployment; it works together with the ring and the deterministic device bucketing.


Health score

A health score is a composite metric from 0–100 that summarizes the quality of a release on a channel. It powers the release health card on the release detail page and the per-channel environment-health cards on the application page.

It is computed from the release's quality signals:

  • Install success rate — installs versus failed installs.
  • Crash rate — crash reports relative to installs.
  • Rollback signal — whether the release has been rolled back.

The score maps to a status: Healthy (≥ 80), Warning (≥ 50), Critical (< 50), and Unknown when there is not yet enough data (so the UI shows "No data" rather than a misleading 100). Health is informational only — it surfaces problems for a human to act on; it never triggers an automatic rollback in V1.

Relationship: a health score is derived from the install, failure, crash, and rollback data collected for a release on a channel.


Device

A device is a unique end-user device running your app with the PatchForge SDK installed.

  • Each device is identified by a UUID that the SDK generates once and stores in the device's secure storage, so the identity is stable across launches and updates.
  • The platform records each device's installation history — which release versions it has downloaded and installed, and whether each install succeeded or failed.
  • The dashboard provides a read-only Devices view, both per application (/applications/[id]/devices) and organization-wide (/devices), where you can inspect a device and its installation history.

Relationship: a device belongs to an application (via its appKey), connects to one channel, and accumulates an installation history that feeds analytics and health scores.


Deployment

A deployment is the act of activating a Ready release on a channel. It is what actually makes a release reach devices.

  • A deployment carries a ring, a rollout percentage, an optional note, and a type (Manual, Scheduled, or Rollback).
  • A channel has at most one Active deployment at a time. Deploying a new release supersedes the previous one (the prior deployment becomes Superseded). Deployment status is one of: Active, Superseded, or RolledBack.
  • Every deployment has a timeline — an append-only record of events (created, validated, signed, patch generated, deployed, rolled back) shown as a GitHub-Actions-style timeline on the deployment detail page.
  • A deployment supports rollback (see below): re-activating the previously deployed release at 100% on the channel.

Relationship: a deployment activates one release on one channel, with a ring + rollout, and records a timeline.


Rollback

A rollback re-activates the previously deployed release on a channel, replacing the current active deployment. It is the manual safety mechanism for backing out a bad update.

  • A rollback is itself a deployment of type Rollback, activated at 100% on the channel.
  • The current active deployment is marked RolledBack, and the prior release becomes active again.
  • On the device side, the SDK pulls the previous bundle on its next update check. The on-device SDK also has its own crash-loop protection (windowed crash detection that reverts to the last known-good bundle), independent of a dashboard-initiated rollback.

Relationship: a rollback is a deployment that restores the previous release; it reverses a deployment.


Patch

A patch is a binary differential between two consecutive releases — it contains only the files that changed (added, modified, or deleted) between a source release and a target release, not the whole bundle.

  • The server generates patches automatically in the background after a release becomes Ready, diffing it against recent prior releases on the same channel and version line.
  • A patch has its own status: Pending, Processing, Completed, or Failed. Patches are hashed and signed just like full releases.
  • When a device that already has the source release checks for an update, the OTA server offers the much smaller patch instead of the full bundle. The SDK applies the patch on-device to reconstruct the target bundle, and falls back to a full download if the patch can't be applied. This keeps over-the-air downloads small for the common case.

Relationship: a patch belongs to an application and connects a source release to a target release; the OTA server chooses patch-vs-full per device during an update check.


The OTA flow, end to end

Putting the entities together, here is how an update travels from your machine to a user's phone:

  1. Build & upload. You build your React Native JavaScript bundle and upload it as a new release for a channel of your application. It starts as Draft/Uploaded.
  2. Process. The worker hashes the bundle (SHA-256), signs the hash (RSA-4096, recorded with a keyVersion), builds the manifest, and moves the release to Ready. Stored privately in R2 or on the filesystem.
  3. Patch generation. In the background, the server generates patches from recent prior releases to this one, so most devices can take a small differential instead of the full bundle.
  4. Deploy. You create a deployment that activates the Ready release on the channel, choosing a ring and a rollout percentage. This becomes the channel's Active deployment (superseding any previous one).
  5. Device check. A device running the SDK on that channel periodically calls the OTA server's check endpoint with its appKey, platform, channel, and current version. The server answers from a Redis-first cache, computes the device's deterministic rollout bucket, and decides whether to offer an update — and whether to offer a patch or the full bundle.
  6. Download & verify. If an update is offered, the SDK downloads it via a short-lived signed URL, verifies the SHA-256 checksum and the RSA signature against its embedded trusted key, and rejects anything that doesn't match.
  7. Install. The SDK applies the patch (or stages the full bundle) and activates it according to the configured install mode (immediately, on next restart, or manually).
  8. Report & observe. The SDK reports download/install/failure/crash events back to the server. These feed the analytics dashboards and the release health score, so you can see how the rollout is doing.
  9. Widen or roll back. Based on the health signals, you either raise the rollout percentage to reach more devices, or roll back to restore the previous release.

This loop — upload → process → patch → deploy → check → download → verify → install → report — is the core of PatchForge.