> ## 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.

# Persistence

> Pause machines, resume paused state, and keep long-running sessions cheap.

Nullspace persistence is built around hibernate and resume. Hibernate stops the
active VM and records a paused-machine snapshot; resume restores that state into
a runnable machine. This is separate from reusable snapshots, which keep the
source machine running and can be used as a 1-to-many starting point.

## Pause a machine

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

  machine = Machine.create(template="base")
  machine.files.write("/workspace/report.txt", "draft\n")
  snapshot = machine.pause()
  print(snapshot.id)
  ```

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

  const machine = await Machine.create({ template: "base" });
  await machine.files.write("/workspace/report.txt", "draft\n");
  const snapshot = await machine.pause();
  console.log(snapshot.id);
  ```

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

  ```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}"
  ```
</CodeGroup>

## Resume paused state

<CodeGroup>
  ```python Python SDK theme={"theme":{"light":"one-light","dark":"one-dark-pro"}}
  resumed = Machine.resume(snapshot.id)
  print(resumed.files.read("/workspace/report.txt"))
  resumed.kill()
  ```

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

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

  ```bash CLI theme={"theme":{"light":"one-light","dark":"one-dark-pro"}}
  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/snap_123/resume" \
    -H "Authorization: Bearer ${NULLSPACE_API_KEY}"
  ```
</CodeGroup>

Resume creates a new running machine ID. If the original machine paused because
of timeout behavior, the original ID can remain as a paused alias so
`Machine.connect(original_id)` and public auto-resume traffic can find the
latest running execution.

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

  resumed = Machine.connect(original_id)
  print(original_id, resumed.id)
  ```

  ```typescript TypeScript SDK theme={"theme":{"light":"one-light","dark":"one-dark-pro"}}
  const originalId = machine.id;
  const snapshot = await machine.pause();

  const resumed = await Machine.connect(originalId);
  console.log(originalId, resumed.id);
  ```

  ```bash CLI theme={"theme":{"light":"one-light","dark":"one-dark-pro"}}
  nullspace machine pause mch_123
  nullspace machine get mch_123   # the original id resolves to the latest execution
  ```

  ```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 "${NULLSPACE_API_URL}/v1/machines/mch_123" \
    -H "Authorization: Bearer ${NULLSPACE_API_KEY}"
  ```
</CodeGroup>

## Reusable snapshots

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

  child_a = Machine.create(snapshot_id=snapshot.id)
  child_b = Machine.create(snapshot_id=snapshot.id)

  child_a.kill()
  child_b.kill()
  ```

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

  const childA = await Machine.create({ snapshotId: snapshot.id });
  const childB = await Machine.create({ snapshotId: snapshot.id });

  await childA.destroy();
  await childB.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
  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>

`create_snapshot()` briefly pauses the source, captures memory and mutable
rootfs state, resumes the source, and returns a reusable snapshot ID. Use
`Machine.create(snapshot_id=...)` to spawn independent children from it.

## Behavior

* VM memory and mutable rootfs state come from hibernate or reusable snapshots.
* Shared volumes are remounted as external storage during resume and fork.
* Snapshot compatibility depends on runtime host and kernel compatibility;
  incompatible restores fail explicitly instead of silently starting from
  scratch.
* `Machine.get_info_by_id(id)` is read-only and does not wake a paused alias.
* Deleting a paused original ID removes the paused alias and its lifecycle
  routing target.
* Use lifecycle events to observe transition state and recovery failures.

## Auto-resume

Create with `on_timeout="pause", auto_resume=True` when a public HTTP or
WebSocket request should wake a paused machine before the request is forwarded.
When the wake cannot complete in time, callers get `503 Service Unavailable`
with `Retry-After: 5`.

## Related

* [Snapshots](./snapshots)
* [Auto-resume](./auto-resume)
* [Fork](./fork)
* [Lifecycle events](../observability/lifecycle-events)
* [Volumes](../volumes/overview)
