-
Notifications
You must be signed in to change notification settings - Fork 11.5k
Adds documentation on DO shutdown #27482
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: production
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||
|---|---|---|---|---|---|---|---|---|
|
|
@@ -39,7 +39,6 @@ Assuming a Durable Object does not run, the first incoming request or event (lik | |||||||
|
|
||||||||
| At this point the Durable Object is in the **active in-memory state**. | ||||||||
|
|
||||||||
|
|
||||||||
| Once all incoming requests or events have been processed, the Durable Object remains idle in-memory for a few seconds either in a hibernateable state or in a non-hibernateable state. | ||||||||
|
|
||||||||
| Hibernation can only occur if **all** of the conditions below are true: | ||||||||
|
|
@@ -68,3 +67,46 @@ The next incoming request or event starts the cycle again. | |||||||
| :::note[Lifecycle states incurring duration charges] | ||||||||
| A Durable Object incurs charges only when it is **actively running in-memory**, or when it is **idle in-memory and non-hibernateable** (indicated as green rectangles in the diagram). | ||||||||
| ::: | ||||||||
|
|
||||||||
| ## Shutdown behavior | ||||||||
|
|
||||||||
| Durable Objects may occasionally shut down and be replaced with a new instance. This can happen for various reasons, including: | ||||||||
|
|
||||||||
| - New deployments with code updates | ||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||
| - Updates to the Workers runtime system | ||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||
| - The runtime deciding to move the Durable Object to a different host | ||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||
|
|
||||||||
| When a Durable Object is shut down, a new instance will come up automatically to handle new requests In-flight requests are handled as follows: | ||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||
|
|
||||||||
| - **HTTP requests**: Requests are allowed to finish for up to 30 seconds. However, if a request attempts to access storage during this grace period, it will be stopped immediately, since storage access is now occurring on the new instance. | ||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
@joshthoward does this also apply to RPC requests? |
||||||||
| - **WebSocket connections**: WebSocket requests are terminated automatically during shutdown. This is so that the new instance can take over the connection as soon as possible. | ||||||||
| - **Other invocations (email, cron)**: Other invocations are treated similarly to HTTP requests. | ||||||||
|
|
||||||||
| It is important to ensure that any services using Durable Objects are designed to handle the possibility of a Durable Object being shut down. | ||||||||
|
|
||||||||
| ### Code updates | ||||||||
|
|
||||||||
| When your Durable Object code is updated, your Worker and Durable Objects are released globally in an eventually consistent manner. This will cause a Durable Object to shut down, with the behavior described above. Updates can also create a situation where a request reaches a new version of your Worker in one location, and calls to a Durable Object still running a previous version elsewhere. Refer to [Code updates](/durable-objects/platform/known-issues/#code-updates) for more information about handling this scenario. | ||||||||
|
|
||||||||
| ### Working without shutdown hooks | ||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's put this in /durable-objects/best-practices/rules-of-durable-objects/#scheduling-and-lifecycle |
||||||||
|
|
||||||||
| Durable Objects do not provide shutdown hooks or lifecycle callbacks that run before shutdown. This is because Cloudflare cannot guarantee these hooks would execute in all cases, and external software may rely too heavily on these (unreliable) hooks. | ||||||||
|
|
||||||||
| Instead of relying on shutdown hooks, you can regularly write to storage to recover gracefully from shutdowns. | ||||||||
|
|
||||||||
| For example, if you are processing a stream of data and need to save your progress, write your position to storage as you go rather than waiting to persist it at the end: | ||||||||
|
|
||||||||
| ```js | ||||||||
| // Good: Write progress as you go | ||||||||
| async processData(data) { | ||||||||
| data.forEach(async (item, index) => { | ||||||||
| await this.processItem(item); | ||||||||
| // Save progress frequently | ||||||||
| await this.ctx.storage.put("lastProcessedIndex", index); | ||||||||
| }); | ||||||||
| } | ||||||||
| ``` | ||||||||
|
|
||||||||
| While this may feel unintuitive, Durable Object storage writes are fast and synchronous, so you can persist state with minimal performance concerns. | ||||||||
|
|
||||||||
| This approach ensures your Durable Object can safely resume from any point, even if it shuts down unexpectedly. | ||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.