Skip to content
sproutboat
Esc
↑↓navigate↵open⌘Jpreview
On this page

Durable Objects

Per-id serialized state and alarms, backed by synchronous storage calls.

Configuration

"durable_objects": { "COUNTER": "Counter" }

The binding name maps to a class declared in the entry file, above the default export.

Usage

class Counter {
  constructor(state, env) { this.state = state; this.env = env; }
  // Synchronous, like every other binding: state.storage.* are blocking calls.
  fetch(request) {
    const n = (this.state.storage.get("n") || 0) + 1;
    this.state.storage.put("n", n);
    // Debounced: a burst of requests produces one alarm, not one per request.
    this.state.storage.setAlarm(Date.now() + 1000);
    return Response.json({ n });
  }
  // Runs later, with no request in flight.
  async alarm() {
    await this.env.DB.prepare("INSERT INTO rollup (n) VALUES (?)").bind(this.state.storage.get("n")).run();
  }
}
export default {
  fetch(request) {
    const id = env.COUNTER.idFromName("global");
    return env.COUNTER.get(id).fetch(request);
  },
};

Storage and alarms

state.storage has get, put, delete, deleteAll, list({ prefix?, limit? }) (a Map), setAlarm(time), getAlarm() and deleteAlarm(). Each object has at most one pending alarm; a later setAlarm replaces it. state.waitUntil(promise) works as in a handler.

The namespace has idFromName(name), idFromString(hex), newUniqueId() and get(id).

Was this page helpful?