Skip to content
cloudhost
Actors

One live copy of each thing, with its own state.

An actor is an instance of a class in your function, called by name. Only one copy of each name runs at a time, and it has its own storage. Chat rooms, live editing, exact counters and per-user rate limiters work without a database of their own.

What you get

  • Exactly one live copy

    env.ROOMS.get("room-42") always reaches the same one actor, whichever server it is on. Requests reach it in order, and two copies of one actor never run at once.

  • Its own storage

    Each actor has its own keys and values with get, put, delete and list. Every write is durable before the actor answers.

  • All or nothing

    All the writes of one request commit together or not at all. Use storage.transaction to undo part of the work on its own.

  • Alarms

    Set a time with storage.setAlarm and the actor wakes then in alarm(), even if nobody calls it. For clearing stale state, reminders or periodic work.

  • WebSockets that sleep

    An actor holds a WebSocket with acceptWebSocket and gets each message in webSocketMessage. A quiet room sleeps while its connections stay open, so it costs little.

  • Groups of connections

    Tag each connection and use getWebSockets to message everyone in a group, such as everyone with one document open.

  • Namespaces and bindings

    A namespace is the actors of one class from one function of the project. That function has it as env.ROOMS; another function or app of the project binds it with a few lines in its project file.

  • Ready before the first request

    Load state from storage in the constructor with blockConcurrencyWhile; no request reaches the actor until it finishes.

  • No data lost

    If a server fails, its actors answer from another server with the same data. No acknowledged write is lost.

  • New code, same data

    Change a namespace's class or function; its actors keep their data and the next request runs the new code. A deleted namespace's data is kept for about a day and comes back if you create it again by the same name.

  • Usage and audit

    Each namespace's requests, run time, reads and writes, day by day. And who changed what in it, and when.

A chat room in a few lines

Each room is one actor: it holds the connections, sends each message to everyone, and keeps the message count in its own storage.

export class Room {
  constructor(state, env) {
    this.state = state
  }

  async fetch(request) {
    const [client, server] = Object.values(new WebSocketPair())
    this.state.acceptWebSocket(server, ["lobby"])
    return new Response(null, { status: 101, webSocket: client })
  }

  async webSocketMessage(ws, message) {
    const n = ((await this.state.storage.get("count")) ?? 0) + 1
    await this.state.storage.put("count", n)
    for (const s of this.state.getWebSockets("lobby")) s.send(message)
    await this.state.storage.setAlarm(Date.now() + 60_000)
  }

  async alarm() {
    await this.state.storage.delete("typing")
  }
}

Per use

Requests, run time, reads and writes, the data you keep, and for WebSockets connected minutes and messages, at the same connected-minute price as Realtime. A sleeping actor has no run time. Use comes from the month's credit first, then from the wallet.

Questions

Build your first actor

One class in a function, one command for the namespace.

Sign-up is by invite for now. If you have a code, create your account.

Sign up withEmail codeSMS code