Solari

Volumes

A volume is durable storage that outlives any single machine. Create one once, then attach it to a sandbox or VM at start-up and read and write it at a path of your choosing. When the machine goes away, the data stays.

Use a volume for anything you want to keep across runs and share between machines: datasets and model weights, a package cache, build artifacts, scraped output. Unlike a snapshot, which freezes a whole machine at a moment in time, a volume is a live folder you mount and keep writing to.

Create a volume

Volumes live on the volumes namespace of a SandboxClient (or DesktopClient). Creating one gives you back a volumeId you can attach later. A volume starts empty and belongs to your organization.

import { SandboxClient } from "@solarisdk/sandbox"

const sandboxes = new SandboxClient({
  apiKey: process.env.SOLARI_API_KEY!,
  baseUrl: "https://api.getsolari.com",
})

const vol = await sandboxes.volumes.create({
  name: "datasets",
  sizeMb: 4096,               // optional soft size hint
  metadata: { team: "ml" },   // optional free-form tags
})
console.log(vol.volumeId)     // vol_0d10088366248dc85ee1489c9a96b1cc
import os
from solari_sandbox import SyncSandboxClient

sandboxes = SyncSandboxClient(api_key=os.environ["SOLARI_API_KEY"], base_url="https://api.getsolari.com")

vol = sandboxes.volumes.create(name="datasets", size_mb=4096, metadata={"team": "ml"})
print(vol["volumeId"])

List, fetch, and delete

The client mirrors the same four calls in every SDK. Deleting a volume is idempotent: deleting one that is already gone still succeeds.

const all = await sandboxes.volumes.list()         // every volume in your org
const one = await sandboxes.volumes.get(vol.volumeId)
await sandboxes.volumes.delete(vol.volumeId)       // idempotent
all_ = sandboxes.volumes.list()
one = sandboxes.volumes.get(vol["volumeId"])
sandboxes.volumes.delete(vol["volumeId"])

Attach a volume to a machine

Pass volumes when you create a sandbox or VM. Each entry maps a volumeId to an absolute mount path inside the machine. The path appears as an ordinary folder. Read and write it like any other directory.

const sbx = await sandboxes.create({
  template: "base",
  volumes: [{ volumeId: vol.volumeId, path: "/data" }],
})
await sbx.connect()

// Everything under /data persists on the volume, not the sandbox.
await sbx.files.write("/data/results.json", JSON.stringify(output))
sbx = sandboxes.create(
    template="base",
    volumes=[{"volumeId": vol["volumeId"], "path": "/data"}],
)

Each mount path must be absolute and unique within a machine. Two volumes cannot share the same path. A machine can mount several volumes at once, and the same volume can be attached to many machines.

Volumes vs. snapshots
Reach for a volume when you want a folder of data that many machines read and write over time. Reach for a snapshot when you want to freeze a whole prepared machine and stamp out ready-to-go copies of it.
An attached volume is a real folder
Attach a volume at start-up and its path is a real folder inside the machine. Data written there survives the machine and reappears when the same volume is attached to a fresh one.
Clean up volumes you're done with
A volume keeps its data, and uses storage, until you delete it, even after every machine that used it is gone. Remove the ones you no longer need.