---
title: Durable Objects
description: "Per-id serialized state and alarms, backed by synchronous storage calls."
---

## Configuration

```jsonc
"durable_objects": { "COUNTER": "Counter" }
```

Binding name maps to a class name declared in the same file as your handler.

## Usage

```js
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.
  alarm() {
    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);
  },
};
```

## Semantics

:::note
One sprout process per deployment means calls to a given id are already serialized. Only `state.storage.*` crosses to the broker, so it outlives a restart.
:::

## Related

- [D1](/bindings/d1) — for data that outlives a single object's id
