.do
Platform

Workers

Durable Object types for stateful serverless compute

The Workers types provide abstractions for building stateful applications on Cloudflare's Durable Objects. This includes the core Durable Object interface, typed state management, transactions, alarms, WebSocket handling, and hibernation configuration.

Durable Objects Overview

Durable Objects provide strongly consistent, stateful compute at the edge. Each object has a unique ID and maintains its own state through a built-in storage API.

import type { DurableObject, DurableObjectState, DurableObjectEnv } from '@dotdo/types/workers'

class Counter implements DurableObject {
  private state: DurableObjectState
  private value: number = 0

  constructor(state: DurableObjectState, env: DurableObjectEnv) {
    this.state = state
    // Restore state from storage
    state.blockConcurrencyWhile(async () => {
      this.value = (await state.storage.get('value')) ?? 0
    })
  }

  async fetch(request: Request): Promise<Response> {
    const url = new URL(request.url)

    if (url.pathname === '/increment') {
      this.value++
      await this.state.storage.put('value', this.value)
    }

    return Response.json({ value: this.value })
  }
}

DurableObject

Cloudflare Workers Durable Object Runtime Types

Prop

Type

DurableObjectState

DurableObjectState - Runtime state provided to a Durable Object instance

Prop

Type

Durable Object IDs

Every Durable Object has a unique ID that determines its global identity:

import type { DurableObjectId, DurableObjectNamespace, DurableObjectStub } from '@dotdo/types/workers'

// Get a namespace from the environment
const namespace: DurableObjectNamespace = env.COUNTER

// Create an ID from a name (deterministic)
const id: DurableObjectId = namespace.idFromName('user-123-counter')

// Create a new unique ID
const newId: DurableObjectId = namespace.newUniqueId()

// Parse an ID from a string
const parsedId: DurableObjectId = namespace.idFromString('abc123...')

// Get a stub to interact with the object
const stub: DurableObjectStub = namespace.get(id)

// Call the object
const response = await stub.fetch('/increment')
const data = await response.json()

DurableObjectId

DurableObjectId - Unique identifier for a Durable Object instance

Prop

Type

DurableObjectNamespace

DurableObjectNamespace - Factory for accessing Durable Object instances

Prop

Type

DurableObjectStub

DurableObjectStub - Proxy for communicating with a Durable Object instance

Prop

Type

Durable Object Storage

The storage API provides strongly consistent key-value storage:

import type { DurableObjectStorage, DurableObjectStorageValue } from '@dotdo/types/workers'

class UserSession implements DurableObject {
  private storage: DurableObjectStorage

  constructor(state: DurableObjectState) {
    this.storage = state.storage
  }

  async login(userId: string) {
    // Store a single value
    await this.storage.put('userId', userId)
    await this.storage.put('loginAt', Date.now())

    // Store multiple values atomically
    await this.storage.put({
      userId,
      loginAt: Date.now(),
      active: true
    })
  }

  async getSession() {
    // Get a single value
    const userId = await this.storage.get<string>('userId')

    // Get multiple values
    const data = await this.storage.get(['userId', 'loginAt', 'active'])

    // List all values with a prefix
    const userData = await this.storage.list({ prefix: 'user:' })

    return { userId, data: Object.fromEntries(userData) }
  }

  async logout() {
    // Delete a single key
    await this.storage.delete('active')

    // Delete multiple keys
    await this.storage.delete(['userId', 'loginAt', 'active'])

    // Delete all keys with a prefix
    await this.storage.deleteAll()
  }
}

DurableObjectStorage

DurableObjectStorage - Persistent key-value storage for Durable Objects

Prop

Type

Storage Transactions

Execute multiple operations atomically:

import type { DurableObjectTransaction } from '@dotdo/types/workers'

