containerd snapshots are how your container images are stored on disk, and managing them is key to preventing your disk from filling up.

Let’s look at a busy system running containers. We’re using containerd, and you’ve got a bunch of images pulled down, maybe for different environments or testing. Each image is made up of layers, and containerd uses a snapshotting mechanism to store these layers efficiently. When a container runs, it gets its own writable layer on top of the read-only image layers.

Here’s ubuntu:latest being pulled and a container started from it:

# Pull the image
ctr images pull docker.io/library/ubuntu:latest

# Inspect the image layers
ctr images inspect docker.io/library/ubuntu:latest

# List available snapshots
ctr snapshots list

# Run a container (this creates a writable snapshot for the container's filesystem)
ctr run --rm docker.io/library/ubuntu:latest my-container

# List snapshots again - notice a new one for the container
ctr snapshots list

You’ll see output detailing the image digests, the manifest, and then the snapshot IDs. The key takeaway is that each image layer isn’t just a file; it’s managed as a distinct snapshot. When you run a container, a new, empty writable snapshot is created, linked to the read-only image layer snapshots. This is what allows containers to have their own isolated filesystem where changes are recorded.

The problem containerd snapshots solve is efficient storage and sharing of image layers. Instead of each container having a full copy of every image layer it uses, containerd shares the read-only layers across all containers that depend on them. Only the changes made within a running container are stored in its unique writable snapshot. This drastically reduces disk space usage, especially when you have many containers running from similar base images.

The core components involved are:

  • Image Layers: The immutable, read-only layers that make up a container image. These are stored and managed by containerd.
  • Snapshots: The actual on-disk representation of these layers. containerd uses a snapshotter (like overlayfs or native) to manage these.
  • Writable Layer: For each running container, a separate writable snapshot is created. This is where all file system changes made by the container are recorded.

The ctr snapshots command is your primary tool here:

  • ctr snapshots list: Shows all snapshots, including those for images and active containers. You’ll see snapshot IDs, their kinds (e.g., commit, image), and their size.
  • ctr snapshots prune: This is the command to clean up unused snapshots. It removes snapshots that are not currently associated with any running containers or committed images.
  • ctr snapshots usage: Provides a breakdown of disk usage by snapshotter.

The one thing most people don’t realize is that ctr snapshots prune by default only cleans up snapshots that are completely unused. If an image is no longer referenced by any running container but the image itself is still stored locally, its underlying snapshots won’t be pruned. You often need to prune both unused images and their associated snapshots.

To really reclaim space, you’ll typically run ctr images prune first to remove unreferenced images, and then ctr snapshots prune to clean up the now-orphaned snapshots.

# Remove all unreferenced images
ctr images prune

# Remove all unreferenced snapshots
ctr snapshots prune

If you’re consistently running out of space, ensure your container orchestration platform (like Kubernetes) has garbage collection policies configured for images. Kubernetes, when configured correctly, will periodically remove unused images, which in turn allows ctr snapshots prune to do its job more effectively. Without such policies, your disk can fill up with old, unused image layers and their corresponding snapshots.

The next problem you’ll likely encounter is managing the storage driver itself, especially if you’re seeing I/O performance issues or errors related to specific snapshotters.

Want structured learning?

Take the full Containerd course →