Persistent Volumes
A volume in Lizard (lizard.build) keeps data after a sandbox stops. It mounts at /workspace and attaches to one sandbox at a time. The sandbox runs on the same node as its volume.
Create and attach by name
Names are unique within a project. Use lowercase letters, digits and dashes, starting and ending with a letter or digit, up to 64 characters.
Use getOrCreate to reuse a named volume. Its size applies only when creating a new volume; it never resizes an existing one. Volume.create returns a conflict if the name is taken.
import { Sandbox, Volume } from '@lizard-build/sdk';
await Volume.getOrCreate('proj_123', 'agent-workdir', { sizeGb: 10 });
const sandbox = await Sandbox.create('base', {
projectId: 'proj_123', volumeName: 'agent-workdir',
});
try {
await sandbox.fs.write('/workspace/state.json', JSON.stringify({ step: 1 }));
} finally {
await sandbox.kill();
}
// A later sandbox mounts the same data by name.
const next = await Sandbox.create('base', {
projectId: 'proj_123', volumeName: 'agent-workdir',
});
try {
console.log(await next.fs.read('/workspace/state.json'));
} finally {
await next.kill();
}from lizard import Sandbox, Volume
Volume.get_or_create("proj_123", "agent-workdir", size_gb=10)
sandbox = Sandbox.create("base", project_id="proj_123", volume_name="agent-workdir")
try:
sandbox.process.exec_("echo hello > /workspace/state.txt")
finally:
sandbox.kill()Size and price
New volumes allow 1–50 GB, in whole GB, with 5 GB as the default. The server can override the maximum through VOLUME_MAX_SIZE_GB; the dashboard and CLI read the current limits from GET /api/projects/:projectId/volume-limits. The dashboard also reads the storage price from that endpoint and shows it below the size slider.
You pay for used space, not the full allocation. Existing volumes larger than the new maximum keep their size and remain accessible. Creating a new volume requires enough unreserved disk space on a healthy worker in the chosen region. If none has room, the API returns 503 with code volume_capacity_unavailable.
Manage volumes
await Volume.list('proj_123');
const volume = await Volume.get('proj_123', 'agent-workdir');
await volume.getInfo('proj_123');
await Volume.delete('proj_123', 'agent-workdir'); // detach first| TypeScript | Python | Purpose |
|---|---|---|
Volume.getOrCreate(projectId, name, options) | Volume.get_or_create(project_id, name, size_gb=5) | Reuse a volume or create it |
Volume.create(projectId, name, options) | Volume.create(project_id, name, size_gb=5) | Create; fail if the name is taken |
Volume.list(projectId) | Volume.list(project_id) | List the project’s volumes |
Volume.get(projectId, nameOrId) | Volume.get(project_id, name_or_id) | Look up a volume |
Volume.delete(projectId, nameOrId) | Volume.remove(project_id, name_or_id) | Delete a detached volume |
Generated IDs and the volumeId / volume_id fields still work for existing callers. Use names in new code.
CLI
lizard volume create agent-workdir --size 10 --project proj_123
lizard volume list --project proj_123
lizard sandbox create --volume agent-workdir --project proj_123
# After stopping the sandbox:
lizard volume rm agent-workdir --project proj_123--size accepts whole GB and checks the current server limit before creating a volume. volume list shows names; use --json when you need IDs.
Dashboard
Open Sandboxes → Volumes in a project. The create form checks the name and offers a size slider with the current maximum and price. The list shows used space, allocated space, status, and the attached sandbox. Copy the ID from the volume’s details when needed.
Storage lifecycle
- Killing or expiring a sandbox detaches its volume and keeps the data.
- An attached volume cannot attach to another sandbox or be deleted.
- A paused sandbox keeps its attachment.
- Deleting a volume removes its data. Volumes use node-local storage; export data you need after a node failure. See storage and recovery.
See the SDK reference for sandbox options.
Updated