You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
SImplify the DO lifecycle and pricing docs to be clearer about idle hibernateable state (#24132)
* Update the DO lifecycle and pricing docs to be clearer about idle hibernateable state
* Apply suggestions from code review
* Updating image
* Updating diagram
* Update src/content/docs/durable-objects/concepts/durable-object-lifecycle.mdx
---------
Co-authored-by: Jun Lee <[email protected]>
This section describes the lifecycle of a [Durable Object](/durable-objects/concepts/what-are-durable-objects/).
12
11
13
-
To use a Durable Object you need to create a [Durable Object Stub](/durable-objects/api/stub/). In its simplest form, this looks like the following snippet:
12
+
To use a Durable Object you need to create a [Durable Object Stub](/durable-objects/api/stub/).
13
+
Simply creating the Durable Object Stub does not send a request to the Durable Object, and therefore the Durable Object is not yet instantiated.
14
+
A request is sent to the Durable Object and its lifecycle begins only once a method is invoked on the Durable Object Stub.
14
15
15
-
```ts
16
-
// Assume a DurableObjectNamespace binding MY_DURABLE_OBJECT
17
-
// Every unique ID refers to an individual instance of the Durable Object class
16
+
```js
18
17
constid=env.MY_DURABLE_OBJECT.idFromName("foo");
19
18
conststub=env.MY_DURABLE_OBJECT.get(id);
20
-
```
21
-
22
-
Once we have the Durable Object Stub, we can now invoke methods on the Durable Object. Note that the above two lines do not yet send any request to the remote Durable Object.
23
-
24
-
The following line invokes the `sayHello()` method (which is an [RPC method](/durable-objects/best-practices/create-durable-object-stubs-and-send-requests/#invoke-rpc-methods)) of the Durable Object class bound to the `MY_DURABLE_OBJECT` binding:
25
-
26
-
```ts
27
-
// All invoked methods need to be awaited.
19
+
// Now the request is sent to the remote Durable Object.
28
20
constrpcResponse=awaitstub.sayHello();
29
21
```
30
22
31
-
At this point, the caller sends a request to the Durable Object identified by the stub. The lifecycle of the Durable Object begins.
32
-
33
23
## Durable Object Lifecycle state transitions
34
24
35
25
A Durable Object can be in one of the following states at any moment:
|**Active, in-memory**| The Durable Object runs, in memory, and handles incoming requests. |
40
30
|**Idle, in-memory non-hibernateable**| The Durable Object waits for the next incoming request/event, but does not satisfy the criteria for hibernation. |
41
-
|**Idle, in-memory hibernateable**| The Durable Object waits for the next incoming request/event and satisfies the criteria for hibernation. It is up to the runtime to decide when to hibernate the Durable Object. Currently, it is after 10 seconds of inactivity while in this state. |
42
-
|**Hibernated**| The Durable Object is removed from memory. Hibernated WebSocket connections stay connected.|
43
-
|**Inactive**| The Durable Object is completely removed from the host process and might need to cold start. This is the initial state of all Durable Objects.|
31
+
|**Idle, in-memory hibernateable**| The Durable Object waits for the next incoming request/event and satisfies the criteria for hibernation. It is up to the runtime to decide when to hibernate the Durable Object. Currently, it is after 10 seconds of inactivity while in this state. |
32
+
|**Hibernated**| The Durable Object is removed from memory. Hibernated WebSocket connections stay connected. |
33
+
|**Inactive**| The Durable Object is completely removed from the host process and might need to cold start. This is the initial state of all Durable Objects. |
44
34
45
35
This is how a Durable Object transitions among these states (each state is in a rounded rectangle).
46
36
@@ -52,26 +42,31 @@ At this point the Durable Object is in the **active in-memory state**.
52
42
53
43
If it continuously receives requests or events within 10 seconds of each other, the Durable Object will remain in this state.
54
44
55
-
After 10 seconds of no incoming request or events, the runtime can now hibernate the Durable Object. Hibernation will only occur if **all** of the below are true:
56
-
- No `setTimeout`/`setInterval` scheduled callbacks are set.
57
-
- No in-progress `fetch()` waiting for a remote request exists.
58
-
- No WebSocket standard API is used.
59
-
- No request/event is still being processed.
45
+
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.
46
+
47
+
Hibernation can only occur if **all** of the conditions below are true:
60
48
61
-
If all conditions are met, the Durable Object will transition into a **hibernated** state.
49
+
- No `setTimeout`/`setInterval` scheduled callbacks are set, since there would be no way to recreate the callback after hibernating.
50
+
- No in-progress awaited `fetch()` exists, since it is considered to be waiting for I/O.
51
+
- No WebSocket standard API is used.
52
+
- No request/event is still being processed, because hibernating would mean losing track of the async function which is eventually supposed to return a response to that request.
53
+
54
+
After 10 seconds of no incoming request or event, and all the above conditions satisfied, the Durable Object will transition into the **hibernated** state.
62
55
63
56
:::caution
64
57
When hibernated, the in-memory state is discarded, so ensure you persist all important information in the Durable Object's storage.
65
58
:::
66
59
67
-
If any of the above conditions are false, the Durable Object remains in-memory, in the **idle, in-memory, non-hibernateable** state.
60
+
If any of the above conditions is false, the Durable Object remains in-memory, in the **idle, in-memory, non-hibernateable** state.
68
61
69
-
In case of an incoming request or event while in the **hibernated** state, the `constructor()` will run again, and the corresponding function invoked will run.
62
+
In case of an incoming request or event while in the **hibernated** state, the `constructor()` will run again, and the Durable Object will transition to the **active, in-memory** state and execute the invoked function.
70
63
71
64
While in the **idle, in-memory, non-hibernateable** state, after 70-140 seconds of inactivity (no incoming requests or events), the Durable Object will be evicted entirely from memory and potentially from the Cloudflare host and transition to the **inactive** state.
72
65
73
-
Objects in the **hibernated** state keep their Websocket clients connected, and the runtime decides if and when to move the object to a different host, thus restarting the lifecycle.
66
+
Objects in the **hibernated** state keep their Websocket clients connected, and the runtime decides if and when to transition the object to the **inactive** state (for example deciding to move the object to a different host) thus restarting the lifecycle.
74
67
75
68
The next incoming request or event starts the cycle again.
76
69
77
-
As explained in [When does a Durable Object incur duration charges?](/durable-objects/platform/pricing/#when-does-a-durable-object-incur-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**.
70
+
:::note[Lifecycle states incurring duration charges]
71
+
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).
Copy file name to clipboardExpand all lines: src/content/partials/durable-objects/do-faq-pricing.mdx
+5-14Lines changed: 5 additions & 14 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -4,21 +4,12 @@
4
4
5
5
### When does a Durable Object incur duration charges?
6
6
7
-
A Durable Object incurs duration charges as long as the JavaScript object is held in memory. Once an object has been evicted from memory, the next time it is needed, it will be recreated (calling the constructor again). There are two factors which decide when an object may be evicted from memory: hibernatability and existence of clients.
7
+
A Durable Object incurs duration charges as long as the JavaScript object has to be in memory, either because it is actively handling a request, or because it cannot hibernate.
8
8
9
-
A Durable Object is considered hibernatable any time that it is not waiting for any I/O or callbacks that depend on the in-memory state.
9
+
Once an object has been evicted from memory, the next time it is needed, it will be recreated (calling the constructor again).
10
10
11
-
- For example, if an object calls `fetch()` and awaits the response, it is considered to be waiting for I/O, and so cannot hibernate.
12
-
13
-
- Less obvious to a user, if an object calls `setTimeout()` to schedule a callback in the future - no matter how far in the future - then it is considered non-hibernatable, since there would be no way to recreate the callback after hibernating.
14
-
15
-
- Additionally, if the Durable Object has received an incoming request and has not fully responded yet, then it cannot be hibernated, because hibernating would mean losing track of the async function which is eventually supposed to return a response to that request.
16
-
17
-
- As an exception, a WebSocket request which has explicitly been accepted using the [WebSocket hibernation API](/durable-objects/best-practices/websockets/#websocket-hibernation-api) allows a Durable Object to hibernate even while the WebSocket is still connected.
18
-
19
-
Once a Durable Object has been in a hibernatable state for 10 consecutive seconds, it hibernates, and duration billing stops.
20
-
21
-
Even if a Durable Object never becomes hibernatable, it will still be evicted once all clients have gone away. A Durable Object is considered to have clients if any other Worker currently holds a stub pointing to the Durable Object, or is waiting for a response from the Durable Object. An incoming WebSocket connection counts as a client. If the object is currently responding to an alarm event, this also counts as having a client. When not hibernatable, a Durable Object will be evicted from memory after it has had no client for 70-140 seconds (the exact interval varies). But again, if the object is hibernatable, then the 10-second hibernation timeout takes precedence and the 70-140 second no-client timeout is moot.
11
+
There are several factors that contribute in keeping the Durable Object in memory and keeping it from hibernating or being inactive.
12
+
Find more information in [Lifecycle of a Durable Object](/durable-objects/concepts/durable-object-lifecycle/).
22
13
23
14
### Does an empty table / SQLite database contribute to my storage?
24
15
@@ -28,4 +19,4 @@ Yes, although minimal. Empty tables can consume at least a few kilobytes, based
28
19
29
20
All writes to a SQLite-backed Durable Object stores nominal amounts of metadata in internal tables in the Durable Object, which counts towards your billable storage.
30
21
31
-
The metadata remains in the Durable Object until you call [`deleteAll()`](/durable-objects/api/storage-api/#deleteall).
22
+
The metadata remains in the Durable Object until you call [`deleteAll()`](/durable-objects/api/storage-api/#deleteall).
0 commit comments