---
title: "Durable Objects"
---

> Documentation Index
> Fetch the complete documentation index at: https://ermahgerd-docs.t-bd7662a5eeb4.workers.ermahgerd.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Durable Objects

Use native Durable Objects when one Worker needs named, stateful coordination
with SQLite storage, alarms, RPC, or WebSockets. Deploy them through Wrangler in
the same project as their owning Worker; no platform-specific deployment command
or Ansible application role is involved.

## Deploy a namespace

Declare the binding and migration in `wrangler.jsonc`:

```jsonc
{
  "name": "durable-counter",
  "main": "src/index.js",
  "compatibility_date": "2026-09-30",
  "durable_objects": {
    "bindings": [{ "name": "COUNTERS", "class_name": "Counter" }]
  },
  "migrations": [
    { "tag": "v1", "new_sqlite_classes": ["Counter"] }
  ]
}
```

Export `Counter` from the Worker module and deploy normally with `wrangler
deploy`. Wrangler reads the active migration tag from the control plane, uploads
the next immutable Worker version, and submits the required namespace migration.
The platform validates the complete native workerd configuration before making
that version active.

The current migration surface supports `new_sqlite_classes` and
`renamed_classes`. Namespace deletion, class transfer, legacy key-value-backed
classes, and cross-Worker namespace bindings are rejected explicitly. Use a
same-organization service binding when another Worker needs to call the owning
Worker.

## Runtime behavior

Stateful Workers use unmodified workerd Durable Object namespaces with SQLite
enabled. Native object addressing, RPC, transactional storage, SQL, alarms, and
WebSockets execute inside workerd. The platform does not emulate the namespace
API or intercept object methods.

Each stateful application receives a stable assignment to a shared runtime
shard. Its objects retain their state across deployments and restarts. The
runtime hosts many applications and objects; there is no dedicated process or
VM per object. Adding capacity does not move existing state.

Assignments are not replicated, automatically failed over, or automatically
migrated. The service remains single-region and non-HA. Operators manage
shard placement and persistence through [Platform operations](/operations/).

The same native shard substrate also hosts platform-owned Cron coordinator
objects. There is one coordinator object per organization on a stable shard;
its SQLite state, alarm, delivery lease, suspension state, and retry schedule
replace the former control-plane polling loop. This reuse is deliberately below
the service-semantics boundary: application Durable Objects and Cron retain
separate schemas and APIs.

Queues already use workerd Durable Objects for their broker state, alarms,
leases, retries, retention, and dead-letter transitions. That proven queue state
machine remains owned by the queue service and currently runs in its dedicated
workerd service. It is not reimplemented through the application namespace API
or collapsed into a generic coordinator object.

## Deployments and operations

A code update preserves namespace identities and their SQLite files. Applying a
namespace migration is an optimistic transition from Wrangler's observed
migration tag. The shard manager encrypts staged application bundles, records
cutover intent in SQLite, validates the candidate configuration, and restores
the last committed configuration after an interrupted or failed cutover.

Workerd owns each SQLite namespace through one process at a time, so the current
implementation performs a stop-before-start shard cutover. Applications sharing
that member can see a brief interruption during an update; the platform does not
claim zero-downtime Durable Object deployments yet. Lifecycle events and cutover
duration are recorded for the Worker.

In the tenant console, open **Compute → Durable Objects** to browse all of your
organization's application namespaces. Filter by class or owning Worker, then
open a namespace to inspect its identity, assigned member, migration tag, stored
object databases, and storage usage. **Lifecycle** shows paginated deployment
and recovery events for the owning Worker. Filters and page selections are
bookmarkable. The owning Worker's **Durable Objects** tab links to the same
namespace detail.

Stored object counts describe persisted databases, not running instances. The
inventory excludes the platform's internal Cron and queue coordination objects.
Class definitions and migrations remain in Wrangler; there is no console action
to delete a namespace or move its state between hosts.

Platform operators see shard process health and
resource pressure with the rest of the selected data host in **Platform → Fleet**.

Namespace holdings are enforced through the quota service before growth. A Free
organization starts with three namespaces, Standard with 20, and Enterprise with
100 unless an explicit support override applies. Reducing a limit does not delete
state; it prevents further namespace growth while usage remains over the limit.

## Example application

The [durable counter](/self-hosted/examples/#durable-counter) demonstrates named state,
RPC, alarms, and WebSockets. It is included in the self-hosted local example
set. Its Wrangler configuration uses the same APIs available to your own
organization.

Source: https://ermahgerd-docs.t-bd7662a5eeb4.workers.ermahgerd.io/build/durable-objects/index.mdx
