Skip to content
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Durable Objects may occasionally shut down and be replaced with a new instance. This can happen for various reasons, including:
Durable Objects will occasionally shut down and objects are restarted, which will run your Durable Object class constructor. This can happen for various reasons, including:


- New deployments with code updates
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- New deployments with code updates
- New Worker [deployments](/workers/configuration/versions-and-deployments/) with code updates

- Updates to the Workers runtime system
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- Updates to the Workers runtime system
- Lack of requests to an object following the state transitions documented above
- Cloudflare updates to the Workers runtime system

- The runtime deciding to move the Durable Object to a different host
Copy link
Contributor

Choose a reason for hiding this comment

The 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
- Workers runtime decisions on where to host objects


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:
Copy link
Contributor

Choose a reason for hiding this comment

The 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:
When a Durable Object is shut down, the object instance is automatically restarted and new requests are routed to the new instance. In-flight requests are handled as follows:


- **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.
Copy link
Contributor

Choose a reason for hiding this comment

The 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.
- **HTTP requests**: In-flight requests are allowed to finish for up to 30 seconds. However, if a request attempts to access a Durable Object's storage during this grace period, it will be stopped immediately to maintain Durable Objects global uniqueness property.

@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
Copy link
Contributor

Choose a reason for hiding this comment

The 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.