# Golden images (/docs/devices/golden-images)



A golden image is a settled simulator warden clones new pool devices from, so a claim that needs a new iOS sim boots in seconds instead of minutes; you only touch it to pre-build one or prune old ones.

```bash
warden golden ensure --profile iphone-17
```

A brand-new simulator's first boot takes 1–10 min, and about 80% of that is the one-time data migration. Measured:

| Scenario                         | Time           |
| -------------------------------- | -------------- |
| fresh create + first boot        | 146–239 s      |
| clone of a settled golden + boot | 3.7 s + 11.9 s |
| 3 clones booted in parallel      | \~20 s         |

So when `warden claim ios` needs a **new** pool device, it clones it (`simctl clone`) from a **golden image**: a sim warden booted once, waited on until its data migration finished (`DMLastMigrationResults`, since `bootstatus -b` can return early) and its CPU settled, then shut down.

* The golden is built on first use and keyed by Xcode build + runtime + runtime build + device type + recipe. An Xcode or runtime upgrade simply builds a new one.
* The golden also has the e2e driver's accessibility switch (`AutomationEnabled`) written in it, so a fresh clone's first driver open skips that in-sim `defaults write`. This is recipe 2: after upgrading to it, every machine builds a recipe-2 golden once (a few minutes) on its next claim; run `warden golden ensure` to pay that ahead of time. Golden names carry their recipe (`warden-golden-<profile>-<key>-r2`), so two warden versions on one machine (say an older npm install and a checkout) each keep their own golden instead of deleting each other's on every claim: a claim keeps the previous recipe's golden of the same target and never deletes a newer recipe's. Each kept golden costs disk (a full simulator, \~1.5 GB); `warden golden prune` deletes the older recipes' goldens once you no longer run the older version.
* Clones are APFS copy-on-write (\~30 MB each).
* If cloning fails, warden falls back to `simctl create`. `WARDEN_GOLDEN=0` turns cloning off.
* A pool device that already exists is always reused first; a second boot takes \~6.5 s.
* Goldens are never allocated, adopted, booted by `gc` or counted in the pool; `warden devices` labels them `golden`.

## Commands [#commands]

```bash
warden golden ensure --profile iphone-17   # build ahead of time, so the first claim doesn't pay
warden golden ls
warden golden prune                        # delete stale goldens; --all deletes every one
```

## Android: warden's quick-boot snapshot [#android-wardens-quick-boot-snapshot]

Claimed emulators launch `-read-only -snapshot warden-<key>` from a quick-boot snapshot warden owns when it exists, instead of whatever `default_boot` your last Android Studio run left (or a full cold boot). A claim never builds it: a claim that finds no current snapshot cold-boots read-only exactly as before, logs one line, and marks the AVD. The next `warden gc` (auto-gc runs it in the background) builds the snapshot of one marked AVD per pass, only while no emulator of that AVD is running and never when `CI` is set; `warden golden ensure --platform android --profile <slug>` builds it now.

The build boots your AVD writable once: warden cold-boots it headless with `-no-snapshot-load -no-snapshot-save` (your `default_boot` is neither loaded nor overwritten), waits for `sys.boot_completed` plus a short settle, runs `adb emu avd snapshot save warden-<key>` and stops it (`emu kill`, then SIGKILL after a minute). That first boot does write first-boot state into the AVD's userdata, as an Android Studio run would, and the snapshot lands in the AVD's `snapshots/` folder (about the AVD's RAM in disk). While it runs, Android Studio cannot start that AVD. To keep warden from ever booting your AVD writable, turn snapshots off with `android: { snapshot: false }` in `warden.config.ts` or `WARDEN_ANDROID_SNAPSHOT=0` (`0/1/true/false/on/off/yes/no`; `=1` overrides the config, any other value is warned about and ignored).

The key covers the system image revision and build fingerprint, the emulator version, the AVD's `hw.*` and guest-shaping settings (data partition, ABI, tag, Play Store, SD card), the headless launch flags and a recipe number, so an emulator or image update builds a new snapshot and `warden golden prune --platform android` (or the next build) deletes the stale one. A snapshot a claim's emulator logs as failing to load is deleted, so the next build replaces it; a launch from the snapshot that fails is retried once as a cold boot. It needs `ANDROID_HOME` (or `ANDROID_SDK_ROOT`; warden says so once when neither is set). Claimed emulators also run `-no-audio -no-metrics` (an emulator that rejects them is relaunched without); `WARDEN_EMULATOR_AUDIO=1` keeps audio. `warden golden ensure|ls|prune --platform android` builds, lists and prunes the snapshots.

## Cloning your own sim [#cloning-your-own-sim]

`warden clone <udid|name> [--name x]` duplicates any **shut-down** sim — e.g. one you've set up by hand — into warden's pool. warden refuses a booted source rather than shutting it down.
