Storage Cleanup
Safely reclaim unreferenced bundle artifacts and shared assets with the storage prune command.
How pruning works
hot-updater storage prune is reference-aware garbage collection. It reads all
bundle records and their manifests, lists the configured storage prefix, and
selects only objects that are no longer referenced.
It can remove:
- Orphaned bundle objects under
bundles/<artifact-id>/..., where the artifact ID is a UUIDv7. - Patch objects that are no longer referenced, including orphaned patches under a target Bundle that is still live.
- Unreferenced content-addressed assets under
assets/sha256/....
Live bundle objects, referenced patches and assets, recently modified objects,
objects without a modification timestamp, and unknown files are protected.
Root-level <artifact-id>/... paths are not recognized and remain protected.
Pruning does not delete live bundle records. Delete records you no longer need before pruning their unreferenced objects.
Remove bundles
Start by listing the bundles you intend to retire:
npx hot-updater bundle list --channel production --platform ios --limit 100 --jsonDisable each selected bundle, then hard-delete it. Hard deletion is separate from operational rollback.
npx hot-updater bundle disable <id> --yes
npx hot-updater bundle delete <id> --yesMultiple bundle IDs can share one immutable artifact, such as a promoted
bundle and its source. Deleting the last bundle that uses an artifact deletes
the artifact's record too, with every patch to or from it, so a device running
that bundle can no longer use it as a Hermes patch base. Unchanged files can
still be reused from the device; changed files download in full.
bundle delete reports the artifact deletion, and its --json output names
the artifact in deletedArtifactId.
hot-updater doctor reports artifact records no bundle uses as
UNREFERENCED_ARTIFACTS, and doctor --fix deletes them so the prune below can
reclaim their files.
A delete removes database records only. Bundle files, patch objects, and shared assets remain until a reference-aware prune confirms that no remaining record uses them.
Preview eligible objects
Run an explicit dry run first:
npx hot-updater storage prune --dry-runThe preview shows each eligible object, its modification time, size, type, and the total reclaimable size. The command fails closed if it cannot load all bundle references or required manifests.
The default --protect-newer-than 24h window compares the current time with
each object's storage lastModified timestamp. It does not measure time
since the bundle record was deleted. Increase the window when deployments may
remain in flight for longer:
npx hot-updater storage prune --dry-run --protect-newer-than 7dDurations accept m, h, d, or w, such as 30m, 24h, 7d, or 2w.
Delete eligible objects
Pause every deploy and patch process that writes to the same storage prefix, then run:
npx hot-updater storage prune --protect-newer-than 24h --yesBefore deletion, Hot Updater reloads bundle and manifest references and removes objects from the candidate set if they became live.
bundle promote does not need to be paused for Storage safety. It creates a new
bundle ID that reuses an existing artifact and does not upload or copy Storage
objects.
The configured database must own every object under the configured storage
prefix; without basePath, that is the whole bucket. If databases or
environments share a bucket, assign each one a separate storage basePath
before pruning.
Storage pruning currently requires the listObjects and deleteObjects
management capabilities provided by s3Storage, including AWS S3 and
S3-compatible services such as Cloudflare R2. Other Storage adapters continue to
support deploy and runtime delivery but cannot use storage prune until they
implement those management operations.