await state.storage.transaction(async (txn: DurableObjectTransaction) => {
  const balance = await txn.get<number>('balance') ?? 0

  if (balance < amount) {
    // Transaction will be aborted
    throw new Error('Insufficient balance')
  }

  await txn.put('balance', balance - amount)
  await txn.put('lastTransaction', {
    type: 'withdrawal',
    amount,
    timestamp: Date.now()
  })
})

Typed State Management

Use the DOState<T> wrapper for fully typed state access:

import type { DOState, DOTransaction, DOStateListOptions } from '@dotdo/types/workers'

interface UserState {
  name: string
  email: string
  loginCount: number
  lastLoginAt: number
  preferences: Record<string, unknown>
}

class UserDO implements DurableObject {
  private state: DOState<UserState>

  constructor(doState: DurableObjectState) {
    this.state = createDOState<UserState>(doState.storage)
  }

  async login() {
    // Typed get - returns string | undefined
    const name = await this.state.get('name')

    // Typed put - type-checked value
    await this.state.put('loginCount', (await this.state.get('loginCount') ?? 0) + 1)
    await this.state.put('lastLoginAt', Date.now())
  }

  async updateProfile(updates: Partial<UserState>) {
    // Put multiple values
    await this.state.putAll(updates)
  }

  async getAll(): Promise<Partial<UserState>> {
    // Get all state as a partial object
    return await this.state.getAll()
  }
}

DOState

Durable Object State Management Types

Prop

Type

Typed Transactions

Execute typed transactions with automatic rollback:

import type { DOTransaction } from '@dotdo/types/workers'

const result = await this.state.transaction(async (txn: DOTransaction<UserState>) => {
  const balance = (await txn.get('credits')) ?? 0

  if (balance < cost) {
    txn.rollback() // Aborts and throws
  }

  await txn.put('credits', balance - cost)
  await txn.put('lastPurchaseAt', Date.now())

  return { newBalance: balance - cost }
})

DOTransaction

DOTransaction<T> - Transactional state interface

Prop

Type

Alarms

Schedule future work with alarms:

import type { DOAlarm, DOAlarmOptions, AlarmEvent } from '@dotdo/types/workers'

class ReminderDO implements DurableObject {
  private alarm: DOAlarm

  constructor(state: DurableObjectState) {
    this.alarm = createDOAlarm(state)
  }

  async scheduleReminder(delayMs: number) {
    // Set an alarm
    await this.alarm.setAlarm(Date.now() + delayMs)

    // Or with a Date
    await this.alarm.setAlarm(new Date('2024-12-31T23:59:59Z'))
  }

  async alarm() {
    // This method is called when the alarm fires
    await this.sendReminder()

    // Check if there's more work
    const nextReminder = await this.getNextReminderTime()
    if (nextReminder) {
      await this.alarm.setAlarm(nextReminder)
    }
  }

  async cancelReminder() {
    await this.alarm.deleteAlarm()
  }

  async getStatus() {
    const scheduled = await this.alarm.getAlarm()
    const hasAlarm = await this.alarm.hasAlarm()
    const remaining = await this.alarm.getTimeRemaining()

    return { scheduled, hasAlarm, remaining }
  }
}

DOAlarm

DOAlarm - Alarm management interface for Durable Objects

Prop

Type

DOAlarmOptions

Options for alarm scheduling

Prop

Type

AlarmEvent

AlarmEvent - Context provided to alarm handlers

Prop

Type

WebSocket State

Manage WebSocket connections that persist through hibernation:

import type { WebSocketState, WebSocketHandlers } from '@dotdo/types/workers'

class ChatRoom implements DurableObject {
  private sessions: Map<WebSocket, WebSocketState> = new Map()

  async fetch(request: Request): Promise<Response> {
    if (request.headers.get('Upgrade') === 'websocket') {
      const [client, server] = Object.values(new WebSocketPair())

      // Accept with hibernation support
      this.state.acceptWebSocket(server, ['chatroom'])

      // Attach user data that survives hibernation
      server.serializeAttachment({ userId: 'user_123', joinedAt: Date.now() })

      return new Response(null, { status: 101, webSocket: client })
    }

    return new Response('Expected WebSocket', { status: 400 })
  }

