Skip to content
Merged
Changes from 3 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
44 changes: 11 additions & 33 deletions src/content/partials/workers/durable_objects_pricing.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,16 @@
{}
---

import { Markdown } from "~/components";
import { Markdown, GlossaryTooltip } from "~/components";

[Durable Objects](/durable-objects/) are only available on the [Workers Paid plan](/workers/platform/pricing/#workers).
[Durable Objects](/durable-objects/) are only available on the [Workers Paid plan](/workers/platform/pricing/#workers), and are billed while the Durable Object is active (including the <GlossaryTooltip term="event context"> event context</GlossaryTooltip>).
Copy link
Contributor

Choose a reason for hiding this comment

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

Not a blocker for this PR, but I'm curious if "event context" is what we want to use. Request context might make more sense. I have used invocation rather than event elsewhere in the docs. CC: @vy-ton

Copy link
Contributor

@vy-ton vy-ton Feb 6, 2025

Choose a reason for hiding this comment

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

Apologies @Oxyjun for getting to this post-merge

I also find request context more clear.

Should we also include The event context for a Durable Objects extends at least 60 seconds after the last client disconnects. mentioned here somewhere on this page below? Otherwise a user could still interpret the removed "Once your Object finishes responding to all requests, it will stop incurring duration charges" to be true.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks - actioning the points here: #19831


| | Paid plan |
| -------------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
| Requests | 1 million, + $0.15/million<br/> Includes HTTP requests, RPC sessions<sup>1</sup>, WebSocket messages<sup>2</sup>, and alarm invocations |
| Duration<sup>3</sup> | 400,000 GB-s, + $12.50/million GB-s<sup>4,5</sup> |

<sup>1</sup> Each [RPC session](/workers/runtime-apis/rpc/lifecycle/) is billed
as one request to your Durable Object. Every [RPC method
call](/durable-objects/best-practices/create-durable-object-stubs-and-send-requests/)
on a [Durable Objects stub](/durable-objects/) is its own RPC session and
therefore a single billed request.
<sup>1</sup> Each [RPC session](/workers/runtime-apis/rpc/lifecycle/) is billed as one request to your Durable Object. Every [RPC method call](/durable-objects/best-practices/create-durable-object-stubs-and-send-requests/) on a [Durable Objects stub](/durable-objects/) is its own RPC session and therefore a single billed request.

RPC method calls can return objects (stubs) extending [`RpcTarget`](/workers/runtime-apis/rpc/lifecycle/#lifetimes-memory-and-resource-management) and invoke calls on those stubs. Subsequent calls on the returned stub are part of the same RPC session and are not billed as separate requests. For example:

Expand All @@ -26,31 +22,13 @@ await foo.baz(); // treated as part of the same RPC session created by calling b
await durableObjectStub.cat(); // billed as a request
```

<sup>2</sup> A request is needed to create a WebSocket connection. There is no
charge for outgoing WebSocket messages, nor for incoming [WebSocket protocol
pings](https://www.rfc-editor.org/rfc/rfc6455#section-5.5.2). For compute
requests billing-only, a 20:1 ratio is applied to incoming WebSocket messages to
factor in smaller messages for real-time communication. For example, 100
WebSocket incoming messages would be charged as 5 requests for billing purposes.
The 20:1 ratio does not affect Durable Object metrics and analytics, which
reflect actual usage.

<sup>3</sup> Application level auto-response messages handled by
[`state.setWebSocketAutoResponse()`](/durable-objects/best-practices/websockets/) will not
<sup>2</sup> A request is needed to create a WebSocket connection. There is no charge for outgoing WebSocket messages, nor for incoming [WebSocket protocol
pings](https://www.rfc-editor.org/rfc/rfc6455#section-5.5.2). For compute requests billing-only, a 20:1 ratio is applied to incoming WebSocket messages to factor in smaller messages for real-time communication. For example, 100 WebSocket incoming messages would be charged as 5 requests for billing purposes. The 20:1 ratio does not affect Durable Object metrics and analytics, which reflect actual usage.

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

<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. Once your
Object finishes responding to all requests, it will stop incurring duration
charges. Calling `accept()` on a WebSocket in an Object will incur duration
charges for the entire time the WebSocket is connected. If you prefer, use
[`state.acceptWebSocket()`](/durable-objects/best-practices/websockets/)
instead, which will stop incurring duration charges once all event handlers
finish running.

<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.
<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. If you prefer, use [`state.acceptWebSocket()`](/durable-objects/best-practices/websockets/) instead, which will stop incurring duration charges once all event handlers finish running.

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