To reduce startup latency for Google Kubernetes Engine (GKE) workloads, you can take a snapshot of a running Pod and restore new Pods from it. This document shows you how to create a Pod snapshot policy and trigger a snapshot, either from your workload or manually. For more information about how Pod snapshots work, see About GKE Pod snapshots.
Platform admins and operators and Application developers can use this document to configure snapshot policies and trigger snapshots. For more information about the common roles and example tasks referenced in Google Cloud content, see Common GKE user roles and tasks.
Before you begin
Before you start, make sure that you have performed the following tasks:
- Enable the Google Kubernetes Engine API. Enable Google Kubernetes Engine API
- To use the Google Cloud CLI for this task,
install and then
initialize the
gcloud CLI. If you previously installed the gcloud CLI, get the latest
version by running the
gcloud components updatecommand. Earlier gcloud CLI versions might not support running the commands in this document.
- Complete the prerequisites and enable Pod snapshots on your cluster. For more information about preparing your cluster and storage, see Prepare for Pod snapshots.
Create a snapshot policy
To enable snapshots for a Pod, create a PodSnapshotPolicy custom resource with a selector that matches the Pod's labels:
Save the following manifest as
example-pod-snapshot-policy.yaml. This example creates a policy that applies to Pods with theapp: my-applabel. The policy uses theexample-pod-snapshot-storage-configPodSnapshotStorageConfig custom resource, which you created in Prepare for Pod snapshots, to define the snapshot storage location:apiVersion: podsnapshot.gke.io/v1 kind: PodSnapshotPolicy metadata: name: example-pod-snapshot-policy namespace: NAMESPACE spec: storageConfigName: example-pod-snapshot-storage-config selector: matchLabels: app: my-app triggerConfig: type: TRIGGER_TYPE postCheckpoint: resumeReplace the following:
NAMESPACE: the namespace for your Pods. Use the same namespace that you granted Cloud Storage access to in Prepare for Pod snapshots.TRIGGER_TYPE: the type of trigger. Supported values areworkloadfor workload-based triggers ormanualfor on-demand snapshots.
In this example, the
postCheckpoint: resumesetting keeps the Pod running after GKE takes the snapshot.For a complete list of the fields that you can configure, see the PodSnapshotPolicy specification.
Apply the manifest:
kubectl apply -f example-pod-snapshot-policy.yaml
Configure additional Pod snapshot policy settings
Your PodSnapshotPolicy custom resource also supports optional settings beyond the required selector, storage configuration, and trigger. These additional settings control what each snapshot captures, how long GKE keeps snapshots, and how GKE groups snapshots for restores:
Snapshot scope: to specify which parts of the Pod state to capture in the snapshot, configure the
spec.snapshotScopefield. Supported values arewhole-pod(default) androotfs-only. Thewhole-podscope captures the entire Pod, including application state, memory, and file systems. Therootfs-onlyscope captures only the container root file system. Therootfs-onlyscope requires GKE version 1.35.3-gke.1031000 or later.Automatic cleanup: to automatically clean up old PodSnapshot custom resources, configure a retention policy by using the
spec.retentionConfigfield. You can specify a duration by using thelastAccessTimeoutfield—for example,7d. After this duration elapses, GKE deletes the snapshot.Snapshot grouping: to isolate snapshots taken in similar environments but in different contexts, specify grouping labels in the
spec.snapshotGroupingRulesfield. For example, in a multi-tenant scenario where the base Pod is the same for all users, you can isolate the snapshots by user or group. During a restore, GKE selects a snapshot only from the same label group. For more information about how this grouping affects compatibility matching during restoration, see Grouping rules matching.
You can configure the snapshot scope, retention, and grouping settings independently. The following example shows all three settings in a PodSnapshotPolicy custom resource:
# Multiple lines are omitted here
spec:
snapshotScope: rootfs-only
retentionConfig:
lastAccessTimeout: 7d
snapshotGroupingRules:
groupByLabelValue:
labels: ["tenant", "environment"]
groupRetentionPolicy:
maxSnapshotCountPerGroup: 5
For a complete list of the fields that you can configure, see the PodSnapshotPolicy specification.
Optimize snapshot size
Larger snapshots take longer to save and restore. Before you trigger a snapshot, reduce its size by deleting any temporary files or application state that your application doesn't need after GKE restores the Pod from the snapshot.
With the default whole-pod snapshot scope, GKE Sandbox captures the entire
state of all containers, including the following:
- Application state, such as memory and registers
- Changes to the root file system and
tmpfsmounts (includingemptyDirvolumes) - Kernel state, such as open file descriptors, threads, and sockets
Optimizing snapshot size is particularly important for workloads like large
language models (LLMs). LLM servers often download model weights into local
storage (rootfs or tmpfs) before loading them into the GPU. When you take a
snapshot, GKE Sandbox saves both the GPU state and the model weight files.
In this scenario, if the model is 100 GB, then the resulting snapshot is
approximately 200 GB (100 GB of model files, plus 100 GB
representing the GPU state). After the application loads the model weights into
the GPU, it often doesn't need the files on the file system to run. By deleting
these model files before you trigger the snapshot, you can reduce the snapshot
size by half and restore the application with significantly lower latency.
Trigger a snapshot
Choose one of the following methods to trigger a snapshot:
Workload trigger: use this method when you can modify your application to signal that it's ready for a snapshot—for example, after initialization completes. This method is best for improving the startup latency of horizontally scaling workloads. A workload trigger runs only once in a workload cycle.
Manual trigger: use this method when you can't modify your application to signal readiness, or when you want on-demand snapshots of a specific Pod. You can create a manual trigger as many times as you need.
Trigger a snapshot from a workload
To trigger a snapshot from within your application code, configure your
application to send a signal when it's ready for a snapshot. To signal
readiness, write the value 1 to the /proc/gvisor/checkpoint file—for
example, by running the echo 1 > /proc/gvisor/checkpoint command. The write
operation starts the snapshot process asynchronously and returns immediately.
Reading from the same file descriptor blocks the reading process until the
snapshot or restore operation completes and the workload is ready to resume.
Before you trigger a snapshot from a workload, make sure that a
snapshot policy selects the Pod. The value of the triggerConfig.type
field in that policy must be set to workload.
The exact usage varies depending on your application, but the following example shows a snapshot trigger for a Python application. To trigger a snapshot from this example workload, follow these steps:
Save the following manifest as
my-app.yaml. In this example, theapp: my-applabel matches the selector in the example snapshot policy, and theruntimeClassName: gvisorsetting runs the Pod in GKE Sandbox:apiVersion: v1 kind: Pod metadata: name: my-app namespace: NAMESPACE labels: app: my-app spec: serviceAccountName: SERVICEACCOUNT_NAME runtimeClassName: gvisor containers: - name: my-container image: python:3.10-slim command: ["python3", "-c"] args: - | import time def trigger_snapshot(): try: with open("/proc/gvisor/checkpoint", "r+") as f: f.write("1") res = f.read().rstrip() print(f"GKE Pod Snapshot: {res}") except FileNotFoundError: print("GKE Pod Snapshot file does not exist -- " "Pod Snapshots is disabled") return i = 0 while True: print(f"Count: {i}", flush=True) if (i == 20): # Simulate readiness at the 20th count trigger_snapshot() i += 1 time.sleep(1) resources: limits: cpu: "500m" memory: "512Mi" requests: cpu: "250m" memory: "256Mi"Replace the following:
NAMESPACE: the namespace for your Pods.SERVICEACCOUNT_NAME: the name of the ServiceAccount object that you granted Cloud Storage access to in Prepare for Pod snapshots.
Deploy the application:
kubectl apply -f my-app.yamlAfter the application starts and signals that it's ready, GKE Sandbox takes the snapshot. To confirm that the snapshot succeeded, see Verify snapshots.
Trigger a snapshot manually
Before you manually trigger a snapshot, make sure that the target Pod is running
and that a snapshot policy selects the Pod. The value of the
triggerConfig.type field in that policy must be set to manual.
To manually trigger an on-demand snapshot for a specific Pod, create a PodSnapshotManualTrigger custom resource by following these steps:
Save the following manifest as
example-manual-trigger.yaml. This example triggers a snapshot for a Pod namedmy-pod:apiVersion: podsnapshot.gke.io/v1 kind: PodSnapshotManualTrigger metadata: name: example-manual-trigger namespace: NAMESPACE spec: targetPod: my-podReplace
NAMESPACEwith the namespace for your Pods.Apply the manifest:
kubectl apply -f example-manual-trigger.yamlTo confirm that the snapshot triggered successfully, check the
statussection of the PodSnapshotManualTrigger custom resource:kubectl get podsnapshotmanualtriggers.podsnapshot.gke.io \ example-manual-trigger \ --namespace NAMESPACE -o yamlReplace
NAMESPACEwith the namespace for your Pods.If the trigger succeeded, then the
status.conditionsfield shows that the checkpoint completed and thestatus.snapshotCreatedfield shows the name of the created PodSnapshot custom resource.
Verify snapshots
To confirm that GKE took a snapshot, check the event history for
GKEPodSnapshotting events:
kubectl get events \
-o custom-columns=NAME:involvedObject.name,CREATIONTIME:.metadata.creationTimestamp,REASON:.reason,MESSAGE:.message \
--namespace NAMESPACE \
--field-selector involvedObject.name=POD_NAME,reason=GKEPodSnapshotting
Replace the following:
NAMESPACE: the namespace for your Pods.POD_NAME: the name of your Pod.
The output is similar to the following:
NAME CREATIONTIME REASON MESSAGE
default/5b449f9c7c-bd7pc 2025-11-05T16:25:11Z GKEPodSnapshotting Successfully checkpointed the pod to PodSnapshot
The MESSAGE column shows Successfully checkpointed the pod to PodSnapshot,
which confirms that GKE saved the Pod state to a PodSnapshot
custom resource. To view and manage your PodSnapshot custom resources, see
Manage snapshots.