Skip to main content
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);
}
account_id
string
required
Your Cloudflare account ID
page
number
Page number for pagination
per_page
number
Number of namespaces per page (default: 20, max: 100)
id
string
The namespace ID
name
string
The namespace name
script
string
The Worker script that defines the Durable Object class
class
string
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());
  }
}

Example: Configure bindings

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'),
      },
    ],
  }
);
type
string
required
Set to ‘durable_object_namespace’
name
string
required
The binding name (accessible as env.COUNTER in your Worker)
class_name
string
required
The exported Durable Object class name
script_name
string
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: [...],
  }
);
new_classes
array
Array of class names to create
renamed_classes
array
Array of objects with ‘from’ and ‘to’ properties for renaming classes
deleted_classes
array
Array of class names to delete
new_sqlite_classes
array
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

  1. Unique IDs: Use idFromName() for deterministic IDs or newUniqueId() for random IDs
  2. State management: Use state.storage for persistent data with strong consistency
  3. Concurrency: Durable Objects handle one request at a time, ensuring strong consistency
  4. Migrations: Always specify migrations when adding, renaming, or removing Durable Object classes
  5. SQLite storage: Use new_sqlite_classes for SQL-based storage in Durable Objects

Build docs developers (and LLMs) love