  // Called after hibernation wake-up
  async webSocketMessage(ws: WebSocket, message: string | ArrayBuffer) {
    // Retrieve attached data
    const state = ws.deserializeAttachment<{ userId: string; joinedAt: number }>()
    console.log(`Message from ${state?.userId}:`, message)

    // Broadcast to all connected clients
    for (const client of this.state.getWebSockets()) {
      if (client !== ws) {
        client.send(message)
      }
    }
  }

  async webSocketClose(ws: WebSocket, code: number, reason: string) {
    const state = ws.deserializeAttachment<{ userId: string }>()
    console.log(`User ${state?.userId} disconnected: ${code} ${reason}`)
  }

  async webSocketError(ws: WebSocket, error: Error) {
    console.error('WebSocket error:', error)
  }
}

WebSocketState

WebSocketState - State tracking for hibernatable WebSocket connections

Prop

Type

Hibernation

Configure how Durable Objects hibernate to save costs:

import type { HibernationConfig, HibernationState, HibernationMetrics } from '@dotdo/types/workers'

const config: HibernationConfig = {
  // Auto-respond to pings without waking
  autoResponseMessage: {
    request: 'ping',
    response: 'pong'
  },

  // Hibernate after 60 seconds of inactivity
  idleTimeout: 60000,

  // Maximum hibernation duration
  maxHibernationDuration: 24 * 60 * 60 * 1000, // 24 hours

  // Preserve in-memory state through hibernation
  preserveState: true,

  // Hooks
  onHibernate: async () => {
    console.log('Going to sleep...')
  },
  onWake: async () => {
    console.log('Waking up!')
  },

  // WebSocket tags for selective wake-up
  webSocketTags: ['chatroom', 'admin']
}

HibernationConfig

HibernationConfig - Configuration for Durable Object hibernation behavior

Prop

Type

HibernationState

HibernationState - Current hibernation status of a Durable Object

type HibernationState = 'active' | 'hibernating' | 'waking' | 'evicted'

Hibernation Metrics

Monitor hibernation behavior:

import type { HibernationMetrics } from '@dotdo/types/workers'

const metrics: HibernationMetrics = {
  totalHibernationTime: 3600000,      // 1 hour in ms
  hibernationCount: 50,                // Times hibernated
  wakeCount: 48,                       // Times woken
  averageHibernationDuration: 72000,   // 72 seconds average
  autoResponseCount: 1000,             // Pings handled while sleeping
  lastHibernatedAt: 1705312800000,
  lastWokenAt: 1705312860000
}

HibernationMetrics

HibernationMetrics - Metrics about a Durable Object's hibernation behavior

Prop

Type

SQL Storage

Durable Objects support SQLite for relational data:

import type { DurableObjectSqlStorage } from '@dotdo/types/workers'

class AnalyticsDO implements DurableObject {
  private sql: DurableObjectSqlStorage

  constructor(state: DurableObjectState) {
    this.sql = state.storage.sql
  }

  async initialize() {
    // Create tables
    await this.sql.exec(`
      CREATE TABLE IF NOT EXISTS events (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        type TEXT NOT NULL,
        data TEXT,
        created_at INTEGER DEFAULT (unixepoch())
      )
    `)

    await this.sql.exec(`
      CREATE INDEX IF NOT EXISTS idx_events_type ON events(type)
    `)
  }

  async recordEvent(type: string, data: unknown) {
    await this.sql.exec(
      'INSERT INTO events (type, data) VALUES (?, ?)',
      type,
      JSON.stringify(data)
    )
  }

  async getEventsByType(type: string) {
    const cursor = this.sql.exec(
      'SELECT * FROM events WHERE type = ? ORDER BY created_at DESC LIMIT 100',
      type
    )

    const events = []
    for (const row of cursor) {
      events.push({
        id: row.id,
        type: row.type,
        data: JSON.parse(row.data as string),
        createdAt: row.created_at
      })
    }
    return events
  }

