Deployments

Release a bundle to a channel from the DeployYourApp dashboard, roll it out gradually, roll it back, and read device and analytics results.


A deployment puts one bundle on one channel at a chosen rollout percentage. Until a bundle is deployed, no device is offered it.

The deployments screen

Open an app and select Deployments. The table lists every deployment for the app, across all of its channels, newest first, 25 to a page. The page size selector offers 10, 25, 50, and 100, and paging fetches from the server, so the whole history is reachable. The order is fixed at newest-first and columns are not sortable.

Column Contents
Bundle Version The version of the deployed bundle
Channel The channel it was released to
Rollout A progress bar and the rollout percentage
Status The deployment's status chip
Deployed By The member who created it
Date When it was created

A deployment is created with the status active, and creating it retires whatever was live on that channel. Exactly one deployment per channel is active at any time:

Status Meaning
active Live on its channel. One per channel
superseded Replaced by a later deployment to the same channel
rolled_back Was live when a rollback moved the channel off it

A rollback is recorded as a new active deployment rather than a change to the old one.

Creating a deployment

Select New Deployment. The form is a five-step wizard.

1. Select bundle

Every bundle uploaded for this app is listed, labelled with its version and target platform, with its size and upload date underneath. If the list is empty, upload a bundle first with dya deploy — there is no upload path in the dashboard. See CLI commands.

A bundle whose storage was reclaimed by the retention policy is still listed — greyed out, with the reclaim date in place of the upload date — but cannot be selected: its record is kept, but there is nothing left to deploy. See Bundle retention below.

2. Select channel

Pick the target channel. Bundles belong to the app, so any bundle can go to any of the app's channels.

3. Rollout percentage

A slider from 1 to 100, with shortcut buttons for 10%, 25%, 50%, 75%, and 100%. The default is 100%.

4. Update behavior

Field Default Effect
Apply Mode When Idle Tells the device when to activate the downloaded bundle. Sent to the plugin with the update response and overrides the app's local setting for this update
Schedule Deployment empty An optional date and time. Before it passes, devices checking the channel are told there is no update
Delay (hours) empty Devices download the update now but hold it until the given number of hours has passed. Maximum 720 hours (30 days)

Apply Mode offers When Idle (whenIdle), Immediate (immediate), On Launch (onLaunch), and Background (background). What each one does on the device is described in Plugin configuration.

Leave both Schedule Deployment and Delay empty to release immediately.

5. Review and deploy

The final step lists the bundle, channel, rollout percentage, apply mode, any schedule or delay, and the bundle's release notes. Deploy Now commits it.

Creating a deployment sets the channel's active bundle to the deployed bundle, writes an audit entry, and sends an in-app notification and an email to the other members of the organization.

Deploying can be blocked by plan state

Deploy Now can fail if the organization has no active plan, or if its monthly active users or bandwidth have gone more than 10% over the plan limit for the current billing month. Rollback is blocked the same way. Both surface the server's message as a toast — the same message a dya deploy from the CLI would print to the terminal — explaining which of the two it is and linking to Settings > Billing.

Either message means more than a paused button: both states also stop devices already running your app from receiving updates at all, so seeing one here means end users are not getting anything right now, not only that this particular deployment is refused. A no-active-plan block lifts as soon as the organization is back on an active plan; an MAU/bandwidth block lifts automatically when the usage period rolls over to the next calendar month, or immediately on a plan with more room. Nothing is deleted in either case. See Usage and limits and Plans and pricing.

Uploading a bundle from dya deploy is unaffected by an MAU/bandwidth block — only creating or releasing a deployment is. A bundle can be uploaded and sit ready while blocked, and appear in step 1's bundle list, but cannot be selected into a live deployment until the block lifts.

How percentage rollouts work

Each device is placed in or out of a rollout by hashing its device ID together with the deployment ID. The result is stable: a device that is included stays included for that deployment however often it checks, and a device that is excluded keeps being told there is no update.

Because the deployment ID is part of the hash, a new deployment reshuffles the buckets. Deploying the same bundle again at a higher percentage does not necessarily keep the same devices in the group — it selects a fresh set of that size.

At 100% the check is skipped and every eligible device is offered the update.

A device also has to pass the channel's own rules before the rollout is even considered — platform match, version blocking, and the downgrade policy. Those are described in Managing apps and channels.

Promoting a bundle between channels

There is no promote button. To move a release from beta to production, create a new deployment, select the same bundle in step 1, and select production in step 2. The bundle's history on the earlier channel is unaffected, and both channels keep their own active bundle and rollout percentage.

Rolling back

