# Machines

https://instabox.sh/docs/machines.md

Lifecycle, sizes, auto-pause, logs, labels and secrets.

### Lifecycle
- Every change is an **operation**, and a machine has at most one at a time. The dashboard shows them in the operations tray.
- **Resume** brings back a paused machine's memory and processes. If that is not possible it starts fresh: files are kept, processes are not.
- A paused machine cannot be stopped: resume or delete it.
- **Restart** (`instabox restart <machine>`, or `recover`) power-cycles a machine that stopped answering: stop, then start. The root disk and `/data` are kept; processes and memory are not. Stop asks the guest to power off, then sends Ctrl+Alt+Del, and kills the VM once the timeout runs out (60 seconds, or `--timeout` up to 10 minutes), so a hung guest comes back too; writes it had not flushed can be lost. A machine stuck in `starting` with no start in progress cannot be power-cycled.
- **Restore** (`instabox restore <machine> --snapshot <snapshot>`, `POST /v1/machines/{id}/restore`) puts a machine's disks back to a snapshot's, in place: it keeps its ID, name, hostname, public port URLs and ssh-config block, and everything on its root disk and `/data` since the snapshot is gone, running programs included. A running machine is stopped first; the restored machine then boots (`--stopped` leaves it stopped). Its SSH host keys are new afterwards. See [Snapshots](https://instabox.sh/docs/snapshots.md).
- A reboot from inside (`sudo reboot`, `systemctl reboot`, `shutdown -r`) reboots the machine: it shows Starting, then Running again on the same disks, with new processes. A shutdown from inside (`sudo poweroff`, `halt`, `shutdown -h`) stops it until a start. Machines created from a template older than this change stop on a reboot too; a machine that reboots more than 5 times in 10 minutes is left stopped.
- The dashboard's states: Creating, Starting, Running, Stopping, Stopped, Pausing, Paused, Resuming, Deleting, Failed.

### Retention, archive and storage sync
- **No forced TTL.** A paused or stopped machine and every snapshot you save stay until **you** delete them. There is no automatic 7- or 14-day purge of stopped sandboxes. The one exception is the workspace itself: a workspace **disabled** (its subscription cancelled, or unpaid past the grace period) keeps its machines and snapshots for 30 days, then they are deleted; a workspace you **delete** has them deleted right away, with no recovery window. Storage still counts toward plan limits and billing ([Pricing](https://instabox.sh/docs/pricing.md)): Free caps stored bytes; Pro and Team bill GiB-hours beyond the monthly credit.
- **Archive deadline.** At create, `archiveSeconds` (SDK `archiveMs`, 60–86400 s) sets `archiveAt = now + that`. When `archiveAt` is reached the server **stops** the machine if it is running; disks stay in object storage and a later **start** brings it back. Resume does not clear `archiveAt`, but the deadline is one-shot: once it passes, running or not, it is cleared, so a machine that was already paused or stopped at that moment is not archived on a later start. Omit the field (or send 0) for none. This is optional; it is not a default retention policy.
- **Delete deadline.** At create, `deleteAfterSeconds` (`deleteAt` on the machine) sets when the server **deletes** the machine in any state (`instabox run --timeout` sets both this and `archiveSeconds` from its timeout). Omit for never.
- **Storage sync.** On `GET /v1/machines/{id}`, `storage.synced` is `false` for a short window after stop or suspend while the newest disk state exists only on the host and is still uploading (often tens of seconds, sometimes a couple of minutes). Until it is `true`, a start may only place on that same host. Agents waiting on a clean handoff should poll until `synced` is true.
- **Region.** A machine has no `region` field in the API, and create does not take one: a `region` in the body is refused as `400 unknown_field` (create rejects fields it does not know). Placement is the platform's.
- **Wake vs manual pause.** Idle auto-pause wakes on use (exec, SSH, public URL, `instabox wake`). A pause or stop you requested does not: call resume or start. CLI commands that need a running sandbox (`ssh`, `exec`, `cp`, `ps`, `ssh-token`, …) and the SSH gateway say `instabox resume` for a paused one and `instabox start` for a stopped one.

### Sizes
A machine is 4 vCPUs and 8 GiB of memory unless the create names another size of your plan, with both the vCPUs and the memory in MiB:

| Plan | Sizes (vCPUs / MiB) |
|---|---|
| Free | 4 / 8192 |
| Pro | 2 / 4096, 4 / 8192 (default), 8 / 16384 |
| Team | 2 / 4096, 4 / 8192 (default) up to 32 / 65536 |

`GET /v1/orgs` (`instabox workspace ls --json`) lists each workspace's as `allowedSpecs`. Another size is `400 spec_not_allowed`. A paid machine moves to another size of its plan while stopped (`PATCH /v1/machines/{id}` `{"vcpus": N, "memMiB": M}`, `instabox resize --vcpus N --mem-mib M`), applied at its next start (which fails with `no_capacity` if the host has no room for the new size, or `host_unavailable` if its node-agent cannot resize yet; the machine stays stopped at the new size); a free machine's size is fixed.
```
instabox create --name big --vcpus 8 --mem-mib 16384
instabox create --name job --template universal@2026-10-15.4   # or --template-version
```
Over the API these are `vcpus`, `memMiB` and `templateVersion` on [Create a machine](https://instabox.sh/docs/api/machines.md#create).

### Auto-pause
A running machine pauses once it has been idle for 30 minutes. On a paid plan (Pro, Team, Enterprise) you choose 5, 10, 15, 20, 25 or 30 minutes (a time between rounds up to the next; below 5 or above 30 minutes is refused), or `0` to turn it off. On the free plan it is fixed at 30 minutes, and another value is refused. Commands, files, SSH and a visit to a public port URL resume an **idle** pause by themselves. A **manual** pause or stop does not wake from a URL: use `instabox resume` (pause) or `instabox start` (stop).
```
instabox auto-suspend job 10m   # pause after 10 idle minutes
instabox auto-suspend job 0     # never pause when idle
```

### Logs
`instabox logs` prints a machine's console log and its last 20 operations (create, start, stop, pause, resume, with their errors). The console log is the serial console: kernel and systemd boot messages, anything written to /dev/console, and errors from the VM monitor. It is kept on the host across stops, pauses and restarts (the last 8 MiB). Reading it works in every state and never wakes the machine, so use it when a machine does not boot, is unreachable, or a start or resume failed.
```
instabox logs job                 # the last 200 console lines and the operations
instabox logs job --tail 50 -f    # follow new output (Ctrl-C stops)
instabox logs job --json          # GET /v1/machines/{id}/logs
```
Over the API, `GET /v1/machines/{id}/logs?tail=N` (scope `machines:read`) returns `console`, `cursor`, `state` and `operations` (oldest first). To follow it, pass `cursor` as `after` on the next request to get only newer output. When the console cannot be read, for example because the machine's disks are in storage, the response is still 200, with `consoleUnavailable` and the operations. A command's own output is kept with its background job, and the full guest journal is read over exec:
```
instabox jobs logs job <job-id>
instabox exec job -- sudo journalctl -b --no-pager   # this boot
```

### Labels
Up to 32 `key=value` labels (metadata) per machine. They are stored in plain text: use them for labels, not secrets.
```
instabox create --name job --meta task=review
instabox ls --meta task=review     # GET /v1/machines?metadata=task:review
```

### Secrets
Use [Org Secrets](https://instabox.sh/docs/secrets.md) for named credentials shared within an org. A sandbox sees placeholders, and the outbound proxy adds the credentials to HTTPS headers sent to each Secret's allowed hosts. Manage values and sandbox selections in the dashboard's Secrets page, the CLI or the API.

### Vault
The per-user Vault continues to support environment variables, home files and metadata selectors alongside Org Secrets. Upgrading does not migrate items or enroll existing sandboxes in Secrets. Manage Vault items with `instabox vault set`, `set-file`, `import`, `ls`, `rm`, `show` and `push`. See [Secrets](https://instabox.sh/docs/secrets.md) for explicit org-owned credentials.
