Skip to content

Commit 99c7363

Browse files
committed
Add docs and changelog for containers snapshots
1 parent eee7e2f commit 99c7363

5 files changed

Lines changed: 284 additions & 9 deletions

File tree

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
---
2+
title: Snapshot and restore Container state
3+
description: Persist point-in-time container filesystem with experimental snapshot APIs.
4+
products:
5+
- containers
6+
date: 2026-03-26
7+
---
8+
9+
import { TypeScriptExample, WranglerConfig } from "~/components";
10+
11+
[Containers](/containers/) now support experimental snapshot APIs for saving and restoring point-in-time filesystem state. Create a snapshot first, then pass it back to `start()` to restore files after container sleep, restart, or handoff to another Durable Object.
12+
13+
Turn on the `experimental` [compatibility flag](/workers/configuration/compatibility-flags/) before you use snapshot APIs:
14+
15+
<WranglerConfig>
16+
17+
```toml
18+
compatibility_flags = ["experimental"]
19+
```
20+
21+
</WranglerConfig>
22+
23+
You can snapshot a single directory with `snapshotDirectory()` or the full container with `snapshotContainer()`:
24+
25+
<TypeScriptExample filename="src/index.ts">
26+
27+
```ts
28+
const directorySnapshot = await this.ctx.container.snapshotDirectory({
29+
dir: "/app/foo",
30+
});
31+
32+
const containerSnapshot = await this.ctx.container.snapshotContainer({});
33+
34+
this.ctx.container.start({
35+
containerSnapshot,
36+
directorySnapshots: [{ snapshot: directorySnapshot }],
37+
});
38+
```
39+
40+
</TypeScriptExample>
41+
42+
Snapshots are immutable. Directory snapshots can be restored to a different `mountPoint`. `snapshotContainer({ memory: true })` can also capture memory. You can restore multiple directory snapshots in one `start()` call, but only one container snapshot.
43+
44+
For more information, refer to [Snapshots](/containers/platform-details/snapshots/) and [Durable Object Container](/durable-objects/api/container/).