  async getStats() {
    const cursor = this.sql.exec(`
      SELECT type, COUNT(*) as count
      FROM events
      GROUP BY type
      ORDER BY count DESC
    `)

    return Array.from(cursor).map(row => ({
      type: row.type,
      count: row.count
    }))
  }
}

DurableObjectSqlStorage

SQL storage interface for Durable Objects using SQLite

Prop

Type

Request Context

Access request context within Durable Objects:

import type { DurableObjectRequestContext } from '@dotdo/types/workers'

class MyDO implements DurableObject {
  async fetch(request: Request): Promise<Response> {
    // Access request metadata
    const url = new URL(request.url)
    const method = request.method
    const headers = request.headers

    // Handle different paths
    switch (url.pathname) {
      case '/get':
        return this.handleGet()
      case '/set':
        return this.handleSet(await request.json())
      default:
        return new Response('Not Found', { status: 404 })
    }
  }
}

Complete Type References

Durable Object Types

DurableObject

Cloudflare Workers Durable Object Runtime Types

Prop

Type

DurableObjectState

DurableObjectState - Runtime state provided to a Durable Object instance

Prop

Type

WebSocketRequestResponsePair

WebSocket auto-response pair for hibernation When a received message matches the request, the response is sent automatically

Prop

Type

AlarmOptions

Options for alarm scheduling and retrieval

Prop

Type

DurableObjectStorage

DurableObjectStorage - Persistent key-value storage for Durable Objects

Prop

Type

DurableObjectStorageReadOptions

Read options for storage operations

Prop

Type

DurableObjectStorageWriteOptions

Write options for storage operations

Prop

Type

DurableObjectStorageListOptions

Options for listing storage keys

Prop

Type

DurableObjectSqlStorage

SQL storage interface for Durable Objects using SQLite

Prop

Type

SqlStorageRunResult

Result metadata from a SQL run operation

Prop

Type

SqlStorageCursor

Cursor for iterating over SQL query results

Prop

Type

DurableObjectId

DurableObjectId - Unique identifier for a Durable Object instance

Prop

Type

DurableObjectNamespace

DurableObjectNamespace - Factory for accessing Durable Object instances

Prop

Type

DurableObjectNamespaceNewUniqueIdOptions

Options for generating a new unique ID

Prop

Type

DurableObjectNamespaceGetOptions

Options for getting a Durable Object stub

Prop

Type

DurableObjectStub

DurableObjectStub - Proxy for communicating with a Durable Object instance

Prop

Type

DurableObjectConstructor

Constructor signature for Durable Object classes

Prop

Type

SqlStorageValue

SQL parameter and result value types

type SqlStorageValue = string | number | boolean | null | Uint8Array | bigint

DurableObjectJurisdiction

Jurisdictions for data residency compliance

type DurableObjectJurisdiction = 'eu' | 'fedramp'

State Management Types

DOState

Durable Object State Management Types

Prop

Type

DOStateListOptions

Options for listing state entries

Prop

Type

DOTransaction

DOTransaction<T> - Transactional state interface

Prop

Type

DOAlarm

DOAlarm - Alarm management interface for Durable Objects

Prop

Type

DOAlarmOptions

Options for alarm scheduling

Prop

Type

AlarmHandler

AlarmHandler - Interface for handling alarm events

Prop

Type

AlarmEvent

AlarmEvent - Context provided to alarm handlers

Prop

Type

WebSocketState

WebSocketState - State tracking for hibernatable WebSocket connections

Prop

Type

HibernationConfig

HibernationConfig - Configuration for Durable Object hibernation behavior

Prop

Type

HibernationMetrics

HibernationMetrics - Metrics about a Durable Object's hibernation behavior

Prop

Type

HibernationState

HibernationState - Current hibernation status of a Durable Object

type HibernationState = 'active' | 'hibernating' | 'waking' | 'evicted'
Edit on GitHub

On this page