Skip to main content
A Volume keeps one folder, /workspace unless you attach it elsewhere, after its sandbox is gone. Processes, memory, connections, and everything outside that folder are lost. Volumes can be switched off for a deployment or workspace. Creating a volume, or a sandbox with a volume, then fails with capability_unavailable (409); the fix says Volumes are not enabled. Nothing starts. If the first create below succeeds, Volumes are on. A privacy-mode workspace fails with privacy_persistence_conflict instead.
Files on a Local Disk: your code runs a sandbox on Provider A, and its files sit on Provider A's local disk. Files in a Volume: your code calls BoxRouter, which runs the sandbox on Provider A or Provider B, and both mount the same Volume.Files on a Local Disk: your code runs a sandbox on Provider A, and its files sit on Provider A's local disk. Files in a Volume: your code calls BoxRouter, which runs the sandbox on Provider A or Provider B, and both mount the same Volume.Files on a Local Disk: your code runs a sandbox on Provider A, and its files sit on Provider A's local disk. Files in a Volume: your code calls BoxRouter, which runs the sandbox on Provider A or Provider B, and both mount the same Volume.Files on a Local Disk: your code runs a sandbox on Provider A, and its files sit on Provider A's local disk. Files in a Volume: your code calls BoxRouter, which runs the sandbox on Provider A or Provider B, and both mount the same Volume.

A local disk ends with its sandbox; a Volume outlives it.

The volume saves that folder as checkpoints. Destroying a write sandbox saves one; call save_volume to save one on demand, as History shows. By default, a new sandbox starts from the volume’s head checkpoint. Before You Begin: BOXROUTER_API_KEY set and a client installed, as in the quickstart.
Sandbox 1, attached with access write, writes /workspace into the volume; destroying it saves a checkpoint. Sandbox 2 saves another with save_volume. A branch sandbox starts from a checkpoint with files of its own, and the head stays unchanged. A second writer is refused with volume_busy until the first sandbox releases the volume.Sandbox 1, attached with access write, writes /workspace into the volume; destroying it saves a checkpoint. Sandbox 2 saves another with save_volume. A branch sandbox starts from a checkpoint with files of its own, and the head stays unchanged. A second writer is refused with volume_busy until the first sandbox releases the volume.Sandbox 1, attached with access write, writes /workspace into the volume; destroying it saves a checkpoint. Sandbox 2 saves another with save_volume. A branch sandbox starts from a checkpoint with files of its own, and the head stays unchanged. A second writer is refused with volume_busy until the first sandbox releases the volume.Sandbox 1, attached with access write, writes /workspace into the volume; destroying it saves a checkpoint. Sandbox 2 saves another with save_volume. A branch sandbox starts from a checkpoint with files of its own, and the head stays unchanged. A second writer is refused with volume_busy until the first sandbox releases the volume.

One writer at a time adds checkpoints to the volume; a branch starts from a checkpoint and leaves the head alone. Processes, memory and everything outside the folder are lost.

Write in One Sandbox, Read in the Next

Create a sandbox with only the volume, write your files, then destroy the sandbox. Destruction flushes the folder and saves a checkpoint. Creating the next sandbox on the same volume waits for the first one to release it, so the next call needs no polling. Use create for the first sandbox: it can prepare an image, while matching a volume requires an image that is already ready.

Continue on Another Provider

Any sandbox that can mount the volume can read it, so the next sandbox does not have to run where the last one did. This example asks the second sandbox to avoid the first one’s provider.
Not every route can mount a volume. Some routes block the network path to the volume’s storage, and BoxRouter skips a route it has not proven end to end. If no remaining route can mount the volume, match and create fail with volume_unavailable (409). Sandboxes without a volume still start on those routes. An explicit provider outside the list fails the same way, so leave preferences.only unset to let BoxRouter pick. Provider support explains how routes differ.

What to Expect

What It Holds

Files are written to the volume as the sandbox writes them, and a later sandbox sees them without a save. While a sandbox has the volume attached with write or shared access, the size shown for the volume and the storage you are billed for refresh about every few minutes. Past the storage limit, writes already in progress are not stopped. A workspace past its storage limit can still read what it has, and nothing it wrote is deleted:
  • Allowed: attaching a volume with read or shared access, resuming a sandbox that already holds a volume, and downloading or listing files. These add no bytes, so they do not check usage.
  • Refused with resource_limit (413): attaching with write or branch access, saving a checkpoint, and starting an upload. A pause or destroy that has to save a checkpoint first is refused the same way, and the sandbox keeps running. Files already written stay on the volume. Delete volumes you no longer need and try again, or destroy with discard_unsaved=true to end the sandbox without a checkpoint.
