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

# Snapshots

> Create and restore sandbox snapshots with the Rust SDK.

<Tooltip tip="Cloud supports disk capture from stopped persistent sandboxes, lookup, listing, removal, and restore. Live capture, full snapshots, groups, archives, verification, and compaction are local-only."><span className="msb-badge-limited">Limited on cloud <Icon icon="circle-info" size={11} /></span></Tooltip>

See the [snapshot guide](/sandboxes/snapshots) for workflows and examples.

Use snapshot objects or references on cloud. Local operations also accept a group head, `group:member`, or artifact path.

## Guest writeback

Use `.guest_flush(GuestFlush::Required)` on snapshot, fork, or fork-many builders, or `source.pause_with_guest_flush(GuestFlush::Required)`. Import `GuestFlush` from `microsandbox::snapshot`. The default `Auto` flushes live disk-only captures, but adds no optional flush to full captures, forks, or pause. `Skip` retains mandatory storage barriers. A paused disk capture needs a matching prior flush; cloud rejects non-Auto policies. See [guest flush policy reference](/sandboxes/snapshots#guest-flushing).

## Static methods

#### <span className="msb-recv">Snapshot::</span><span className="msb-hn">builder()</span>

```rust theme={null}
fn builder(name: impl Into<String>) -> SnapshotBuilder
```

Configure a snapshot. Set the required source with `from_sandbox()`; see [SnapshotBuilder](#snapshotbuilder) for options.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>name</code><span className="msb-type">impl Into\<String></span></div>
    <div className="msb-param-desc">Member name; generated when empty. Names must not contain path separators or start with <code>.</code>.</div>
  </div>
</div>

<p className="msb-label">Returns</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><a className="msb-type" href="#snapshotbuilder">SnapshotBuilder</a></div>
    <div className="msb-param-desc">Builder for configuring the snapshot.</div>
  </div>
</div>

<Accordion title="Example">
  ```rust theme={null}
  let snap = Snapshot::builder("baseline")
      .from_sandbox("api")
      .create()
      .await?;
  ```
</Accordion>

***

#### <span className="msb-recv">Snapshot::</span><span className="msb-hn">create()</span>

```rust theme={null}
async fn create(config: SnapshotConfig) -> MicrosandboxResult<Snapshot>
```

Create an installed snapshot artifact atomically, then best-effort update the rebuildable local index. Locally, disk mode supports running, paused, stopped, and crashed sources; full mode includes memory and execution state from a running or paused source. Cloud supports only disk capture from a stopped persistent source. Most callers use the [builder](#snapshotbuilder)'s [`create()`](#create) instead of constructing a [`SnapshotConfig`](#snapshotconfig) by hand.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>config</code><a className="msb-type" href="#snapshotconfig">SnapshotConfig</a></div>
    <div className="msb-param-desc">Name, source sandbox, labels, and integrity flag.</div>
  </div>
</div>

<p className="msb-label">Returns</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><a className="msb-type" href="#instance-methods">Snapshot</a></div>
    <div className="msb-param-desc">The created artifact handle.</div>
  </div>
</div>

<Accordion title="Example">
  ```rust theme={null}
  let snap = Snapshot::create(
      Snapshot::builder("baseline").from_sandbox("api").build()?
  ).await?;
  ```
</Accordion>

***

#### <span className="msb-recv">Snapshot::</span><span className="msb-hn">create\_archive()</span>

```rust theme={null}
async fn create_archive(
    config: SnapshotConfig,
    out: impl AsRef<Path>,
    plain_tar: bool,
) -> MicrosandboxResult<SnapshotArchive>
```

Capture a disk or full snapshot directly into an archive without installing it locally.

<Accordion title="Example">
  ```rust theme={null}
  let archive = Snapshot::create_archive(
      Snapshot::builder("baseline").from_sandbox("api").build()?,
      "/tmp/baseline.msb",
      false,
  ).await?;
  println!("{} {}", archive.id(), archive.path().display());
  ```
</Accordion>

***

#### <span className="msb-recv">Snapshot::</span><span className="msb-hn">open()</span>

```rust theme={null}
async fn open(path_or_name: impl AsRef<str>) -> MicrosandboxResult<Snapshot>
```

<Accordion title="Example">
  ```rust theme={null}
  let snap = Snapshot::open("api:baseline").await?;
  println!("{}", snap.manifest().image.reference);
  ```
</Accordion>

Open an existing artifact by group head, `group:member`, or path. This is a fast metadata operation: it verifies the manifest structure, recomputes the manifest digest, and checks that the upper file exists with the recorded size. It does **not** read the full upper contents; use [`verify()`](#snap-verify) for that.

For the local backend, relative artifact paths are resolved when the operation begins, and the returned snapshot retains that absolute location. Changing the process working directory later does not retarget an opened or listed snapshot. Local import, export, copy, and capture destinations are also resolved before asynchronous work starts. Group names and snapshot IDs continue to resolve through the snapshot store.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>path\_or\_name</code><span className="msb-type">impl AsRef\<str></span></div>
    <div className="msb-param-desc">Group head, <code>group:member</code>, or filesystem path to an artifact directory.</div>
  </div>
</div>

<p className="msb-label">Returns</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><a className="msb-type" href="#instance-methods">Snapshot</a></div>
    <div className="msb-param-desc">The opened artifact handle.</div>
  </div>
</div>

#### <span className="msb-recv">Snapshot::</span><span className="msb-hn">open\_ref()</span>

```rust theme={null}
async fn open_ref(reference: impl Into<SnapshotReference>) -> MicrosandboxResult<Snapshot>
```

Open a snapshot from an explicit [`SnapshotReference`](#snapshotreference).
Use this when passing through a reference returned by another SDK operation;
it preserves whether the backend should resolve the value as an identifier or
a path.

<Accordion title="Example">
  ```rust theme={null}
  let snap = Snapshot::open_ref(SnapshotReference::Id(snapshot_id)).await?;
  ```
</Accordion>

#### <span className="msb-recv">Snapshot::</span><span className="msb-hn">get()</span>

```rust theme={null}
async fn get(name_or_digest: &str) -> MicrosandboxResult<SnapshotHandle>
```

<Accordion title="Example">
  ```rust theme={null}
  let h = Snapshot::get("api:baseline").await?;
  println!("{} from {}", h.digest(), h.image_ref());
  ```
</Accordion>

Look up a lightweight [`SnapshotHandle`](#snapshothandle) by group head, `group:member`, stable snapshot ID, descriptor digest, or artifact path. Global IDs and digests must resolve unambiguously.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>name\_or\_digest</code><span className="msb-type">\&str</span></div>
    <div className="msb-param-desc">Group head, <code>group:member</code>, stable snapshot ID, descriptor digest, or artifact path.</div>
  </div>
</div>

<p className="msb-label">Returns</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><a className="msb-type" href="#snapshothandle">SnapshotHandle</a></div>
    <div className="msb-param-desc">Handle backed by the matching index row.</div>
  </div>
</div>

#### <span className="msb-recv">Snapshot::</span><span className="msb-hn">list()</span>

```rust theme={null}
async fn list() -> MicrosandboxResult<Vec<SnapshotHandle>>
```

<Accordion title="Example">
  ```rust theme={null}
  for h in Snapshot::list().await? {
      println!("{:?} - {}", h.name(), h.digest());
  }
  ```
</Accordion>

List snapshots from the active backend. Locally this uses the local index;
in cloud it paginates through managed snapshots. Host-volume artifacts are not
included automatically.

<p className="msb-label">Returns</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><a className="msb-type" href="#snapshothandle">Vec\<SnapshotHandle></a></div>
    <div className="msb-param-desc">Indexed snapshot handles, ordered by creation time descending.</div>
  </div>
</div>

#### <span className="msb-recv">Snapshot::</span><span className="msb-hn">list\_dir()</span>

```rust theme={null}
async fn list_dir(dir: impl AsRef<Path>) -> MicrosandboxResult<Vec<Snapshot>>
```

Walk a directory and parse each subdirectory's manifest. Does not touch the index. Skips entries that don't look like snapshot artifacts (no `snapshot.json`) and malformed artifacts.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>dir</code><span className="msb-type">impl AsRef\<Path></span></div>
    <div className="msb-param-desc">Directory to scan for artifacts.</div>
  </div>
</div>

<p className="msb-label">Returns</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><a className="msb-type" href="#instance-methods">Vec\<Snapshot></a></div>
    <div className="msb-param-desc">One handle per valid artifact found.</div>
  </div>
</div>

#### <span className="msb-recv">Snapshot::</span><span className="msb-hn">remove()</span>

```rust theme={null}
async fn remove(path_or_name: &str, force: bool) -> MicrosandboxResult<()>
```

<Accordion title="Example">
  ```rust theme={null}
  Snapshot::remove("api:baseline", false).await?;
  ```
</Accordion>

Remove a snapshot artifact by group selector, unambiguous ID or digest, or path, along with its index row. Refuses if the snapshot has indexed children unless `force` is set. A group's head cannot be removed while other members remain, even with `force`; select another head first.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>path\_or\_name</code><span className="msb-type">\&str</span></div>
    <div className="msb-param-desc">Group head, <code>group:member</code>, unambiguous snapshot ID or digest, or artifact path.</div>
  </div>

  <div className="msb-param">
    <div className="msb-param-key"><code>force</code><span className="msb-type">bool</span></div>
    <div className="msb-param-desc">When <code>true</code>, remove even if the snapshot has indexed children.</div>
  </div>
</div>

#### <span className="msb-recv">Snapshot::</span><span className="msb-hn">remove\_ref()</span>

```rust theme={null}
async fn remove_ref(
    reference: impl Into<SnapshotReference>,
    force: bool,
) -> MicrosandboxResult<()>
```

Remove a snapshot using an explicit backend-neutral reference. Prefer this
over [`remove()`](#snapshotremove) when the value came from
`Snapshot::reference()` or `SnapshotHandle::reference()`.

#### <span className="msb-recv">Snapshot::</span><span className="msb-hn">reindex()</span>

```rust theme={null}
async fn reindex(dir: impl AsRef<Path>) -> MicrosandboxResult<usize>
```

Rebuild the local snapshot index from artifacts in `dir`.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>dir</code><span className="msb-type">impl AsRef\<Path></span></div>
    <div className="msb-param-desc">Directory of artifacts to index.</div>
  </div>
</div>

<p className="msb-label">Returns</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><span className="msb-type">usize</span></div>
    <div className="msb-param-desc">Number of artifacts indexed.</div>
  </div>
</div>

<Accordion title="Example">
  ```rust theme={null}
  let n = Snapshot::reindex("/data/snapshots").await?;
  println!("indexed {n} snapshots");
  ```
</Accordion>

#### <span className="msb-recv">Snapshot::</span><span className="msb-hn">reindex\_default()</span>

```rust theme={null}
async fn reindex_default() -> MicrosandboxResult<usize>
```

Rebuild the local snapshot index from the configured default snapshot
directory. This is equivalent to [`reindex()`](#snapshotreindex) with the
local backend's configured store and returns `MicrosandboxError::Unsupported`
on backends without a rebuildable artifact index.

***

#### <span className="msb-recv">Snapshot::</span><span className="msb-hn">save()</span>

<div className="msb-tags"><span className="msb-tag is-static">static</span><span className="msb-tag is-async">async</span></div>

```rust theme={null}
async fn save(name_or_path: &str, out: &Path, opts: SaveOpts) -> MicrosandboxResult<()>
```

Bundle a snapshot into a `.msb` archive (or plain `.tar`) at `out`. Recorded payload integrity is preserved but not executed implicitly; call [`verify()`](#snap-verify) when an independent content scan is part of your workflow. See [`SaveOpts`](#saveopts) to also include ancestors and the OCI image cache.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>name\_or\_path</code><span className="msb-type">\&str</span></div>
    <div className="msb-param-desc">Group head, <code>group:member</code>, or artifact path to save.</div>
  </div>

  <div className="msb-param">
    <div className="msb-param-key"><code>out</code><span className="msb-type">\&Path</span></div>
    <div className="msb-param-desc">Output archive path. Parent directories are created if missing.</div>
  </div>

  <div className="msb-param">
    <div className="msb-param-key"><code>opts</code><a className="msb-type" href="#saveopts">SaveOpts</a></div>
    <div className="msb-param-desc">Bundling options. <code>SaveOpts::default()</code> writes the head snapshot only, zstd-compressed.</div>
  </div>
</div>

<Accordion title="Example">
  ```rust theme={null}
  use microsandbox::snapshot::SaveOpts;
  use std::path::Path;

  Snapshot::save(
      "api:baseline",
      Path::new("/tmp/baseline.msb"),
      SaveOpts { with_parents: true, with_image: true, ..Default::default() },
  ).await?;
  ```
</Accordion>

***

#### <span className="msb-recv">Snapshot::</span><span className="msb-hn">load()</span>

<div className="msb-tags"><span className="msb-tag is-static">static</span><span className="msb-tag is-async">async</span></div>

```rust theme={null}
async fn load(archive_path: &Path, dest: Option<&Path>) -> MicrosandboxResult<SnapshotHandle>
```

<Accordion title="Example">
  ```rust theme={null}
  use std::path::Path;

  let h = Snapshot::load(Path::new("/tmp/baseline.msb"), None).await?;
  println!("loaded {}", h.digest());
  ```
</Accordion>

Unpack a snapshot archive (`.msb` or `.tar`, detected from magic bytes) into the snapshots directory (or `dest`), routing any bundled image-cache entries into the global cache and registering everything found in the index. Structural and archive-entry checks remain mandatory, while recorded payload integrity is preserved for explicit [`verify()`](#snap-verify). Returns a handle for the head snapshot.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>archive\_path</code><span className="msb-type">\&Path</span></div>
    <div className="msb-param-desc">Archive to unpack.</div>
  </div>

  <div className="msb-param">
    <div className="msb-param-key"><code>dest</code><span className="msb-type">Option\<\&Path></span></div>
    <div className="msb-param-desc">Destination directory. <code>None</code> uses the default snapshots directory.</div>
  </div>
</div>

<p className="msb-label">Returns</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><a className="msb-type" href="#snapshothandle">SnapshotHandle</a></div>
    <div className="msb-param-desc">Handle for the archive-declared head snapshot, which may differ from the receiving group's selected head.</div>
  </div>
</div>

<Accordion title="Example">
  ```rust theme={null}
  use std::path::Path;

  let h = Snapshot::load(Path::new("/tmp/baseline.msb"), None).await?;
  println!("loaded {}", h.digest());
  ```
</Accordion>

***

<p className="msb-member-group" id="instance-methods">Instance methods</p>

Methods on an opened [`Snapshot`](#snapshotopen) artifact.

#### <span className="msb-recv">Snapshot::</span><span className="msb-hn">load\_with\_base()</span>

```rust theme={null}
async fn load_with_base(
    path: &Path,
    dest: Option<&Path>,
    base: &str,
) -> MicrosandboxResult<SnapshotHandle>
```

Import an archive with an explicit dependency base or destination group. See [import options](#import-options).

#### <span className="msb-recv">Snapshot::</span><span className="msb-hn">load\_with\_options()</span>

```rust theme={null}
async fn load_with_options(
    path: &Path,
    opts: LoadOpts,
) -> MicrosandboxResult<SnapshotHandle>
```

Import an archive with an explicit dependency base or destination group. See [import options](#import-options).

#### <span className="msb-recv">Snapshot::</span><span className="msb-hn">load\_many()</span>

```rust theme={null}
async fn load_many(
    paths: &[PathBuf],
    opts: LoadOpts,
) -> MicrosandboxResult<Vec<SnapshotHandle>>
```

Import archives as one batch. Returns handles in input order. Dependencies resolve from the batch, the named group, or an explicit base; input order does not matter. All members are validated before publication.

#### <span className="msb-recv">Snapshot::</span><span className="msb-hn">group\_head()</span>

```rust theme={null}
async fn group_head(selector: &str) -> MicrosandboxResult<HeadUpdate>
```

Read a group’s head, or select an exact member with `group:member`. Returns the group, previous and current snapshot IDs, reason, and whether the head changed. See [group selection](/sandboxes/snapshots#snapshot-groups).

<span id="snapshot-groups" />

<span id="load-multiple-archives" />

### Import options

Options for `LoadOpts`.

| Option | Purpose |
| - | - |
| `dest` | Parent directory containing groups. Defaults to the local snapshot store. |
| `base` | External snapshot or standalone archive for missing dependencies. |
| `group` | Destination group. Omit to create one group for the import. |
| `set_head` | Select the imported tip, even with divergent ancestry. Defaults to false; requires a unique tip. |

With divergent tips, the existing head stays selected; a new group has no head. Select a member explicitly. Identical members may be reused; conflicting identities fail. See [archive imports](/sandboxes/snapshots#import-archives).

## Instance methods

#### <span className="msb-recv">snap.</span><span className="msb-hn">id()</span>

```rust theme={null}
fn id(&self) -> &SnapshotId
```

Stable opaque `snap_...` identity. Copying, archiving, or relabeling the snapshot preserves this value.

#### <span className="msb-recv">snap.</span><span className="msb-hn">digest()</span>

```rust theme={null}
fn digest(&self) -> &str
```

SHA-256 digest of the canonical descriptor bytes. This detects descriptor conflicts but is separate from the stable snapshot ID.

<p className="msb-label">Returns</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><span className="msb-type">\&str</span></div>
    <div className="msb-param-desc">Manifest digest in <code>sha256:hex</code> form.</div>
  </div>
</div>

#### <span className="msb-recv">snap.</span><span className="msb-hn">reference()</span>

```rust theme={null}
fn reference(&self) -> SnapshotReference
```

Backend-neutral locator that preserves whether the snapshot is addressed by an identifier or path. Use it with dedicated restore and lifecycle methods without assuming client-host filesystem access.

<p className="msb-label">Returns</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><span className="msb-type">SnapshotReference</span></div>
    <div className="msb-param-desc">Typed backend-relative snapshot reference.</div>
  </div>
</div>

#### <span className="msb-recv">snap.</span><span className="msb-hn">manifest()</span>

```rust theme={null}
fn manifest(&self) -> &Manifest
```

<Accordion title="Example">
  ```rust theme={null}
  let snap = Snapshot::open("api:baseline").await?;
  let m = snap.manifest();
  println!("{} @ {}", m.image.reference, m.image.manifest_digest);
  ```
</Accordion>

The parsed [`Manifest`](#manifest): stable identity, state closure, capture provenance, pinned image, parent identity, and extensions. Mutable labels are exposed by `labels()` and are not part of this descriptor.

<p className="msb-label">Returns</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><a className="msb-type" href="#manifest">\&Manifest</a></div>
    <div className="msb-param-desc">Parsed snapshot manifest.</div>
  </div>
</div>

#### <span className="msb-recv">snap.</span><span className="msb-hn">size\_bytes()</span>

```rust theme={null}
fn size_bytes(&self) -> Option<u64>
```

Backend-reported stored payload size. This is the apparent upper-file size for
local and host-volume artifacts, and the stored archive size for managed cloud
snapshots.

<p className="msb-label">Returns</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><span className="msb-type">u64</span></div>
    <div className="msb-param-desc">Upper-layer apparent size in bytes.</div>
  </div>
</div>

#### <span className="msb-recv">snap.</span><span className="msb-hn">path()</span>

```rust theme={null}
fn path(&self) -> MicrosandboxResult<&Path>
```

Return the local artifact directory. Cloud snapshots return
`MicrosandboxError::Unsupported` because managed and host-volume artifacts are
not paths on the client host. Use `reference()` for backend-neutral restore and
lifecycle operations.

#### <span className="msb-recv">snap.</span><span className="msb-hn">save\_to()</span>

```rust theme={null}
async fn save_to(&self, out: &Path, opts: SaveOpts) -> MicrosandboxResult<()>
```

Bundle this snapshot into an archive using the backend retained when it was
created or opened. This avoids re-resolving its reference through the current
default backend. Artifact archives are currently local-only; other backends
return `MicrosandboxError::Unsupported`.

#### <span className="msb-recv">snap.</span><span className="msb-hn">copy\_to()</span>

```rust theme={null}
fn copy_to(&self, output_archive_path: impl Into<PathBuf>) -> SnapshotCopyBuilder
```

Create a new archive from this snapshot's disk data while replacing its labels
and integrity metadata. The source snapshot is unchanged. Artifact copies are
currently local-only; other backends return `MicrosandboxError::Unsupported`
when `save()` is awaited.

```rust theme={null}
use std::collections::BTreeMap;

let copied_manifest = snapshot
    .copy_to("./baseline-copy.tar.zst")
    .labels(BTreeMap::from([("environment".into(), "test".into())]))
    .record_integrity(true)
    .save()
    .await?;
```

#### <span className="msb-recv">snap.</span><span className="msb-hn">verify()</span>

```rust theme={null}
async fn verify(&self) -> MicrosandboxResult<SnapshotVerifyReport>
```

<Accordion title="Example">
  ```rust theme={null}
  use microsandbox::snapshot::UpperVerifyStatus;

  let snap = Snapshot::open("api:baseline").await?;
  match snap.verify().await?.upper {
      UpperVerifyStatus::Verified { algorithm, .. } => println!("ok via {algorithm}"),
      UpperVerifyStatus::NotRecorded => println!("no integrity hash recorded"),
  }
  ```
</Accordion>

Verify the snapshot's complete state closure. File state recomputes recorded upper-layer integrity and returns `NotRecorded` without reading the payload when integrity is absent. Checkpoint state validates the root, manifests, disk layers, device/execution objects, and every referenced memory object, then returns the verified checkpoint root.

<p className="msb-label">Returns</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><a className="msb-type" href="#snapshotverifyreport">SnapshotVerifyReport</a></div>
    <div className="msb-param-desc">Digest, path, and upper-layer verification status.</div>
  </div>
</div>

## SnapshotHandle methods

Accessors and lifecycle on a [`SnapshotHandle`](#snapshothandle) returned by
the active backend. Returned by [`Snapshot::get()`](#snapshotget),
[`Snapshot::list()`](#snapshotlist), and [`Snapshot::load()`](#snapshotload).

#### <span className="msb-recv">h.</span><span className="msb-hn">digest()</span>

```rust theme={null}
fn digest(&self) -> &str
```

Descriptor digest (`sha256:hex`), separate from the stable snapshot ID.

#### <span className="msb-recv">h.</span><span className="msb-hn">name()</span>

```rust theme={null}
fn name(&self) -> Option<&str>
```

Member name within its group, or `None` when no alias is recorded.

#### <span className="msb-recv">h.</span><span className="msb-hn">parent\_digest()</span>

```rust theme={null}
fn parent_digest(&self) -> Option<&str>
```

The captured parent snapshot's stable ID, or `None` when no parent is known. The accessor retains its existing `parent_digest` name.

***

#### <span className="msb-recv">h.</span><span className="msb-hn">scope()</span>

<div className="msb-tags"><span className="msb-tag is-instance">instance</span></div>

```rust theme={null}
fn scope(&self) -> SnapshotScope
```

Snapshot payload scope: [`SnapshotScope::Disk`](#snapshotscope) for a disk-only snapshot or `Full` for disk plus VM execution state.

***

#### <span className="msb-recv">h.</span><span className="msb-hn">image\_ref()</span>

```rust theme={null}
fn image_ref(&self) -> &str
```

Image reference the snapshot was taken from.

#### <span className="msb-recv">h.</span><span className="msb-hn">format()</span>

```rust theme={null}
fn format(&self) -> SnapshotFormat
```

On-disk format of the upper layer.

<p className="msb-label">Returns</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><a className="msb-type" href="#snapshotformat">SnapshotFormat</a></div>
    <div className="msb-param-desc">Upper-layer format (<code>Raw</code> today).</div>
  </div>
</div>

#### <span className="msb-recv">h.</span><span className="msb-hn">size\_bytes()</span>

```rust theme={null}
fn size_bytes(&self) -> Option<u64>
```

Backend-reported stored payload size, if known.

#### <span className="msb-recv">h.</span><span className="msb-hn">path()</span>

```rust theme={null}
fn path(&self) -> MicrosandboxResult<&Path>
```

Return the local artifact directory. Cloud snapshots return
`MicrosandboxError::Unsupported`. Use `reference()` for backend-neutral restore
and lifecycle operations.

#### <span className="msb-recv">h.</span><span className="msb-hn">created\_at()</span>

```rust theme={null}
fn created_at(&self) -> chrono::NaiveDateTime
```

Snapshot creation time, parsed from the manifest.

#### <span className="msb-recv">h.</span><span className="msb-hn">open()</span>

```rust theme={null}
async fn open(&self) -> MicrosandboxResult<Snapshot>
```

<Accordion title="Example">
  ```rust theme={null}
  let h = Snapshot::get("api:baseline").await?;
  let snap = h.open().await?;
  snap.verify().await?;
  ```
</Accordion>

Open the underlying snapshot metadata using the backend retained by the handle,
without requiring the caller to interpret its storage location.

<p className="msb-label">Returns</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><a className="msb-type" href="#instance-methods">Snapshot</a></div>
    <div className="msb-param-desc">The opened artifact.</div>
  </div>
</div>

#### <span className="msb-recv">h.</span><span className="msb-hn">remove()</span>

```rust theme={null}
async fn remove(&self, force: bool) -> MicrosandboxResult<()>
```

<Accordion title="Example">
  ```rust theme={null}
  let h = Snapshot::get("api:baseline").await?;
  h.remove(false).await?;
  ```
</Accordion>

Remove this installed snapshot copy by its stored artifact path. Other groups containing the same snapshot ID or digest remain unchanged.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>force</code><span className="msb-type">bool</span></div>
    <div className="msb-param-desc">When <code>true</code>, remove even if the snapshot has indexed children.</div>
  </div>
</div>

## SnapshotBuilder

Builder for a [`SnapshotConfig`](#snapshotconfig). Obtained via [`Snapshot::builder(name)`](#snapshotbuilder). A source sandbox is required ([`from_sandbox`](#from_sandbox)); the other setters are optional. Every setter returns `Self`, so calls chain.

<Accordion title="Example">
  ```rust theme={null}
  let snap = Snapshot::builder("deps")
      .from_sandbox("api")           // sandbox to capture
      .label("stage", "post-deps")
      .record_integrity()            // hash the upper layer
      .create()
      .await?;
  ```
</Accordion>

***

#### <span className="msb-recv">.</span><span className="msb-hn">from\_sandbox()</span>

<div className="msb-tags"><span className="msb-tag is-builder">builder</span></div>

```rust theme={null}
fn from_sandbox(self, source_sandbox: impl Into<String>) -> Self
```

Set the sandbox to capture. Required; [`build()`](#build) and [`create()`](#create) fail without it.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>source\_sandbox</code><span className="msb-type">impl Into\<String></span></div>
    <div className="msb-param-desc">Name of the OCI-rooted source sandbox. Local disk capture also supports running and paused sources. Cloud requires a stopped persistent source.</div>
  </div>
</div>

***

#### <span className="msb-recv">.</span><span className="msb-hn">group()</span>

```rust theme={null}
fn group(self, group: impl Into<String>) -> Self
```

Set the local snapshot group. Defaults to the source sandbox’s name. Direct archive capture does not accept a group.

#### <span className="msb-recv">.</span><span className="msb-hn">dest\_dir()</span>

<div className="msb-tags"><span className="msb-tag is-builder">builder</span></div>

```rust theme={null}
fn dest_dir(self, dest_dir: impl Into<PathBuf>) -> Self
```

Create the snapshot group under this parent directory instead of the default snapshots store. Member names are local aliases within the group; stable snapshot IDs identify immutable artifacts.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>dest\_dir</code><span className="msb-type">impl Into\<PathBuf></span></div>
    <div className="msb-param-desc">Parent directory to create the artifact in (e.g. a larger volume).</div>
  </div>
</div>

#### <span className="msb-recv">.</span><span className="msb-hn">label()</span>

```rust theme={null}
fn label(self, key: impl Into<String>, value: impl Into<String>) -> Self
```

Add a user label. Can be called multiple times. Labels are sorted by key in the manifest's canonical form.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>key</code><span className="msb-type">impl Into\<String></span></div>
    <div className="msb-param-desc">Label key.</div>
  </div>

  <div className="msb-param">
    <div className="msb-param-key"><code>value</code><span className="msb-type">impl Into\<String></span></div>
    <div className="msb-param-desc">Label value.</div>
  </div>
</div>

#### <span className="msb-recv">.</span><span className="msb-hn">force()</span>

```rust theme={null}
fn force(self) -> Self
```

Overwrite an existing direct archive output file. Installed group members are immutable, so installed creation rejects this option.

#### <span className="msb-recv">.</span><span className="msb-hn">record\_integrity()</span>

```rust theme={null}
fn record_integrity(self) -> Self
```

Compute and record sparse-aware BLAKE3 Merkle integrity during creation. [`verify()`](#snap-verify) checks it explicitly; ordinary open, boot, save, load, and upgrade preserve the value without adding an independent payload pass.

***

#### <span className="msb-recv">snapshot\_builder.</span><span className="msb-hn">full()</span>

<div className="msb-tags"><span className="msb-tag is-builder">builder</span></div>

```rust theme={null}
fn full(self) -> Self
```

Local-only: capture disk, memory, and execution state. The source must be running or paused and returns to that state after capture.

#### <span className="msb-recv">.</span><span className="msb-hn">guest\_flush()</span>

```rust theme={null}
fn guest_flush(self, policy: GuestFlush) -> Self
```

Select guest writeback before capture. Defaults to `GuestFlush::Auto`; see [guest writeback](#guest-writeback).

#### <span className="msb-recv">.</span><span className="msb-hn">build()</span>

```rust theme={null}
fn build(self) -> MicrosandboxResult<SnapshotConfig>
```

Materialize the [`SnapshotConfig`](#snapshotconfig) without creating the snapshot. Errors with `InvalidConfig` if [`from_sandbox`](#from_sandbox) was not called. For capturing, use [`create`](#create) instead; it calls `build` internally.

<p className="msb-label">Returns</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><a className="msb-type" href="#snapshotconfig">SnapshotConfig</a></div>
    <div className="msb-param-desc">Validated snapshot configuration.</div>
  </div>
</div>

#### <span className="msb-recv">.</span><span className="msb-hn">create()</span>

```rust theme={null}
async fn create(self) -> MicrosandboxResult<Snapshot>
```

Build and execute the snapshot in one step. Equivalent to [`Snapshot::create(self.build()?)`](#snapshotcreate).

<p className="msb-label">Returns</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><a className="msb-type" href="#instance-methods">Snapshot</a></div>
    <div className="msb-param-desc">The created artifact handle.</div>
  </div>
</div>

## SnapshotCopyBuilder

Returned by [`Snapshot::copy_to()`](#snap-copy_to). It reuses the source disk
data while replacing explicit-snapshot metadata in a new archive.

| Method | Returns | Description |
| - | - | - |
| `labels(BTreeMap<String, String>)` | `Self` | Replace all labels in the copied manifest |
| `record_integrity(bool)` | `Self` | Compute integrity when true, or omit it when false |
| `save()` | `MicrosandboxResult<Manifest>` | Write the archive and return its manifest |

## RestoreBuilder

Restore into a new detached sandbox. Disk boots fresh; full resumes execution. See [restore examples](/sandboxes/snapshots#disk-snapshots) and [progress](/sandboxes/snapshots#restore-progress).

<Accordion title="Example">
  ```rust theme={null}
  let child = Sandbox::restore("api:baseline")
      .name("api-restored")
      .cow_memory()
      .restore()
      .await?;
  ```
</Accordion>

| Control | Purpose |
| - | - |
| `cow_memory()` | Share unchanged full-snapshot memory. |
| `.forked()` | Deprecated alias for the same CoW memory policy; see [migration notes](/sandboxes/snapshots#migrating-restore-options). |
| `disk_only()` | Boot only the saved disk. |
| `snapshot_base(base)` | Supply an archive dependency. |
| `restore()` | Return the restored sandbox. |
| `restore_with_progress()` | Return the progress receiver and result task. |

Image, replacement, and startup-command options are not accepted. Full restore requires matching CPU and memory settings, keeps captured network devices, and cannot apply a new guest security profile. Use disk-only restore to change these.

Full restore rejects missing external filesystems and additional disks by default. Use `allow_missing_resources()` to resume with unavailable devices and warnings. This is separate from strict/relaxed validation of supplied mappings; inheritance does not waive missing backing. Root and owned storage remain required.

<Accordion title="Destination options">
  | Option | Purpose |
  | - | - |
  | `cpus(), memory()` | CPU count and memory in MiB. Full restore must match capture. |
  | `network_policy()` | Replace host traffic filtering; guest DNS and TLS settings stay unchanged. |
  | `max_connections()` | Concurrent TCP limit; zero means unlimited. |
  | `disable_network()` | Remove the NIC. Rejected for full snapshots that captured one. |
  | `security()` | Guest security profile. Disk boot only, including an explicit default profile. |
  | `guest_clock()` | Override the snapshot's clock setting with `Sync` or `Off`. Supports full restores. |
  | `max_duration(), idle_timeout()` | Lifetime and idle limits. Omitted means unlimited; zero expires immediately. |
  | `volume()` | Map host volumes or select captured private volumes. |
  | `port(), port_bind(), port_udp(), port_udp_bind()` | Bind destination TCP or UDP ports. |
  | `vsock(), vsock_dgram()` | Bind destination vsock endpoints. |
  | `user(), log_level()` | Default user for new execs and host runtime log level. |
  | `dangerously_inherit_resources()` | Explicitly inherit host resources. Disabled by default. |
  | `allow_missing_resources()` | Allow unavailable external filesystems or additional disks, with warnings. Full restore otherwise requires their bindings. |
  | `external_mount_policy()` | Validate supplied filesystem mappings: strict (default) or relaxed. Does not grant access. |

  Omitted controls retain destination defaults. Durations are whole seconds. Network policy accepts `NetworkPolicy`. Use `|v| v.captured()` for a private captured volume.
</Accordion>

#### <span className="msb-recv">Sandbox::</span><span className="msb-hn">restore\_ref()</span>

```rust theme={null}
fn restore_ref(reference: impl Into<SnapshotReference>) -> RestoreBuilder
```

Restore from an explicit backend-neutral snapshot reference. Pass a `Snapshot` or `SnapshotHandle` reference without reinterpreting an identifier as a path. This uses the same dedicated restore options and backend capability checks as `Sandbox::restore()`.

<Accordion title="Example">
  ```rust theme={null}
  let restored = Sandbox::restore_ref(snapshot.reference())
      .name("api-restored")
      .restore()
      .await?;
  ```
</Accordion>

#### <span className="msb-recv">h.</span><span className="msb-hn">snapshot()</span>

```rust theme={null}
async fn snapshot(&self, name: &str) -> MicrosandboxResult<Snapshot>
```

`SandboxHandle` method. Snapshot this sandbox's disk into its default group with the given member name. Use the returned artifact path or `sandbox:member` to open it later. Live captures are crash-consistent and preserve the source's running/paused state. Local handles only. To place the artifact elsewhere, use [`Snapshot::save()`](#snapshotsave) / [`Snapshot::load()`](#snapshotload) or move the self-contained artifact directory.

<p className="msb-label">Parameters</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><code>name</code><span className="msb-type">\&str</span></div>
    <div className="msb-param-desc">Member name within the source sandbox's group.</div>
  </div>
</div>

<p className="msb-label">Returns</p>

<div className="msb-params">
  <div className="msb-param">
    <div className="msb-param-key"><a className="msb-type" href="#instance-methods">Snapshot</a></div>
    <div className="msb-param-desc">The created artifact handle.</div>
  </div>
</div>

<Accordion title="Example: capture under another group-store root">
  ```rust theme={null}
  let snap = Snapshot::builder("baseline")
      .from_sandbox("api")
      .dest_dir("/data/snapshots")
      .create()
      .await?;
  // snap.path() is /data/snapshots/api/<snapshot_id>.
  ```
</Accordion>

***

<span id="disk-maintenance-and-incremental-export" />

## Compaction

Compact a local sandbox’s root or owned disks. See [compaction](/sandboxes/snapshots#compact-disks) for examples and recovery requirements.

<Accordion title="Options and results">
  | Option | Purpose |
  | - | - |
  | `disk()` | Select one owned disk by guest path; `/` selects the root. |
  | `root_disk_only()` | Select only the root. Cannot combine with the disk selector. |
  | `layers()` | Oldest sealed layers to merge, including the base. Minimum two; omit for all. Excludes the writable layer. |
  | `dry_run()` | Preview without changing storage. |

  Defaults to the root and owned data disks; excludes named/external volumes and directories. Requires a running or fully stopped local sandbox. Fewer than two sealed layers means no change; no eligible disks returns an empty result with zero counts.

  Results include aggregate counts and per-disk entries keyed by `guest_path`. `materialized_bytes` counts copied bytes, not reclaimed space. Times are microseconds: per-disk `total_us` covers preparation; aggregate `total_us` also includes switching; `pause_us` measures the shared VM pause.
</Accordion>

## Types

### SnapshotReference

<div className="msb-tags"><span className="msb-tag is-type">enum</span></div>

A backend-neutral snapshot locator. Obtain one from `Snapshot::reference()` or
`SnapshotHandle::reference()` and pass it to
`Sandbox::restore_ref()`, `Snapshot::open_ref()`, or
`Snapshot::remove_ref()`. This preserves whether a value is an identifier or a
path without exposing the selected backend.

| Variant | Meaning |
| - | - |
| `Auto(String)` | Compatibility string interpreted automatically by the active backend |
| `Id(String)` | Identifier resolved by the selected backend |
| `Path(String)` | Path in the selected backend's filesystem namespace |

Use `SnapshotReference::auto()`, `id()`, or `path()` to construct a reference.
`value()` returns the underlying string and `kind()` returns `auto`, `id`, or
`path`.

### SnapshotHandle

<div className="msb-tags"><span className="msb-tag is-type">struct</span></div>

<p className="msb-backref">Returned by <a href="#snapshotget">Snapshot::get()</a> · <a href="#snapshotlist">Snapshot::list()</a> · <a href="#snapshotload">Snapshot::load()</a></p>

A lightweight handle returned by the active backend. Use [`open()`](#h-open) to
read the snapshot metadata. The handle retains its backend, so `open()` and
`remove()` work without the caller interpreting its storage location.

| Method | Type | Description |
| - | - | - |
| digest() | `&str` | Manifest digest (`sha256:hex`) |
| name() | `Option<&str>` | Name alias; `None` for digest-only entries |
| parent\_digest() | `Option<&str>` | Parent snapshot digest, or `None` for a root |
| scope() | [`SnapshotScope`](#snapshotscope) | Snapshot payload scope (`Disk` today) |
| image\_ref() | `&str` | Source image reference |
| format() | [`SnapshotFormat`](#snapshotformat) | On-disk upper format |
| size\_bytes() | `Option<u64>` | Upper file size at index time |
| created\_at() | `chrono::NaiveDateTime` | Creation time from the manifest |
| reference() | `SnapshotReference` | Stable backend-neutral restore reference |
| open() | `Result<`[`Snapshot`](#instance-methods)`>` | Open the underlying artifact |
| remove(force) | `Result<()>` | Remove this snapshot |
| save\_to(out, opts) | `Result<()>` | Bundle through the backend retained by this handle |

### SnapshotConfig

<p className="msb-backref">Used by <a href="#snapshotcreate">Snapshot::create()</a> · returned by <a href="#build">build()</a></p>

Inputs to create a snapshot. A type alias for `SnapshotSpec`. Usually built via [`SnapshotBuilder`](#snapshotbuilder) rather than constructed directly.

| Field | Type | Description |
| - | - | - |
| name | `String` | Member name within its group; generated when empty |
| group | `Option<String>` | Destination group; defaults to the source sandbox's name |
| dest\_dir | `Option<PathBuf>` | Parent directory containing groups; `None` = the default snapshots directory |
| source\_sandbox | `String` | Name of the source sandbox; local disk capture preserves running/paused state. Cloud requires a stopped persistent source |
| labels | `Vec<(String, String)>` | User-supplied labels |
| force | `bool` | Overwrite a direct archive output; rejected for installed group members |
| record\_integrity | `bool` | Compute and record upper-layer integrity at creation |
| full | `bool` | Local-only when `true`: include memory and execution state from a running or paused source. With `false`, local disk capture supports running, paused, stopped, or crashed sources. Cloud requires `false` and a stopped persistent source |
| guest\_flush | `GuestFlush` | Guest writeback policy; defaults to `GuestFlush::Auto`. See [guest writeback](#guest-writeback) |

### SnapshotFormat

<p className="msb-backref">Used by <a href="#h-format">format()</a> · <a href="#manifest">Manifest.format</a></p>

On-disk format of the captured upper layer. Today only `Raw` is produced; the variant exists so qcow2 chains drop in later without a schema migration.

| Value | Description |
| - | - |
| `Raw` | Raw ext4 image, sparse on disk |
| `Qcow2` | qcow2 with optional backing chain (future) |

### SnapshotScope

<div className="msb-tags"><span className="msb-tag is-type">enum</span></div>

<p className="msb-backref">Used by <a href="#h-scope">scope()</a> · <a href="#manifest">Manifest.scope</a></p>

Snapshot payload scope. Parsing accepts every known scope so older runtimes can still list and inspect artifacts they cannot restore; create and restore paths enforce support. Re-exported as `microsandbox::snapshot::SnapshotScope`.

| Value | Description |
| - | - |
| `Disk` | Disk-only snapshot; captures the writable filesystem state |
| `Full` | Disk plus memory, execution, device, and admitted resource state |

### SaveOpts

<div className="msb-tags"><span className="msb-tag is-type">struct</span></div>

<p className="msb-backref">Used by <a href="#snapshotsave">Snapshot::save()</a> and instance <code>save\_to()</code> methods</p>

Options for [`Snapshot::save()`](#snapshotsave) and instance `save_to()` methods. Implements `Default`; `SaveOpts::default()` writes the head snapshot only, zstd-compressed.

| Field | Type | Description |
| - | - | - |
| with\_parents | `bool` | Walk the parent chain and include each ancestor in the archive |
| with\_image | `bool` | Bundle the OCI image artifacts (EROFS layers, fsmeta, VMDK descriptor) from the global cache so the archive boots offline |
| plain\_tar | `bool` | Skip zstd compression and write a plain `.tar`. Default: zstd |

### SnapshotVerifyReport

<p className="msb-backref">Returned by <a href="#snap-verify">verify()</a></p>

Result of explicit snapshot verification.

| Field | Type | Description |
| - | - | - |
| digest | `String` | Snapshot manifest digest |
| path | `PathBuf` | Artifact directory |
| upper | [`UpperVerifyStatus`](#upperverifystatus) | Upper-layer result; retained as `NotRecorded` for checkpoint state |
| checkpoint | `Option<CheckpointVerifyStatus>` | Verified checkpoint root for full state |

### UpperVerifyStatus

<p className="msb-backref">Used by <a href="#snapshotverifyreport">SnapshotVerifyReport.upper</a></p>

Upper-layer content verification result.

| Variant | Fields | Description |
| - | - | - |
| `NotRecorded` | - | No content integrity descriptor was recorded in the manifest |
| `Verified` | - `algorithm: String` <br /> - `digest: String` | Recorded integrity matched the computed digest |

### Manifest

<p className="msb-backref">Returned by <a href="#snap-manifest">manifest()</a></p>

The snapshot artifact descriptor, serialized as `snapshot.json` (`DESCRIPTOR_FILENAME`) and re-exported as `microsandbox::snapshot::Manifest`. Its SHA-256 digest is computed over RFC 8785 canonical JSON. Stable lineage identity is the separate `snapshot_id` field.

| Field | Type | Description |
| - | - | - |
| schema | `String` | Exactly `microsandbox.snapshot/1` |
| snapshot\_id | `SnapshotId` | Stable opaque snapshot identity |
| scope | [`SnapshotScope`](#snapshotscope) | File or checkpoint state family |
| state | `SnapshotState` | Closed file-layer or checkpoint representation |
| capture | `SnapshotCapture` | Immutable capture time, lineage, source checkpoint, and consistency |
| image | [`ImageRef`](#imageref) | Image the snapshot was taken from |
| parent | `Option<SnapshotId>` | Logical parent identity, or `None` for a root |
| requires | `Vec<String>` | Sorted must-understand extension names |
| extensions | `BTreeMap<String, Value>` | Namespaced additive descriptor fields |

### ImageRef

<p className="msb-backref">Used by <a href="#manifest">Manifest.image</a></p>

Reference to the OCI image the snapshot was taken from. Re-exported as `microsandbox::snapshot::ImageRef`.

| Field | Type | Description |
| - | - | - |
| reference | `String` | Human-readable image reference (e.g. `docker.io/library/python:3.12`) |
| manifest\_digest | `String` | Digest of the OCI manifest, in `sha256:hex` form |

### DiskLayer

<p className="msb-backref">Used by <a href="#manifest">Manifest.upper</a></p>

One member of the complete oldest-first file-layer closure. Re-exported as `microsandbox::snapshot::DiskLayer`; `UpperLayer` remains a source-compatibility alias.

| Field | Type | Description |
| - | - | - |
| layer\_id | `DiskLayerId` | Stable opaque physical-member identity |
| format | `SnapshotFormat` | `raw` or `qcow2` |
| virtual\_size | `u64` | Guest-visible size in bytes |
| backing | `Option<DiskLayerId>` | Immediate predecessor; raw layers cannot have one |
| payload.file\_kind | `LayerFileKind` | `regular` |
| integrity | `Option<`[`UpperIntegrity`](#upperintegrity)`>` | Optional content integrity descriptor; `None` on local hot paths |

### UpperIntegrity

<p className="msb-backref">Used by <a href="#disklayer">DiskLayer.payload.integrity</a></p>

Content integrity descriptor for the captured upper layer.

| Variant | Serialized algorithm | Fields | Purpose |
| - | - | - | - |
| `Sha256` | `sha256` | `digest` | Exact released compatibility |
| `SparseSha256V1` | `msb-sparse-sha256-v1` | `digest` | Exact released sparse-SHA compatibility |
| `FileMerkleBlake3V1` | `msb-file-merkle-blake3-v1` | `root`, `logical_size`, `leaf_size` | Current opt-in sparse-aware integrity |


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.