Skip to main content

Sailbox Volumes

Alpha: Sailbox Volumes are available for early testing. The API and durability semantics may change before general availability.
Sailbox Volumes are org-scoped persistent workspace trees that can be mounted into one or more Sailboxes. A mounted volume is a filesystem path; data is shared with other Sailboxes only when you call commit() and pulled from remote only when you call reload().
import sail

app = sail.App.find(name="my-app", mint_if_missing=True)
volume = sail.Volume.get("shared-data", mint_if_missing=True)

sb = sail.Sailbox.create(
    app=app,
    image=sail.Image.debian_arm64,
    name="worker-1",
    volumes={"/mnt/shared": volume},
)
Inside the Sailbox:
import sail

volume = sail.Volume.from_mount("/mnt/shared")

with open("/mnt/shared/notebook.ipynb", "w") as f:
    f.write("{}")

volume.commit()
volume.reload()
reload() updates the mounted view to the latest remote manifest through lazy FUSE. It does not download every file in the volume. File bytes are downloaded into a local cache when a process opens the file, while new writes are kept in a dirty local overlay until commit(). Mounted volumes require guest FUSE support; if the guest cannot run the volume FUSE helper, reload() fails with an error.

API

sail.Volume.get

volume = sail.Volume.get("shared-data", mint_if_missing=True)
Gets an org-scoped volume by name. When mint_if_missing=True, Sail creates the volume if it does not exist.

Sailbox.create(..., volumes=...)

sb = sail.Sailbox.create(
    app=app,
    image=sail.Image.debian_arm64,
    name="worker",
    volumes={"/mnt/shared": volume},
)
volumes is a mapping from absolute guest mount path to a sail.Volume handle. The mount path must not be /.

sail.Volume.from_mount

volume = sail.Volume.from_mount("/mnt/shared")
Returns a mounted volume handle inside a Sailbox.

volume.commit

commit_id = volume.commit()
Publishes the mounted local tree as the latest remote volume state.

volume.reload

commit_id = volume.reload()
Updates the mounted view to the latest remote volume state. This is metadata-only; file bytes are fetched on first open through the required lazy FUSE helper.

Semantics

  • Volume data is not included in Sailbox checkpoints.
  • Commit dirty local work before migration, fork, or restore if those bytes must survive. The durability boundary is commit().
  • Deleting or terminating a Sailbox does not delete its volumes.
  • Multiple Sailboxes can mount the same volume concurrently.
  • commit() detects changed files, uploads missing chunks and delete markers, then publishes a metadata commit. Unchanged chunks are not re-uploaded.
  • Concurrent commits to different paths are merged at commit time. Concurrent commits to the same path are last-writer-wins.
  • reload() overwrites unsynced local changes and updates the lazy mounted view without prefetching the full tree.
  • There is no POSIX locking or live remote filesystem behavior.
  • Volumes store files as chunks. Small files use 8MiB chunks; large files use larger chunks for higher bulk throughput. Rewriting bytes inside a chunk uploads that chunk again; appending after a full final chunk uploads only the new tail chunk.
  • Large changed files are uploaded and downloaded with bounded chunk concurrency.

Performance

Writes are local until commit(). Clean remote files are fetched lazily on first open and cached locally, so mounting or reloading a large volume does not require local disk proportional to the full remote tree. File chunks stream directly to S3 through short-lived URLs, and Sailbox API requests carry metadata only. This is intended for object-store-shaped workspace access: whole-file CRUD, notebooks and small files rewritten frequently, and occasional larger file upload/download.