If BoxRouter cannot read usage at that moment, the checkpoint that a pause or destroy takes retries the reading once. If it is still unavailable, the call fails with capability_unavailable (503) and the sandbox keeps running. Files already written stay on the volume; retry shortly. A save you request does not retry on its own; save again. An abrupt kill loses writes the sandbox had not yet flushed. fsync files you cannot afford to lose before anything that might kill the sandbox, or save a checkpoint. A workspace in transient privacy mode cannot create or attach volumes, because that mode forbids persistence. The request fails with privacy_persistence_conflict.

Move Files in and Out

You can upload and download without a sandbox. A directory upload preserves its relative paths. A download path ending in / selects everything under that path. Delete a file the same way, or everything under a path ending in /, to free space without deleting the volume. Deleting a path that does not exist succeeds, so a repeated request is safe. After a delete, BoxRouter reads the volume’s size once. The storage system can take a short while to report the freed space, so the size shown for the volume may still be the old one; it is read again at the next attach, save, or upload. An upload session, and the part URLs it returns, stay valid for six hours plus about one hour for each 70 GiB of the file’s declared size, up to 72 hours. expires_at in the response says when. That allows for a sustained 20 MiB/s; a slower link needs a smaller file or a faster connection. Expired sessions are aborted, and you can start a new upload. A directory upload sends up to four files at once, and each file sends up to four parts at once. Set file_concurrency (Python) or fileConcurrency (TypeScript) to change the number of files, and concurrency to change the number of parts per file; both must be at least 1. The progress callback receives the bytes sent and the total bytes of every file. After the first failure the SDK starts no more files and aborts the uploads still sending, so files that finished before the failure stay on the volume. The Python call returns the uploaded files in path order. The SDKs can retry a Volume upload part after a network or server failure; resending replaces the part. They can retry upload completion with the same idempotency key. If an upload still fails, check its outcome and target before starting another. You cannot upload or delete files while a sandbox is attached with write, a save is running, or an upload is open, and you cannot attach a write sandbox while an upload is open. Each is refused with volume_busy.
Each example uploads a local report.csv, downloads it again, lists the folder, deletes the file, and deletes its own volume. To keep the volume for a sandbox, leave out the last line. Uploaded files appear under /workspace/ in the next sandbox. An upload does not save a checkpoint.

History

A volume saves its folder as checkpoints. Destroying a write sandbox saves one. To save one on demand, call save_volume; it returns the checkpoint number. Pass that number as checkpoint when you create a sandbox to start from that state. This does not roll back the volume itself. A sandbox can attach a checkpoint only with the image and architecture the checkpoint was saved with. Any other image or architecture fails with volume_incompatible (409) before anything starts. The fix names the image and architecture to use; create the sandbox again with them.

Access Modes

Set access on the attachment to say what the sandbox may do with the volume:
  • Use write (the default) to change the volume’s files. Only one write sandbox can be attached at a time.
  • Use read to read files without changing them.
  • Use shared when several sandboxes need the volume at once.
  • Use branch to work on files of your own without changing the head.
A new volume needs one write attachment or one upload before it accepts read or shared. An empty volume has no head. Pass a checkpoint number as checkpoint to start from a saved state other than the head. read and shared refuse any other historical checkpoint with capability_unavailable (409). On the CLI, --volume takes the volume ID alone, ID:ACCESS (for example "$VOLUME_ID:read"), ID@CHECKPOINT, or both as ID@CHECKPOINT:ACCESS. Use the JSON form, such as --volume '{"id":"vol_...","path":"/data"}', to set path as well.

Branches

A branch starts from a checkpoint and has its own files. Save it using the branch sandbox’s ID; the resulting checkpoint contains only that branch’s files. The volume’s head and the source files stay unchanged. Creating a sandbox without checkpoint still starts from the head. Read the branch checkpoint with access: read and its number, on any provider that can mount the volume.
Branches share one disk, so a sandbox in one branch can reach the files of the others. A branch is not a security boundary: do not use branches to isolate untrusted code.

Reading Many Small Files

Reading many small files is slower from a volume than from the sandbox’s own disk, because each file is a separate network read. Scans such as grep -r or git status over a large tree are slow in the same way. Copy a working set you read heavily onto the sandbox’s own disk first.

Delete a Volume

Delete erases the files and every checkpoint. If the last writer is still ending, delete waits for its release, at most 120 seconds. It is refused with volume_busy while a sandbox is still running on the volume, so destroy the sandboxes that use it first. If storage removal does not finish at once, the volume stays in the list with state deleting and keeps counting toward the 20-volume limit. BoxRouter keeps retrying, and you can send the same delete again; it returns 204 once the volume is gone. The dashboard’s Storage page lists and inspects volumes, and Delete is its only action. In Use By shows each attached sandbox. Checkpoints and branches are code-only. See the Volumes API reference for every field.

Next Steps

Choose a Sandbox Image

Fix software in the image instead.

Pause, Resume, and Extend

Keep the whole sandbox, memory included.

Work with Files

Move files in and out of one sandbox.