Skip to content
DocsAll docs
Console

Snapshots

Take a snapshot of a workspace or an environment to add it to the lineage of its volume.

Last updated

On this page

Description and operation

General

A snapshot is a saved, read-only copy of a workspace or an environment at one time. It holds the files of the disk and the definition of its source. You push a snapshot to save one. Each push adds one snapshot to the lineage of the volume of its source. The new snapshot names the snapshot before it as its parent. For a push after a restore, see Restore and clone.

text
before the push:   backend-base@2 ← backend-base@1after the push:    backend-base@3 ← backend-base@2 ← backend-base@1      "before the refactor"

Later you restore a workspace or an environment from a snapshot. A clone is not a snapshot: it copies the live state of a workspace or an environment.

A snapshot stays when its workspace or environment is deleted. The snapshots of one source are kept on one volume. The first push names the volume. See Names and versions.

The platform shows no size for one snapshot. The volume shows the disk that it uses with all its snapshots. For the parts of a snapshot, see Lineage.

A snapshot belongs to the owner of its source. A snapshot of a team workspace or a team environment counts against the quota of the team. You read the snapshots of your own volumes and of the volumes of your teams.

To do these tasks with an AI agent, see Agentic workflows – Volumes.

Snapshot types

The source sets the type of a snapshot. The type sets what the snapshot freezes and how you use it.

AspectWorkspace snapshotEnvironment snapshot
Made withPush a snapshot of a workspacePush a snapshot of an environment
FilesThe home of the workspaceThe data folders of all services
Frozen in stateimage, packages, locks, resources, quotaGbservices, quotaGb
Not frozenVariables, the session, extra working directoriesIntercepts, the sessions that connect to it
Makes a new workspace or environmentRestore a workspaceClone an environment from a snapshot
Puts the source backNoRestore an environment

A workspace snapshot cannot make an environment, and an environment snapshot cannot make a workspace.

Snapshot parameters

A request to push a snapshot has a body. A request with no body is valid after the volume has a name.

ParameterRequiredDescription
messageNoA note for the history.
ttl_secsNoThe lifetime in seconds, 3600 to 31536000. See Lifecycle.
neverNotrue keeps the snapshot with no expiry. Do not give it with ttl_secs.
volumeOn the first pushThe name of the volume. The first push of a volume must give it. Later pushes can omit it. When given, it must equal the name.

The answer is 202 with id, phase, volume, name, version and expires_at. volume is the volume id. name and version are the volume name and the number of this push. expires_at is null when never is true. Only the versions list of a named volume shows expires_at later.

States

phaseMeaning
pendingThe request is accepted. It did not start.
workingThe snapshot is being made. A second snapshot of the same workspace or environment is refused.
readyThe snapshot is complete. You can restore, clone and delete it.
errorThe snapshot failed. The snapshot is not usable.

Lifecycle

  • Push. A push is the only operation that makes a snapshot.
  • Sync points. Between snapshots, the platform keeps internal copies of each running workspace and environment. These sync points are not snapshots. They are never listed, are not a restore target and cannot be deleted by hand.
  • Expiry. A snapshot lives for the region default, 30 days, unless the request gives ttl_secs or never. An administrator can change the default.
  • Use. A restore or a clone from a snapshot moves its expiry to a full default lifetime from now. An expiry never becomes shorter.
  • Expired snapshots. Every 10 minutes the platform deletes expired snapshots, with the rules of a delete by hand. The platform keeps a snapshot that a running workspace or environment uses, or that a pipeline reads.
  • Source deleted. A snapshot stays when its workspace or environment is deleted. The volume then stays too, detached, so that you can restore from it.
  • Delete. You delete one snapshot at a time, as in Delete a snapshot from the lineage.

Quota and limits

Two quota dimensions apply to snapshots. See Quota and requests.

ItemLimit
snapshotsThe number of snapshots of the owner. Each snapshot counts one. Sync points do not count.
diskGbThe disk of all volumes of the owner, also detached volumes. A new snapshot is refused when the disk is already above the limit.
ttl_secs3600 to 31536000 seconds.
Snapshots in progressOne for each workspace or environment.

Tasks

Push a snapshot of a workspace

Reason for the task: Save the files and the definition of a workspace in a snapshot.

Job set-up

