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
[DO] Adding explanation on duration billing of a DO. (#22023)
* Adding explanation on duration billing of a DO.
Removing glossary term for request context until
later.
* Implementing feedback from Frederik
* Updating wording
* Apply suggestions from code review
Co-authored-by: Vy Ton <[email protected]>
---------
Co-authored-by: Vy Ton <[email protected]>
Copy file name to clipboardExpand all lines: src/content/docs/durable-objects/api/state.mdx
+2-2Lines changed: 2 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -53,11 +53,11 @@ export class MyDurableObject extends DurableObject {
53
53
54
54
### `waitUntil`
55
55
56
-
`waitUntil` waits until the promise which is passed as a parameter resolves and can extend a <GlossaryTooltipterm="request context">request context</GlossaryTooltip> up to 30 seconds after the last client disconnects.
56
+
`waitUntil` waits until the promise which is passed as a parameter resolves and can extend a request context up to 30 seconds after the last client disconnects.
57
57
58
58
:::note[`waitUntil` is not necessary]
59
59
60
-
The request context for a Durable Objects extends at least 60 seconds after the last client disconnects. So `waitUntil` is not necessary. It remains part of the `DurableObjectState` interface to remain compatible with [Workers Runtime APIs](/workers/runtime-apis/context/#waituntil).
60
+
A Durable Object will remain active for at least 70 seconds after the last client disconnects if the Durable Object is still waiting on any ongoing work or outbound I/O. So `waitUntil` is not necessary. It remains part of the `DurableObjectState` interface to remain compatible with [Workers Runtime APIs](/workers/runtime-apis/context/#waituntil).
Copy file name to clipboardExpand all lines: src/content/docs/durable-objects/platform/pricing.mdx
+21-1Lines changed: 21 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -130,4 +130,24 @@ Yes, although minimal. Empty tables can consume at least a few kilobytes, based
130
130
131
131
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.
132
132
133
-
The metadata remains in the Durable Object until you call [`deleteAll()`](/durable-objects/api/storage-api/#deleteall).
133
+
The metadata remains in the Durable Object until you call [`deleteAll()`](/durable-objects/api/storage-api/#deleteall).
134
+
135
+
### When does a Durable Object incur duration charges?
136
+
137
+
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.
138
+
139
+
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.
140
+
141
+
- For example, if an object calls `fetch()` and awaits the response, it is considered to be waiting for I/O, and so cannot hibernate.
142
+
143
+
- 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.
144
+
145
+
- 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.
146
+
147
+
- 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.
148
+
149
+
150
+
151
+
Once a Durable Object has been in a hibernatable state for 10 consecutive seconds, it hibernates, and duration billing stops.
152
+
153
+
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.
Copy file name to clipboardExpand all lines: src/content/glossary/durable-objects.yaml
+3-4Lines changed: 3 additions & 4 deletions
Original file line number
Diff line number
Diff line change
@@ -60,10 +60,6 @@ entries:
60
60
general_definition: |-
61
61
A Durable Object alarm is a mechanism that allows you to schedule the Durable Object to be woken up at a time in the future.
62
62
63
-
- term: "request context"
64
-
general_definition: |-
65
-
The duration of time that a Durable Object is processing a request, such as a remote procedure call. [Compute duration charges](/durable-objects/platform/pricing) are incurred for the duration of the request context. Note that the request context for a Durable Object extends at least 60 seconds after the last client disconnects.
66
-
67
63
- term: "input gate"
68
64
general_definition: |-
69
65
While a storage operation is executing, no events shall be delivered to a Durable Object except for storage completion events. Any other events will be deferred until such a time as the object is no longer executing JavaScript code and is no longer waiting for any storage operations. We say that these events are waiting for the "input gate" to open.
@@ -76,3 +72,6 @@ entries:
76
72
general_definition: |-
77
73
A bookmark is a mostly alphanumeric string like `0000007b-0000b26e-00001538-0c3e87bb37b3db5cc52eedb93cd3b96b` which represents a specific state of a SQLite database at a certain point in time. Bookmarks are designed to be lexically comparable: a bookmark representing an earlier point in time compares less than one representing a later point, using regular string comparison.
78
74
75
+
# - term: "request context"
76
+
# general_definition: |-
77
+
# The duration of time that a Durable Object is processing a request, such as a remote procedure call. [Compute duration charges](/durable-objects/platform/pricing) are incurred for the duration of the request context. Note that the request context for a Durable Object extends at least 60 seconds after the last client disconnects.
Durable Objects are billed only while the Durable Object is active (includes the <GlossaryTooltipterm="request context"> request context</GlossaryTooltip>).
11
+
Durable Objects are billed for duration while the Durable Object is active and running in memory. Requests to a Durable Object keep it active or creates the object if it was inactive, not in memory.
@@ -32,7 +32,7 @@ await durableObjectStub.cat(); // billed as a request
32
32
33
33
<sup>3</sup> Application level auto-response messages handled by [`state.setWebSocketAutoResponse()`](/durable-objects/best-practices/websockets/) will not incur additional wall-clock time, and so they will not be charged.
34
34
35
-
<sup>4</sup> Duration is billed in wall-clock time as long as the Object is active, but is shared across all requests active on an Object at once. Calling `accept()` on a WebSocket in an Object will incur duration charges for the entire time the WebSocket is connected. The request context of a Durable Object is evaluated every 70 seconds and the context is ended if it has been active for 70 seconds. If you prefer, use the [WebSocket Hibernation API](/durable-objects/best-practices/websockets/#websocket-hibernation-api) to avoid incurring durationcharges once all event handlers finish running.
35
+
<sup>4</sup> Duration is billed in wall-clock time as long as the Object is active, but is shared across all requests active on an Object at once. Calling `accept()` on a WebSocket in an Object will incur duration charges for the entire time the WebSocket is connected. It is recommended to use the WebSocket Hibernation API to avoid incurring duration charges once all event handlers finish running. Note that the Durable Object will remain active for 10 seconds after the last client disconnects. For a complete explanation, refer to [When does a Durable Object incur duration charges?](/durable-objects/platform/pricing/#when-does-a-durable-object-incur-duration-charges).
36
36
37
37
<sup>5</sup> Duration billing charges for the 128 MB of memory your Durable Object is allocated, regardless of actual usage. If your account creates many instances of a single Durable Object class, Durable Objects may run in the same isolate on the same physical machine and share the 128 MB of memory. These Durable Objects are still billed as if they are allocated a full 128 MB of memory.
0 commit comments