src/content/docs/containers/faq.mdx

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -89,11 +89,9 @@ See [image management documentation](/containers/platform-details/image-manageme
8989

9090
## Is disk persistent? What happens to my disk when my container sleeps?
9191

92-
All disk is ephemeral. When a Container instance goes to sleep, the next time
93-
it is started, it will have a fresh disk as defined by its container image.
92+
All disk is ephemeral by default. When a Container instance goes to sleep, the next time it starts, it uses a fresh disk from the container image.
9493

95-
Persistent disk is something the Cloudflare team is exploring in the future, but
96-
is not slated for the near term.
94+
If you need point-in-time filesystem state, create and restore an experimental snapshot. Snapshots are immutable, so later file changes require a new snapshot. For more information, refer to [Snapshots](/containers/platform-details/snapshots/).
9795

9896
## What happens if I run out of memory?
9997

src/content/docs/containers/platform-details/architecture.mdx

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -98,12 +98,11 @@ When a container instance is going to be shut down, it is sent a `SIGTERM` signa
9898
and then a `SIGKILL` signal after 15 minutes. You should perform any necessary
9999
cleanup to ensure a graceful shutdown in this time.
100100

101-
#### Persistent disk
101+
#### Use snapshots
102102

103-
All disk is ephemeral. When a Container instance goes to sleep, the next time
104-
it is started, it will have a fresh disk as defined by its container image.
105-
Persistent disk is something the Cloudflare team is exploring in the future, but
106-
is not slated for the near term.
103+
All disk is ephemeral by default. When a Container instance goes to sleep, the next time it starts, it uses a fresh disk from the container image.
104+
105+
If you need point-in-time filesystem state, create and restore an experimental snapshot. Snapshots are immutable, so later file changes require a new snapshot. For more information, refer to [Snapshots](/containers/platform-details/snapshots/).
107106

108107
## An example request
109108

Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
---
2+
title: Use snapshots
3+
pcx_content_type: how-to
4+
sidebar:
5+
order: 55
6+
description: Persist container filesystem across restarts.
7+
---
8+
9+
import { TypeScriptExample, WranglerConfig } from "~/components";
10+
11+
Snapshots let you save point-in-time filesystem state from a running [Container](/containers/). `snapshotContainer({ memory: true })` can also include container memory.
12+
13+
:::caution[Experimental]
14+
Snapshot APIs require the `experimental` [compatibility flag](/workers/configuration/compatibility-flags/). These APIs may change in backward-incompatible ways.
15+
:::
16+
17+
## Turn on the compatibility flag
18+
19+
Add `experimental` to your Worker's Wrangler configuration before you use snapshot APIs:
20+
21+
<WranglerConfig>
22+
23+
```toml
24+
compatibility_date = "$today"
25+
compatibility_flags = ["experimental"]
26+
```
27+
28+
</WranglerConfig>
29+
30+
## Choose a snapshot type
31+
32+
Use `snapshotDirectory()` to capture one directory. Use `snapshotContainer()` to capture the full container filesystem.
33+
34+
Directory snapshots only capture filesystem contents. Container snapshots can also capture memory when you set `memory: true`.
35+
36+
Both snapshot types are immutable. If you restore a snapshot and then change files, create a new snapshot to persist those changes.
37+
38+
- You can restore multiple directory snapshots in one `start()` call.
39+
- You can restore only one container snapshot in one `start()` call.
40+
- You can restore directory snapshots on top of a container snapshot.
41+
- Snapshot handles are plain data objects, so you can store them and restore them later, even from another Durable Object.
42+
43+
## Create a directory snapshot
44+
45+
Use `snapshotDirectory()` to capture the current contents of a directory in a running container:
46+
47+
<TypeScriptExample filename="src/index.ts">
48+
49+
```ts
50+
export class MyContainer extends DurableObject {
51+
async saveWorkspace() {
52+
return await this.ctx.container.snapshotDirectory({
53+
dir: "/app/workspace",
54+
name: "workspace-checkpoint",
55+
});
56+
}
57+
}
58+
```
59+
60+
</TypeScriptExample>
61+
62+
The `dir` value must be an absolute path. The API returns a serializable snapshot handle that you can store and restore later.
63+
64+
## Create a container snapshot
65+
66+
Use `snapshotContainer()` to capture the full container filesystem:
67+
68+
<TypeScriptExample filename="src/index.ts">
69+
70+
```ts
71+
export class MyContainer extends DurableObject {
72+
async saveContainer() {
73+
return await this.ctx.container.snapshotContainer({
74+
name: "before-upgrade",
75+
memory: true,
76+
});
77+
}
78+
}
79+
```
80+
81+
</TypeScriptExample>
82+
83+
Set `memory: true` to include container memory in the snapshot. The API returns a serializable snapshot handle that you can store and restore later.
84+
85+
:::note[Local development]
86+
`snapshotContainer({ memory: true })` is not supported in [local development](/containers/local-dev/) with `wrangler dev` or `vite dev`. Deploy your Worker to use memory snapshots.
87+
:::
88+
89+
## Restore snapshots
90+
91+
Pass saved snapshot handles to `this.ctx.container.start()` when you start the container:
92+
93+
<TypeScriptExample filename="src/index.ts">
94+
95+
```ts
96+
const directorySnapshot = await this.ctx.container.snapshotDirectory({
97+
dir: "/app/foo",
98+
});
99+
100+
const containerSnapshot = await this.ctx.container.snapshotContainer({});
101+
102+
this.ctx.container.start({
103+
containerSnapshot,
104+
directorySnapshots: [{ snapshot: directorySnapshot }],
105+
});
106+
```
107+
108+
</TypeScriptExample>
109+
110+
If you do not set `mountPoint`, the directory snapshot is restored to the same path that was snapshotted. You can also restore it to a different path:
111+
112+
<TypeScriptExample filename="src/index.ts">
113+
114+
```ts
115+
this.ctx.container.start({
116+
directorySnapshots: [
117+
{
118+
snapshot: directorySnapshot,
119+
mountPoint: "/app/restored-workspace",
120+
},
121+
],
122+
});
123+
```
124+
125+
</TypeScriptExample>
126+
127+
## Understand restore behavior
128+
129+
- Directory snapshots cannot be restored to `/`.
130+
- You can snapshot `/`, but you must restore it to a subdirectory by setting `mountPoint`.
131+
- Nested directory snapshots restore in depth order. If you restore snapshots to `/app` and `/app/data`, `/app` is always restored first.
132+
- Directory snapshots can overlay files from a container snapshot.
133+
134+
## Understand retention
135+
136+
Snapshots currently have an implicit 90-day time-to-live. Each restore refreshes that time-to-live.
137+
138+
You cannot set a custom time-to-live yet.
139+
140+
## Related resources
141+
142+
- [Durable Object Container](/durable-objects/api/container/) - Full `ctx.container` API reference
143+
- [Lifecycle of a Container](/containers/platform-details/architecture/) - Understand startup, sleep, and shutdown behavior

src/content/docs/durable-objects/api/container.mdx

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,26 @@ import {
1313
Type,
1414
MetaInfo,
1515
TypeScriptExample,
16+
WranglerConfig,
1617
} from "~/components";
1718

1819
## Description
1920

2021
When using a [Container-enabled Durable Object](/containers), you can access the Durable Object's associated container via
2122
the `container` object which is on the `ctx` property. This allows you to start, stop, and interact with the container.
2223

24+
:::caution[Experimental snapshot APIs]
25+
`snapshotDirectory()`, `snapshotContainer()`, `directorySnapshots`, and `containerSnapshot` require the `experimental` [compatibility flag](/workers/configuration/compatibility-flags/). These APIs may change in backward-incompatible ways.
26+
27+
<WranglerConfig>
28+
29+
```toml
30+
compatibility_flags = ["experimental"]
31+
```
32+
33+
</WranglerConfig>
34+
:::
35+
2336
:::note
2437
It is likely preferable to use the official `Container` class, which provides helper methods and
2538
a more idiomatic API for working with containers on top of Durable Objects.
@@ -76,11 +89,86 @@ this.ctx.container.start({
7689
- `env`: An object containing environment variables to pass to the container. This is useful for passing configuration values or secrets to the container.
7790
- `entrypoint`: An array of strings representing the command to run in the container.
7891
- `enableInternet`: A boolean indicating whether to enable internet access for the container.
92+
- `directorySnapshots`: An array of objects describing directory snapshots to restore before the container starts. You can restore more than one directory snapshot in a single call.
93+
- `snapshot`: The `ContainerDirectorySnapshot` to restore.
94+
- `mountPoint` (optional): The absolute path where the snapshot is restored. If omitted, the snapshot is restored to its original `dir` path.
95+
- `containerSnapshot`: A full container snapshot to restore before the container starts. You can restore only one container snapshot in a single call.
7996

8097
#### Return values
8198

8299
- None.
83100

101+
#### Understand snapshot restore behavior
102+
103+
- Directory snapshots are restored before the container starts.
104+
- If `mountPoint` is not set, the snapshot is restored to the original `dir` path.
105+
- Directory snapshots cannot be restored to `/`.
106+
- You can snapshot `/`, but that snapshot must be restored to a subdirectory by setting `mountPoint`.
107+
- Nested directory snapshots are restored in depth order. For example, `/app` is restored before `/app/data`.
108+
- Directory snapshots can be restored on top of a container snapshot.
109+
110+
### `snapshotDirectory`
111+
112+
`snapshotDirectory` creates a point-in-time snapshot of a directory in a running container.
113+
114+
<TypeScriptExample filename="index.ts">
115+
116+
```ts
117+
const snapshot = await this.ctx.container.snapshotDirectory({
118+
dir: "/app/workspace",
119+
name: "workspace-checkpoint",
120+
});
121+
```
122+
123+
</TypeScriptExample>
124+
125+
#### Parameters
126+
127+
- `options`: An object with the following properties:
128+
- `dir` (string): An absolute path for the directory to snapshot.
129+
- `name` (optional string): A human-friendly name for the snapshot.
130+
131+
#### Return values
132+
133+
- A promise that resolves to a `ContainerDirectorySnapshot` object with `id`, `size`, `dir`, and optional `name` properties.
134+
135+
#### Notes
136+
137+
- Snapshots are immutable. If you change restored files, create a new snapshot to persist those changes.
138+
- You can serialize the returned snapshot handle and restore it later, including from another Durable Object.
139+
- Snapshot handles currently have an implicit 90-day time-to-live that refreshes when you restore them.
140+
141+
### `snapshotContainer`
142+
143+
`snapshotContainer` creates a point-in-time snapshot of the full running container.
144+
145+
<TypeScriptExample filename="index.ts">
146+
147+
```ts
148+
const snapshot = await this.ctx.container.snapshotContainer({
149+
name: "before-upgrade",
150+
memory: true,
151+
});
152+
```
153+
154+
</TypeScriptExample>
155+
156+
#### Parameters
157+
158+
- `options`: An object with the following properties:
159+
- `memory` (optional boolean): If `true`, include container memory in the snapshot.
160+
- `name` (optional string): A human-friendly name for the snapshot.
161+
162+
#### Return values
163+
164+
- A promise that resolves to a `ContainerSnapshot` object with `id`, `size`, optional `name`, and `memory` properties.
165+
166+
#### Notes
167+
168+
- Container snapshots are immutable.
169+
- `snapshotContainer({ memory: true })` is not supported in [local development](/containers/local-dev/) with `wrangler dev` or `vite dev`. Deploy your Worker to use memory snapshots.
170+
- Snapshot handles currently have an implicit 90-day time-to-live that refreshes when you restore them.
171+
84172
### `destroy`
85173

86174
`destroy` stops the container and optionally returns a custom error message to the `monitor()` error callback.
@@ -207,6 +295,7 @@ await this.ctx.container.interceptOutboundHttp("123.123.123.123/23", worker);
207295
`interceptAllOutboundHttp` routes all outbound HTTP requests from the container through a `WorkerEntrypoint`, regardless of destination.
208296

209297
await this.ctx.container.interceptAllOutboundHttp(worker);
298+
210299
```
211300
212301
#### Parameters
@@ -229,3 +318,5 @@ await this.ctx.container.interceptAllOutboundHttp(worker);
229318
230319
- [Containers](/containers)
231320
- [Get Started With Containers](/containers/get-started)
321+
- [Snapshots](/containers/platform-details/snapshots/)
322+
```

0 commit comments

Comments
 (0)