Procedure

  1. Push a snapshot of the workspace. Give a note in message and a name in volume.

    Python
    snap = kl.workspaces.take_snapshot(workspace="backend", message="before the refactor", volume="backend-base")print(snap["id"], snap["phase"], snap["expires_at"])
    TypeScript
    const snap = (await kl.workspaces.takeSnapshot({ workspace: "backend", message: "before the refactor", volume: "backend-base" })) as Record<string, unknown>;console.log(snap.id, snap.phase, snap.expires_at);
    Go
    snap, err := kl.Workspaces.TakeSnapshot(kloudlite.TakeWorkspaceSnapshot{Workspace: "backend", Message: "before the refactor", Volume: "backend-base"})if err != nil {    log.Fatal(err)}fmt.Println(snap["id"], snap["phase"], snap["expires_at"])
    Ruby
    snap = kl.workspaces.take_snapshot(workspace: "backend", message: "before the refactor", volume: "backend-base")puts snap.values_at("id", "phase", "expires_at").join(" ")
    Java
    // The SDK returns the answer as raw JSON. Read the fields with your own JSON library.String snap = kl.workspaces().takeSnapshot(new Kloudlite.TakeWorkspaceSnapshot().workspace("backend").message("before the refactor").volume("backend-base"));System.out.println(snap);
    CLI
    kloudlite snapshots push --workspace backend --message "before the refactor" --volume backend-base
  2. Send ttl_secs or never in a raw request in place of step 1, to set the lifetime.

    Python
    ws = kl.workspaces.get(workspace="backend")kl.request("POST", f"/v1/workspaces/{ws['id']}/snapshots", body={"ttl_secs": 604800})
    TypeScript
    const ws = (await kl.workspaces.get({ workspace: "backend" })) as { id: string };await kl.request("POST", `/v1/workspaces/${ws.id}/snapshots`, { ttl_secs: 604800 });
    Go
    ws, err := kl.Workspaces.Get("backend")if err != nil {    log.Fatal(err)}err = kl.Request("POST", fmt.Sprintf("/v1/workspaces/%v/snapshots", ws["id"]), kloudlite.RequestOptions{    Body: map[string]any{"ttl_secs": 604800},})if err != nil {    log.Fatal(err)}
    Ruby
    ws = kl.workspaces.get(workspace: "backend")kl.request("POST", "/v1/workspaces/#{ws['id']}/snapshots", body: { ttl_secs: 604800 })
    Java
    // The path takes the name of the workspace in place of its id.kl.request(new Kloudlite.RawRequest()    .method("POST")    .path("/v1/workspaces/backend/snapshots")    .body("{\"ttl_secs\":604800}"));
    CLI
    kloudlite request POST /v1/workspaces/ws-0a1b2c3d4e5f6a7b/snapshots --body '{"ttl_secs": 604800}'

Close-out

  1. Show the lineage, as in Show the lineage. Make sure that the first row shows your note and the phase ready.

Push a snapshot of an environment

Reason for the task: Save the services and the data of an environment in a snapshot.

Job set-up

Procedure

  1. Push a snapshot of the environment. Use team/name for a team environment, and give volume.

    Python
    snap = kl.environments.take_snapshot(environment="acme/dev", message="before the schema change", volume="dev-data")print(snap["id"], snap["phase"], snap["expires_at"])
    TypeScript
    const snap = (await kl.environments.take_snapshot({ environment: "acme/dev", message: "before the schema change", volume: "dev-data" })) as Record<string, unknown>;console.log(snap.id, snap.phase, snap.expires_at);
    Go
    snap, err := kl.Environments.TakeSnapshot(kloudlite.TakeEnvironmentSnapshot{Environment: "acme/dev", Message: "before the schema change", Volume: "dev-data"})if err != nil {    log.Fatal(err)}fmt.Println(snap["id"], snap["phase"], snap["expires_at"])
    Ruby
    snap = kl.environments.take_snapshot(environment: "acme/dev", message: "before the schema change", volume: "dev-data")puts snap.values_at("id", "phase", "expires_at").join(" ")
    Java
    // The SDK returns the answer as raw JSON. Read the fields with your own JSON library.String snap = kl.environments().takeSnapshot(new Kloudlite.TakeEnvironmentSnapshot().environment("acme/dev").message("before the schema change").volume("dev-data"));System.out.println(snap);
    CLI
    kloudlite snapshots push --environment acme/dev --message "before the schema change" --volume dev-data

Close-out

  1. Show the lineage, as in Show the lineage. Make sure that the first row shows your note and the phase ready.

Troubleshooting

SymptomPossible causeCorrective action
409 with snapshots: 20 of 20 in use; request more under QuotaThe owner used all the snapshots of the quota. The numbers are examples.Delete a snapshot, or request more quota.
409 with diskGb: 120 of 100 in use; request more under QuotaThe disk of the owner is above the quota.Delete snapshots or volumes that you do not need.
409 with a snapshot is already being cut for this workspaceAn earlier snapshot or clone of the same source is in progress.Wait until its phase is ready, then push the snapshot again.
409 with not ready yet: no volume for this workspaceThe workspace or the environment has no disk yet.Wait until it is ready, then push the snapshot again.
422 with volume: this volume has no name yet; name it on its first pushThe volume has no name, and the push gave no volume.Push again with volume. See Volumes.
422 with volume go-base: …The name breaks the name rule.Use 1 to 40 characters of a-z, 0-9 and -.
409 with volume go-base already exists; delete it firstAnother volume of the owner has this name.Use a different name, or delete the other volume.
409 with this volume is named go-base, not othervolume differs from the name of the volume.Leave out volume, or give the name of the volume.
409 with the version counter of go-base is busy; retryMany pushes of the volume ran at the same time.Push again.
400 with invalid snapshot bodyThe body is not valid JSON, or a field has the wrong type.Send a JSON object with only the snapshot parameters.
400 with ttl_secs and never are exclusiveThe request gives ttl_secs and never.Give one of them.
422 with ttl_secs must be between 3600 and 31536000ttl_secs is out of range.Give a value in the range.
404 with the volume this worktree is on no longer existsThe volume of the source was deleted.Show the status of the source. Push the snapshot again when it has a volume.