Skip to main content

Snapshot Management

Snapshot Management

Create a Snapshot from an Instance

You can create a snapshot from a running instance to save its current state.

from morphcloud.api import MorphCloudClient

client = MorphCloudClient()

instance_id = "instance_your_instance_id" # Replace with a valid instance ID
instance = client.instances.get(instance_id=instance_id)

# Create a snapshot
snapshot = instance.snapshot()

print(f"Snapshot ID: {snapshot.id}")

Snapshot TTL (Auto-Expiration)

Snapshots can optionally expire after a period of inactivity. This is useful for temporary checkpoints and cache-like workflows where you don’t want snapshots to live forever.

  • If ttl_seconds is unset, the snapshot does not expire.
  • If ttl_seconds is set, expiration is based on the snapshot’s last use time (for example, when you boot or start an instance from it).
# Create a snapshot that expires after 1 hour of inactivity
snapshot = instance.snapshot(ttl_seconds=60 * 60)

# Update TTL later (e.g. 24 hours)
snapshot.set_ttl(24 * 60 * 60)

# Clear TTL (never expire)
snapshot.clear_ttl()

print(snapshot.ttl.ttl_seconds, snapshot.ttl.ttl_expire_at)

Snapshot Garbage Collection (Spec)

Snapshot garbage collection (GC) reclaims unreferenced chunk data while keeping live snapshots safe. The system only performs GC on snapshots that have already been soft-deleted and placed into a deleting state, and it only runs for partitions that have deleting (but not yet deleted) snapshots. The GC sweep runs in the control-plane worker and executes the gc_partition binary locally (not via a Kubernetes job).

The GC job is executed per partition with:

  • the partition id
  • the complete set of live snapshot ids
  • a cutoff time
  • an optional verify mode (checks that chunks referenced before GC are still present after)

Core correctness requirements:

  • The live snapshot set must be complete and correct; if it is incomplete, data loss is possible.
  • If any live snapshot manifest/index/protobuf cannot be parsed, GC for that partition must abort and delete nothing.

Algorithm:

  1. Iterate the live snapshot ids.
  2. For each snapshot, fetch and parse it. Supported formats:
    • legacy .manifest + .index
    • unified protobuf format
  3. Build the set of candidate chunk locations (bucket + prefix):
    • include the legacy default location
    • include any protobuf-defined chunk locations
  4. Concurrently build a bloom filter of all referenced chunk ids.
  5. In parallel, scan all chunks in the candidate locations.
  6. For each chunk:
    • if the chunk id is in the bloom filter, do not delete
    • if the chunk is newer than the cutoff time, do not delete
    • otherwise, delete

This design keeps GC efficient (bloom filter + parallel scan) while preventing accidental deletion of live data (no false negatives, abort on parse errors).

Operational notes:

  • GC runs in dry-run mode by default; deletions only occur when explicitly executed.
  • Verify mode can be combined with dry-run to confirm chunk stability without mutating data.
  • Cutoff times should include a grace window (at least 24 hours) to avoid deleting chunks that may still be referenced by in-progress snapshot writes. For local testing, use a fake-GCS timestamp override rather than weakening production checks.

List Snapshots

You can get a list of all snapshots you've created.

from morphcloud.api import MorphCloudClient

client = MorphCloudClient()

snapshots = client.snapshots.list()

for snapshot in snapshots:
print(f"ID: {snapshot.id}, Created At: {snapshot.created}")

Get Snapshot Details

You can retrieve detailed information about a specific snapshot.

from morphcloud.api import MorphCloudClient

client = MorphCloudClient()

snapshot_id = "snapshot_your_snapshot_id" # Replace with a valid snapshot ID
snapshot = client.snapshots.get(snapshot_id=snapshot_id)

print(f"Snapshot ID: {snapshot.id}")
print(f"Created At: {snapshot.created}")
print(f"Metadata: {snapshot.metadata}")

Set Snapshot Metadata

You can add metadata to snapshots for organization and search purposes.

from morphcloud.api import MorphCloudClient

client = MorphCloudClient()

snapshot_id = "snapshot_your_snapshot_id" # Replace with a valid snapshot ID
snapshot = client.snapshots.get(snapshot_id=snapshot_id)

# Set metadata
snapshot.set_metadata({"environment": "production", "version": "1.0.0"})

print(f"Snapshot '{snapshot_id}' metadata updated: {snapshot.metadata}")

Delete a Snapshot

When you no longer need a snapshot, you can delete it.

from morphcloud.api import MorphCloudClient

client = MorphCloudClient()

snapshot_id = "snapshot_your_snapshot_id" # Replace with a valid snapshot ID
snapshot = client.snapshots.get(snapshot_id=snapshot_id)
snapshot.delete()

print(f"Snapshot {snapshot_id} has been deleted")