You can now create a client (a Durable Object stub) to a Durable Object with the new getByName method, removing the need to convert Durable Object names to IDs and then create a stub.
// Before: (1) translate name to ID then (2) get a client const objectId = env.MY_DURABLE_OBJECT.idFromName("foo"); // or .newUniqueId()const stub = env.MY_DURABLE_OBJECT.get(objectId); // Now: retrieve client to Durable Object directly via its name const stub = env.MY_DURABLE_OBJECT.getByName("foo");// Use client to send request to the remote Durable Objectconst rpcResponse = await stub.sayHello();
Each Durable Object has a globally-unique name, which allows you to send requests to a specific object from anywhere in the world. Thus, a Durable Object can be used to coordinate between multiple clients who need to work together. You can have billions of Durable Objects, providing isolation between application tenants.
The @cloudflare/actors library is a new SDK for Durable Objects and provides a powerful set of abstractions for building real-time, interactive, and multiplayer applications on top of Durable Objects. With beta usage and feedback, @cloudflare/actors will become the recommended way to build on Durable Objects and draws upon Cloudflare's experience building products/features on Durable Objects.
The name "actors" originates from the actor programming model, which closely ties to how Durable Objects are modelled.
The @cloudflare/actors library includes:
Storage helpers for querying embeddeded, per-object SQLite storage
Storage helpers for managing SQL schema migrations
Alarm helpers for scheduling multiple alarms provided a date, delay in seconds, or cron expression
Actor class for using Durable Objects with a defined pattern
Durable Objects Workers API ↗︎ is always available for your application as needed
Storage and alarm helper methods can be combined with any Javascript class ↗︎ that defines your Durable Object, i.e, ones that extend DurableObject including the Actor class.
import { Storage } from "@cloudflare/actors/storage";export class ChatRoom extends DurableObject<Env> { storage: Storage; constructor(ctx: DurableObjectState, env: Env) { super(ctx, env) this.storage = new Storage(ctx.storage); this.storage.migrations = [{ idMonotonicInc: 1, description: "Create users table", sql: "CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY)" }] } async fetch(request: Request): Promise<Response> { // Run migrations before executing SQL query await this.storage.runMigrations(); // Query with SQL template let userId = new URL(request.url).searchParams.get("userId"); const query = this.storage.sql`SELECT * FROM users WHERE id = ${userId};` return new Response(`${JSON.stringify(query)}`); }}
@cloudflare/actors library introduces the Actor class pattern. Actor lets you access Durable Objects without writing the Worker that communicates with your Durable Object (the Worker is created for you). By default, requests are routed to a Durable Object named "default".
export class MyActor extends Actor<Env> { async fetch(request: Request): Promise<Response> { return new Response('Hello, World!') }}export default handler(MyActor);
You can route to different Durable Objects by name within your Actor class using nameFromRequest ↗︎.
export class MyActor extends Actor<Env> { static nameFromRequest(request: Request): string { let url = new URL(request.url); return url.searchParams.get("userId") ?? "foo"; } async fetch(request: Request): Promise<Response> { return new Response(`Actor identifier (Durable Object name): ${this.identifier}`); }}export default handler(MyActor);
For more examples, check out the library README ↗︎. @cloudflare/actors library is a place for more helpers and built-in patterns, like retry handling and Websocket-based applications, to reduce development overhead for common Durable Objects functionality. Please share feedback and what more you would like to see on our Discord channel ↗︎.
You can now create Durable Objects using
Python Workers. A Durable Object is a special kind of
Cloudflare Worker which uniquely combines compute with storage, enabling stateful
long-running applications which run close to your users. For more info see
here.
You can define a Durable Object in Python in a similar way to JavaScript:
Durable Objects can now be used with zero commitment on the Workers Free plan allowing you to build AI agents with Agents SDK, collaboration tools, and real-time applications like chat or multiplayer games.
Durable Objects let you build stateful, serverless applications with millions of tiny coordination instances that run your application code alongside (in the same thread!) your durable storage. Each Durable Object can access its own SQLite database through a Storage API. A Durable Object class is defined in a Worker script encapsulating the Durable Object's behavior when accessed from a Worker. To try the code below, click the button:
import { DurableObject } from "cloudflare:workers";// Durable Objectexport class MyDurableObject extends DurableObject { ... async sayHello(name) { return `Hello, ${name}!`; }}// Workerexport default { async fetch(request, env) { // Every unique ID refers to an individual instance of the Durable Object class const id = env.MY_DURABLE_OBJECT.idFromName("foo"); // A stub is a client used to invoke methods on the Durable Object const stub = env.MY_DURABLE_OBJECT.get(id); // Methods on the Durable Object are invoked via the stub const response = await stub.sayHello("world"); return response; },};
Free plan limits apply to Durable Objects compute and storage usage. Limits allow developers to build real-world applications, with every Worker request able to call a Durable Object on the free plan.
SQLite in Durable Objects is now generally available (GA) with 10GB SQLite database per Durable Object. Since the public beta ↗︎ in September 2024, we've added feature parity and robustness for the SQLite storage backend compared to the preexisting key-value (KV) storage backend for Durable Objects.
SQLite-backed Durable Objects are recommended for all new Durable Object classes, using new_sqlite_classesWrangler configuration. Only SQLite-backed Durable Objects have access to Storage API's SQL and point-in-time recovery methods, which provide relational data modeling, SQL querying, and better data management.
export class MyDurableObject extends DurableObject { sql: SqlStorage constructor(ctx: DurableObjectState, env: Env) { super(ctx, env); this.sql = ctx.storage.sql; } async sayHello() { let result = this.sql .exec("SELECT 'Hello, World!' AS greeting") .one(); return result.greeting; }}
KV-backed Durable Objects remain for backwards compatibility, and a migration path from key-value storage to SQL storage for existing Durable Object classes will be offered in the future.