Skip to content

Create Durable Object stubs and send requests

A Durable Object stub is a client Object used to send requests to a remote Durable Object.

OBJECT_NAMESPACE.get(id) creates a Durable Object.

Durable Objects implement E-order semantics. When you make multiple calls to the same Durable Object, it is guaranteed that the calls will be delivered to the remote Durable Object in the order in which you made them. E-order semantics makes many distributed programming problems easier.

However, due to random network disruptions or other transient issues, a Durable Object stub may become disconnected from its remote Durable Object. A disconnected stub is permanently broken. In this scenario, all in-flight calls and future calls will fail with exceptions.

To make new requests to the Durable Object, you must call OBJECT_NAMESPACE.get(id) again to get a new Durable Object stub. There are no ordering guarantees between requests to the new stub compared to the old one. If ordering is not a concern, you can create a new Durable Object for every request.

Terminology

Durable Objects documentation uses several concepts and terms, including:

Term Definition
Durable Objects

The product name, or the collective noun referring to more than one Durable Object instance.

Namespace

A container for a collection of Durable Objects that all share the same Durable Object (class) definition. A single Namespace can have (tens of) millions of Durable Objects. Metrics are scoped per Namespace.

Durable Object

An individual Durable Object. A Durable Object is globally unique (referenced by ID), provides a global point of coordination for all methods/requests sent to it, and has private, persistent storage that is not shared with other Durable Objects within a Namespace.

Stub

An object that refers to a unique Durable Object within a Namespace and allows you to call into that Durable Object via RPC methods or the fetch API. For example, let stub = env.MY_DURABLE_OBJECT.get(id)

actor

A term referring to a unique Durable Object.

instance

See 'actor'.

Durable Object class

The JavaScript class that defines the methods (RPC) and handlers (fetch, alarm) as part of your Durable Object, and/or an optional constructor. All Durable Objects within a single Namespace share the same class definition.

Storage Backend

By default, a Durable Object class can use Storage API that leverages a key-value storage backend. New Durable Object classes can opt-in to using a SQLite storage backend.

Storage API

The transactional and strongly consistent (serializable) Storage API for persisting data within each Durable Object instance. State stored within a unique DO instance is "private" to that Durable Object, and not accessible from other Durable Objects.

Storage API includes key-value (KV) API, SQL API, and point-in-time-recovery (PITR) API.

  • Durable Object classes with the key-value storage backend can use KV API.
  • Durable Object classes with the SQLite storage backend can use KV API, SQL API, and PITR API.
KV API

API methods part of Storage API that support persisting key-value data.

SQL API

API methods part of Storage API that support SQL querying.

Migration

A Durable Object migration is a mapping process from a class name to a runtime state. Initiate a Durable Object migration when you need to:

  • Create a new Durable Object class.
  • Rename a Durable Object class.
  • Delete a Durable Object class.
  • Transfer an existing Durable Objects class.
Alarm

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.

Get a Durable Object stub

let durableObjectStub = OBJECT_NAMESPACE.get(id);

Parameters

  • id DurableObjectId
    • An ID constructed using newUniqueId(), idFromName(), or idFromString() on this Durable Object namespace. For details, refer to Access a Durable Object .

    • This method constructs an Object, which is a local client that provides access to a remote Object.

    • If the remote Object does not already exist, it will be created. Thus, there will always be an Object accessible from the stub.

    • This method always returns the Object immediately, before it has connected to the remote Object. This allows you to begin making requests to the Object right away, without waiting for a network round trip.

Call a Durable Object

You can call a Durable Object by:

Call RPC methods

To use RPC, a Durable Objects class must extend the built-in type DurableObject. Then, public methods on a Durable Objects class are exposed as RPC methods, which you can call from a Durable Object stub in a Worker. All RPC calls are asynchronous, accept and return serializable types, and propagate exceptions to the caller without a stack trace. Refer to Workers RPC for complete details.

import { DurableObject } from "cloudflare:workers";
export class Counter extends DurableObject {
async increment(amount = 1) {
let value: number = (await this.ctx.storage.get("value")) || 0;
value += amount;
this.ctx.storage.put("value", value);
return value;
}
}
// A Worker calling a Durable Object
let durableObjectStub = env.COUNTERS.get(id);
let response = await durableObjectStub.increment();

Refer to Build a Counter for a full example.

Send HTTP requests

let response = await durableObjectStub.fetch(request);
// Alternatively, passing a URL directly:
let response = await durableObjectStub.fetch(url, options);

The url passed to the fetch() handler of your Durable Object must be a well-formed URL, but does not have to be a publicly-resolvable hostname. You can:

  • Pass the client Request directly into the fetch() handler as is.
  • Use an internal URL scheme, such as http://do/some-path, as the url parameter in the fetch() handler. This allows you to construct your own path or query parameter based approach to sharing state between your client-facing Worker and your Durable Object.
  • Alternatively, you can construct your own Request object, which allows you to use a Headers object to pass in key-value pairs, representing data you wish to pass to your Durable Objects.

The example below shows you how to construct your own Request object:

// Constructing a new Request and passing metadata to the Durable Object via headers
let doReq = new Request("http://do/write", { headers: { "user-id": userId }})
let resp = await durableObjectStub.fetch(doReq)
// Alternatively, using URL query params or paths
let resp = await durableObjectStub.fetch(`http://do/write?userId=${userId}`)

List Durable Objects

The Cloudflare REST API supports retrieving a list of Durable Objects within a Durable Object namespace and a list of namespaces associated with an account.