The Rollback action appears only on active rows — one per channel — because a rollback moves a channel off whatever is currently live on it. Confirming it reverts the channel to the bundle from the deployment before that one, marks the deployment you left as rolled_back, and records a new deployment at 100% rollout marked as a rollback.

Two things to know:

  • The request names the row you selected, and the server checks it is still that channel's live deployment. If someone else deployed to the channel while your table was open, the rollback is refused with "That deployment is no longer the active one for this channel" and the table reloads, rather than rolling back a deployment you never saw.
  • If the channel has only ever had one deployment, rollback is refused with "No previous deployment to roll back to".

Only owners and admins can roll back. Developers can create deployments but not roll them back — see the permission matrix.

The CLI has an equivalent command, dya rollback.

Bundle retention

Uploaded bundles used to sit in storage forever — every deploy left the previous bundle behind, counted against your storage limit for the life of the account. An hourly background pass now reclaims the storage of bundles that are no longer needed for rollback, on this policy:

A bundle is expired — its storage object removed — when all three are true:

  • It is not among the 5 most recently deployed bundles of any channel on the app.
  • It is older than 15 days.
  • It is not protected (see below).

Retention is per channel, unioned across channels. Each channel keeps its own most-recently-deployed set; a bundle survives if it is in any one channel's set, even if every other channel has moved on. A busy beta channel redeploying daily does not push a production rollback target out of retention — the two channels' retained sets are added together, never intersected.

Protected, regardless of age or recency:

  • A channel's current active bundle.
  • The rollback target of a channel's newest deployment — the bundle a plain dya rollback or Rollback would return to.

A bundle never deployed to any channel — uploaded but never released, or a candidate that was replaced before deployment — is in no channel's retained set at all. It is kept only by the age rule: it expires once it turns 15 days old, whether or not it was ever deployed anywhere. This is the one case worth calling out explicitly, since "the recent few per channel" does not by itself predict what happens to a bundle with no channel history.

Expiry keeps the database record and removes only the storage object. The version, checksum, upload date, release notes, deployment history, and audit trail all remain, and the bundle stays visible in the list above and in the API's bundle responses, which carry an expiredAt timestamp so a client can tell "reclaimed" apart from "never existed". What is gone is the file itself: an expired bundle cannot be downloaded, and cannot be selected as a rollback target or deployed to a channel. Attempting either is refused with a message naming the retention policy, not a generic "not found" or "deleted" — nobody in your organization deleted it.

Every expiry is recorded in the audit log as a bundle.expired entry naming the bundle and its version — deliberately distinct from the bundle.deleted entry a member's own deletion writes, so that "the file is gone" can always be traced to either the policy or a person. The entries are captured on every plan; reading them under Settings > Audit Log requires Scale or higher, as described in Team and audit log.

The worker runs hourly, so a bundle that becomes eligible does not disappear the instant it crosses the age threshold — expect up to an hour's lag, the same as the other background aggregation described in Usage and limits.

Reading the results

Devices

The Devices screen lists the devices that have checked in for the app: device ID, custom ID, platform, OS version, app version, plugin version, the channels the device is subscribed to, and when it was last seen. You can filter by platform and search by device ID or custom ID.

The screen loads the 100 most recently active devices. If the app has more, a notice above the table says so and gives the true total — the platform filter and the search box apply to the loaded rows only. Export CSV downloads the full device list (up to 10,000 rows), which is the way to work with the complete set.

Analytics

The Analytics screen has a date range with 24h, 7d, 30d, and 90d presets, and covers:

  • Counters — events in the selected range, events in the last 30 days, total devices, and devices active in the last 7 days.
  • Event Types — a breakdown of the event types reported in the last 30 days.
  • Channel Adoption — how the app's devices are distributed across channels.
  • Deployment State — which bundle version every active device is actually running, as percentages, with a chip per channel showing its released version and current rollout percentage. Devices still on the version shipped in the store show as builtin.
  • Top Errors — errors grouped by message, with unique devices affected, that figure as a percentage of the active install base, total occurrences, fatal count, the bundle versions involved, and when each was last seen. A warning appears if the range contained more error events than a single query scans.
  • Recent Events — the raw event stream with device, bundle version, and event details.

Export CSV downloads the underlying event stream for the selected range.

Analytics reflect what devices report: the update lifecycle events emitted by the plugin, plus any custom events your app sends. See Update lifecycle.

Update logs

A per-app update log records the individual lifecycle events a device went through — check, available, download_start, download_complete, download_fail, verify_pass, verify_fail, apply_start, apply_complete, app_ready, and rollback — with filters by event type, device, and time range, and a metadata viewer per row.

This screen is not currently linked from the navigation. Reach it at /dashboard/apps/<app>/update-logs.


Previous
Apps & Channels
Next
Team & Access