> ## Documentation Index
> Fetch the complete documentation index at: https://docs.ns.rocks/llms.txt
> Use this file to discover all available pages before exploring further.

# Machine Lifecycle

> Understand create, exec, hibernate, resume, fork, and destroy.

Nullspace machines move through explicit states instead of hiding lifecycle
behind sessions. Use the state table when deciding whether to destroy,
hibernate, resume, snapshot, or fork.

```mermaid theme={"theme":{"light":"one-light","dark":"one-dark-pro"}}
flowchart LR
  Create --> Running
  Running --> Exec
  Exec --> Running
  Running --> Hibernate
  Hibernate --> Paused
  Paused --> Resume
  Resume --> Running
  Running --> Snapshot
  Snapshot --> Running
  Running --> Fork
  Fork --> Running
  Running --> Destroy
  Paused --> Destroy
```

## State Semantics

| State or operation | Memory                                              | Mutable rootfs and files                                        | Processes                                                                     | Volumes                                                                               | Runtime resources                                              |
| ------------------ | --------------------------------------------------- | --------------------------------------------------------------- | ----------------------------------------------------------------------------- | ------------------------------------------------------------------------------------- | -------------------------------------------------------------- |
| Creating           | Booting from template or snapshot.                  | Materializing template/rootfs state.                            | Start commands may run before ready.                                          | Mount intents are resolved before ready.                                              | Counts against create capacity while placement is in progress. |
| Running            | Live guest memory.                                  | File changes are immediately visible inside the machine.        | Commands, services, PTY, desktop, and agents can run.                         | Mounted volumes are live external storage.                                            | CPU, memory, disk, and routing resources are allocated.        |
| Exec               | Same live memory as the running machine.            | Command side effects persist in the running machine.            | Foreground commands return output; background commands keep a PID.            | Commands can read/write mounted volumes.                                              | Uses the running machine resources.                            |
| Hibernate / pause  | Captured into a pause/resume snapshot.              | Mutable rootfs state is captured with the paused machine state. | Live processes stop with the VM and resume with memory state when compatible. | Mount leases are released; attachment intent remains durable and remounts on resume.  | Running VM resources are released after hibernate succeeds.    |
| Paused             | Stored in snapshot artifacts.                       | Stored with the paused machine metadata and artifacts.          | Not running while paused.                                                     | External volume data remains in the volume backend.                                   | No running VM; storage artifacts remain.                       |
| Resume             | Restored lazily from paused memory state.           | Restored with the paused machine.                               | Processes continue from captured VM state when the restore is compatible.     | Volumes remount with fresh internal leases before ready.                              | Allocates a new running machine execution.                     |
| Reusable snapshot  | Captures a baseline while the source keeps running. | Captured as a reusable 1-to-many baseline.                      | Snapshot children start from captured state; source keeps running.            | Volume data remains external; snapshot stores attachment intent, not volume contents. | Snapshot artifacts are stored for future creates.              |
| Fork               | Branches a running machine into a child.            | Parent and child start from the same warm state, then diverge.  | Parent and child continue independently.                                      | Shared external volumes remain shared unless mounted read-only or separated by path.  | Allocates a second running machine.                            |
| Destroy            | Memory is discarded.                                | Machine-local mutable state is discarded.                       | Processes stop.                                                               | External volumes are not deleted.                                                     | Runtime resources are released.                                |
| Error              | State depends on the failing transition.            | Inspect lifecycle events and error envelope.                    | May be unavailable.                                                           | Existing external volume data is not deleted by a machine error.                      | Cleanup or recovery depends on error type.                     |

## Timeout And Auto-Resume

`timeout_ms` controls when the reaper acts on an idle or long-running machine.
The default timeout action is destroy. Use `on_timeout="pause"` or
`lifecycle.on_timeout: "pause"` when the machine should hibernate instead.

`auto_resume=True` lets SDK calls, command/file/PTY/desktop routes, or public
traffic targeting the original machine ID wake a hibernated machine. Preview URL
traffic waits for resume and then forwards the original request when the
runtime is ready.

## Create And Exec

<CodeGroup>
  ```python Python SDK theme={"theme":{"light":"one-light","dark":"one-dark-pro"}}
  from nullspace import Machine

  with Machine.create(template="base") as machine:
      result = machine.commands.run("uname -a", shell=True)
      print(result.stdout)
  ```

  ```typescript TypeScript SDK theme={"theme":{"light":"one-light","dark":"one-dark-pro"}}
  import { Machine } from "nullspace";

  await using machine = await Machine.create({ template: "base" });
  const result = await machine.commands.run("uname -a", { shell: true });
  console.log(result.stdout);
  ```

  ```bash CLI theme={"theme":{"light":"one-light","dark":"one-dark-pro"}}
  nullspace machine create --template base
  nullspace machine exec mch_123 --shell "uname -a"
  ```

  ```bash HTTP API theme={"theme":{"light":"one-light","dark":"one-dark-pro"}}
  curl -X POST "${NULLSPACE_API_URL}/v1/machines" \
    -H "Authorization: Bearer ${NULLSPACE_API_KEY}" \
    -H "Content-Type: application/json" \
    -d '{"template": "base"}'

  curl -X POST "${NULLSPACE_API_URL}/v1/machines/mch_123/exec" \
    -H "Authorization: Bearer ${NULLSPACE_API_KEY}" \
    -H "Content-Type: application/json" \
    -d '{"command": "uname -a", "shell": true}'
  ```
</CodeGroup>

## Hibernate And Resume

