Durable Objects provide low-latency coordination and consistent storage for the Workers platform. Use the API to manage Durable Object namespaces.
Overview
Access the Durable Objects API:
import Cloudflare from 'cloudflare';
const client = new Cloudflare({
apiToken: process.env.CLOUDFLARE_API_TOKEN,
});
// Access Durable Objects resources
const durableObjects = client.durableObjects;
Namespaces
Durable Object namespaces are containers for Durable Object instances.
List namespaces
Retrieve all Durable Object namespaces in your account.
for await (const namespace of client.durableObjects.namespaces.list({
account_id: '023e105f4ecef8ad9ca31a8372d0c353',
})) {
console.log(namespace);
}
Your Cloudflare account ID
Page number for pagination
Number of namespaces per page (default: 20, max: 100)
The Worker script that defines the Durable Object class
The exported class name in the Worker script
Creating Durable Objects
Durable Objects are created through Worker bindings. You define the class in your Worker script and bind it using migrations.
Example: Define a Durable Object class
In your Worker script:
export class Counter {
constructor(state, env) {
this.state = state;
}
async fetch(request) {
let value = (await this.state.storage.get('value')) || 0;
value++;
await this.state.storage.put('value', value);
return new Response(value.toString());
}
}
When deploying your Worker, configure Durable Object bindings:
const version = await client.workers.beta.workers.versions.create(
workerId,
{
account_id: accountId,
main_module: 'worker.mjs',
compatibility_date: '2024-03-01',
bindings: [
{
type: 'durable_object_namespace',
name: 'COUNTER',
class_name: 'Counter',
script_name: 'my-worker',
},
],
modules: [
{
name: 'worker.mjs',
content_type: 'application/javascript+module',
content_base64: Buffer.from(scriptContent).toString('base64'),
},
],
}
);
Set to ‘durable_object_namespace’
The binding name (accessible as env.COUNTER in your Worker)
The exported Durable Object class name
The Worker script that exports the class (defaults to current script)
Migrations
When deploying Workers with Durable Objects, you need to specify migrations to create, rename, or delete Durable Object classes.
Example: Create a new Durable Object class
const version = await client.workers.beta.workers.versions.create(
workerId,
{
account_id: accountId,
main_module: 'worker.mjs',
compatibility_date: '2024-03-01',
migrations: {
new_classes: ['Counter'],
},
bindings: [
{
type: 'durable_object_namespace',
name: 'COUNTER',
class_name: 'Counter',
},
],
modules: [...],
}
);
Array of class names to create
Array of objects with ‘from’ and ‘to’ properties for renaming classes
Array of class names to delete
Array of class names to create with SQLite storage
Example: Rename a Durable Object class
const version = await client.workers.beta.workers.versions.create(
workerId,
{
account_id: accountId,
main_module: 'worker.mjs',
compatibility_date: '2024-03-01',
migrations: {
renamed_classes: [
{
from: 'Counter',
to: 'CounterV2',
},
],
},
bindings: [...],
modules: [...],
}
);
Using Durable Objects in Workers
Once configured, access Durable Objects from your Worker:
export default {
async fetch(request, env) {
// Get a Durable Object ID
const id = env.COUNTER.idFromName('global-counter');
// Get the Durable Object stub
const stub = env.COUNTER.get(id);
// Send a request to the Durable Object
const response = await stub.fetch(request);
return response;
},
};
export class Counter {
constructor(state, env) {
this.state = state;
}
async fetch(request) {
let value = (await this.state.storage.get('value')) || 0;
value++;
await this.state.storage.put('value', value);
return new Response(value.toString());
}
}
Best practices
- Unique IDs: Use
idFromName() for deterministic IDs or newUniqueId() for random IDs
- State management: Use
state.storage for persistent data with strong consistency
- Concurrency: Durable Objects handle one request at a time, ensuring strong consistency
- Migrations: Always specify migrations when adding, renaming, or removing Durable Object classes
- SQLite storage: Use
new_sqlite_classes for SQL-based storage in Durable Objects