Skip to content

Backups

Last updated View as MarkdownAgent setup

Create point-in-time snapshots of sandbox directories and restore them from R2.

For setup, restore workflows, and generated-cache exclusions, refer to Backup and restore. For overlay semantics, refer to Directory backups.

Methods

createBackup()

Create a snapshot of a directory and upload it to R2.

await sandbox.createBackup(options: BackupOptions): Promise<DirectoryBackup>

Parameters:

  • options - Backup configuration (see BackupOptions):
    • dir (required) - Absolute path to back up. Must be under /workspace, /home, /tmp, /var/tmp, or /app.
    • name (optional) - Human-readable name. Maximum 256 characters. Control characters are rejected.
    • ttl (optional) - Time-to-live in seconds. Default: 259200 (3 days). Must be a positive number.
    • gitignore (optional) - When true, exclude paths matching .gitignore rules if dir is inside a git repository. Default: false. If the directory is not in a git repository, no git exclusions apply. If git is not installed, the SDK logs a warning and continues without git-based exclusions.
    • excludes (optional) - Glob patterns to omit from the archive. Passed to mksquashfs as wildcard excludes. ** globstars are normalized automatically. Default: [].
    • localBucket (optional) - When true, use the BACKUP_BUCKET R2 binding instead of presigned URLs. Intended for wrangler dev. Default: false.
    • compression (optional) - Archive compression. Default format: lz4. Default threads: 8. Format must be gzip, lz4, or zstd. threads must be a positive integer.
    • multipart (optional) - Use parallel multipart upload for large archives. Default: true.

Returns: Promise<DirectoryBackup> containing:

  • id - Unique backup identifier (UUID)
  • dir - Directory that was backed up
  • localBucket (optional) - Whether the backup used local R2 binding mode
import { getSandbox } from "@cloudflare/sandbox";

const sandbox = getSandbox(env.Sandbox, "my-sandbox");

const backup = await sandbox.createBackup({ dir: "/workspace" });
await sandbox.restoreBackup(backup);
import { getSandbox } from "@cloudflare/sandbox";

const sandbox = getSandbox(env.Sandbox, "my-sandbox");

const backup = await sandbox.createBackup({ dir: "/workspace" });
await sandbox.restoreBackup(backup);

How it works:

In production:

  1. The container creates a compressed squashfs archive.
  2. The container uploads the archive to R2 with a presigned URL.
  3. Metadata is stored alongside the archive in R2.
  4. The local archive is deleted.

With localBucket: true:

  1. The container creates a compressed squashfs archive.
  2. The archive is uploaded through the BACKUP_BUCKET R2 binding.
  3. Metadata is stored alongside the archive in R2.
  4. The local archive is deleted.

Throws:

  • InvalidBackupConfigError - If dir is not an allowed absolute path, the BACKUP_BUCKET binding is missing, or (in production) R2 presigned URL credentials are not configured
  • BackupCreateError - If archive creation or the upload to R2 fails

restoreBackup()

Restore a previously created backup.

await sandbox.restoreBackup(backup: DirectoryBackup): Promise<RestoreBackupResult>

Parameters:

  • backup - Handle returned by createBackup(). Contains id and dir. Restore writes into backup.dir, which may differ from the original backup path. (see DirectoryBackup)

Returns: Promise<RestoreBackupResult> containing:

  • success - Whether the restore succeeded
  • dir - Directory that was restored
  • id - Backup ID that was restored
await sandbox.restoreBackup(backup);
await sandbox.restoreBackup(backup);

How it works:

In production:

  1. Metadata is downloaded from R2 and the TTL is checked, with a 60-second buffer. An expired backup throws.
  2. The container downloads the archive from R2 with a presigned URL.
  3. The container mounts the archive with FUSE overlayfs.

With localBucket: true:

  1. Metadata is downloaded from the BACKUP_BUCKET binding and the TTL is checked.
  2. The archive is downloaded from the R2 binding.
  3. The archive is extracted with unsquashfs.

Throws:

  • InvalidBackupConfigError - If backup.id is missing or not a UUID, or backup.dir is invalid
  • BackupNotFoundError - If the metadata or archive is not in R2
  • BackupExpiredError - If the TTL has elapsed
  • BackupRestoreError - If the container fails to restore

Behavior

  • Concurrent backup and restore operations on the same sandbox are serialized.
  • DirectoryBackup is serializable. Store it in KV, D1, or Durable Object storage.
  • Overlapping backups are independent. Restoring a parent directory overwrites subdirectory mounts. Restore the parent first when restoring both.
  • ttl is enforced at restore time only. Expired objects remain in R2 until you delete them or an R2 lifecycle rule removes them.
  • Backup objects use backups/{id}/data.sqsh and backups/{id}/meta.json.

Types

BackupOptions

interface BackupCompressionOptions {
	format?: "gzip" | "lz4" | "zstd";
	threads?: number;
}

interface BackupOptions {
	dir: string;
	name?: string;
	ttl?: number;
	gitignore?: boolean;
	excludes?: string[];
	localBucket?: boolean;
	compression?: BackupCompressionOptions;
	multipart?: boolean;
}

Fields:

  • dir (required) - Absolute path under /workspace, /home, /tmp, /var/tmp, or /app
  • name (optional) - Human-readable name. Maximum 256 characters. No control characters.
  • ttl (optional) - Time-to-live in seconds. Default: 259200 (3 days). Must be a positive number.
  • gitignore (optional) - When true, exclude .gitignore matches if dir is inside a git repository. Default: false.
  • excludes (optional) - Glob patterns to omit. Example: ['node_modules/.cache', '*.log']. Refer to Exclude generated caches.
  • localBucket (optional) - Use the BACKUP_BUCKET binding instead of presigned URLs. Default: false.
  • compression (optional) - format defaults to lz4. threads defaults to 8.
  • multipart (optional) - Parallel multipart upload. Default: true.

DirectoryBackup

interface DirectoryBackup {
	readonly id: string;
	readonly dir: string;
	readonly localBucket?: boolean;
}

Fields:

  • id - Unique backup identifier (UUID)
  • dir - Directory to restore into
  • localBucket (optional) - Whether the backup used local R2 binding mode

RestoreBackupResult

interface RestoreBackupResult {
	success: boolean;
	dir: string;
	id: string;
}

Fields:

  • success - Whether the restore succeeded
  • dir - Directory that was restored
  • id - Backup ID that was restored

Was this helpful?