<CodeGroup>
  ```python Python SDK theme={"theme":{"light":"one-light","dark":"one-dark-pro"}}
  machine = Machine.create(template="base")
  machine.files.write("/workspace/state.txt", "kept across pause\n")
  snapshot = machine.hibernate()

  resumed = Machine.resume(snapshot.id)
  print(resumed.files.read("/workspace/state.txt"))
  resumed.kill()
  ```

  ```typescript TypeScript SDK theme={"theme":{"light":"one-light","dark":"one-dark-pro"}}
  import { NullspaceClient } from "nullspace";

  const client = new NullspaceClient();
  const machine = await client.machines.create({ template: "base" });
  await machine.files.write("/workspace/state.txt", "kept across pause\n");
  const snapshot = await machine.hibernate();

  const resumed = await client.snapshots.resume(snapshot.id);
  console.log(await resumed.files.read("/workspace/state.txt"));
  await resumed.destroy();
  ```

  ```bash CLI theme={"theme":{"light":"one-light","dark":"one-dark-pro"}}
  nullspace machine hibernate mch_123   # returns the pause snapshot id
  nullspace machine resume snap_123
  ```

  ```bash HTTP API theme={"theme":{"light":"one-light","dark":"one-dark-pro"}}
  curl -X POST "${NULLSPACE_API_URL}/v1/machines/mch_123/hibernate" \
    -H "Authorization: Bearer ${NULLSPACE_API_KEY}"

  curl -X POST "${NULLSPACE_API_URL}/v1/machines/snap_123/resume" \
    -H "Authorization: Bearer ${NULLSPACE_API_KEY}"
  ```
</CodeGroup>

`pause()` is an alias for `hibernate()`.

## Reusable Snapshots

<CodeGroup>
  ```python Python SDK theme={"theme":{"light":"one-light","dark":"one-dark-pro"}}
  source = Machine.create(template="base")
  source.files.write("/workspace/state.txt", "baseline\n")
  snapshot = source.create_snapshot()

  child = Machine.create(snapshot_id=snapshot.id)
  child.kill()
  source.kill()
  ```

  ```typescript TypeScript SDK theme={"theme":{"light":"one-light","dark":"one-dark-pro"}}
  const source = await Machine.create({ template: "base" });
  await source.files.write("/workspace/state.txt", "baseline\n");
  const snapshot = await source.createSnapshot();

  const child = await Machine.create({ snapshotId: snapshot.id });
  await child.destroy();
  await source.destroy();
  ```

  ```bash CLI theme={"theme":{"light":"one-light","dark":"one-dark-pro"}}
  nullspace snapshot create mch_123   # returns a reusable snapshot id
  nullspace machine create --snapshot-id snap_123
  ```

  ```bash HTTP API theme={"theme":{"light":"one-light","dark":"one-dark-pro"}}
  curl -X POST "${NULLSPACE_API_URL}/v1/machines/mch_123/snapshots" \
    -H "Authorization: Bearer ${NULLSPACE_API_KEY}"

  curl -X POST "${NULLSPACE_API_URL}/v1/machines" \
    -H "Authorization: Bearer ${NULLSPACE_API_KEY}" \
    -H "Content-Type: application/json" \
    -d '{"snapshot_id": "snap_123"}'
  ```
</CodeGroup>

Reusable snapshots keep the source machine running and can start many
independent children with `Machine.create(snapshot_id=...)`.

## Fork

<CodeGroup>
  ```python Python SDK theme={"theme":{"light":"one-light","dark":"one-dark-pro"}}
  parent = Machine.create(template="base")
  parent.files.write("/workspace/state.txt", "common\n")

  child = parent.fork()
  parent.files.write("/workspace/state.txt", "parent\n")
  child.files.write("/workspace/state.txt", "child\n")

  parent.kill()
  child.kill()
  ```

  ```typescript TypeScript SDK theme={"theme":{"light":"one-light","dark":"one-dark-pro"}}
  const parent = await Machine.create({ template: "base" });
  await parent.files.write("/workspace/state.txt", "common\n");

  const child = await parent.fork();
  await parent.files.write("/workspace/state.txt", "parent\n");
  await child.files.write("/workspace/state.txt", "child\n");

  await parent.destroy();
  await child.destroy();
  ```

  ```bash CLI theme={"theme":{"light":"one-light","dark":"one-dark-pro"}}
  nullspace machine fork mch_123
  ```

  ```bash HTTP API theme={"theme":{"light":"one-light","dark":"one-dark-pro"}}
  curl -X POST "${NULLSPACE_API_URL}/v1/machines/mch_123/fork" \
    -H "Authorization: Bearer ${NULLSPACE_API_KEY}"
  ```
</CodeGroup>

## Destroy

Destroy releases runtime resources. It does not delete external durable data,
such as shared volume contents.

<CodeGroup>
  ```python Python SDK theme={"theme":{"light":"one-light","dark":"one-dark-pro"}}
  machine.kill()
  ```

  ```typescript TypeScript SDK theme={"theme":{"light":"one-light","dark":"one-dark-pro"}}
  await machine.destroy();
  ```

  ```bash CLI theme={"theme":{"light":"one-light","dark":"one-dark-pro"}}
  nullspace machine kill mch_123
  ```

  ```bash HTTP API theme={"theme":{"light":"one-light","dark":"one-dark-pro"}}
  curl -X DELETE "${NULLSPACE_API_URL}/v1/machines/mch_123" \
    -H "Authorization: Bearer ${NULLSPACE_API_KEY}"
  ```
</CodeGroup>

## Related

* [Persistence](./persistence)
* [Snapshots](./snapshots)
* [Fork](./fork)
* [Lifecycle events](../observability/lifecycle-events)
* [Hosted endpoints](../reference/hosted-endpoints)
