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
A function may run in several copies at once, and none of them remembers anything between requests. Each actor has exactly one copy, and it keeps its state in its own storage.
The requests reach the same copy one after the other, so a counter stays exact and two writes never collide.
Inside Iran, on the platform's own servers. Every write is durable before the actor answers, and losing a server does not lose it.
There is no maximum, because the actor sleeps while quiet and the connection stays open. On a deploy or a move, the connection closes with code 1012 so the browser reconnects.
If a message only needs to reach everyone on a channel, Realtime does it with no server code. If the server must check each message, keep state or run its own logic, write an actor.
An idle actor sleeps and has no run time. Only the data it keeps is counted, and connected minutes if a connection is still open.
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