Actors and Channels
The three core concepts of Verani.
1. Actors = Isolated Realtime Containers
Think of each Actor instance as a self-contained realtime room.
+---------------------------------------+
| Actor Instance (Durable Object) |
| |
| [WebSocket] [WebSocket] [WebSocket]
| User A User B User C |
| |
| Memory: Sessions Map |
| Hibernation: Attachments |
+---------------------------------------+
Key insight: You control isolation by how you route requests to Actors.
- Chat room: Route by room ID → everyone in room shares Actor
- User feed: Route by user ID → each user gets their own Actor
- Game session: Route by game ID → players in same game share Actor
2. Channels = Sub-rooms Within an Actor
Inside a single Actor, connections can subscribe to different channels for selective message delivery.
Actor: "game-room-123"
|
+-- Channel: "default"
| +-- User A
| +-- User B
| +-- User C
|
+-- Channel: "game-state"
| +-- User A
| +-- User B
|
+-- Channel: "chat"
+-- User C
When you broadcast to a channel, only connections subscribed to that channel receive the message:
// Only users in "game-state" channel receive this (using emit API)
ctx.actor.emit.to("game-state").emit("score", { score: 100 });
// Alternative: Legacy broadcast API (still supported)
// ctx.actor.broadcast("game-state", { score: 100 });
Default behavior: Every connection starts in the ["default"] channel.
Summary
Remember these three mental models:
- Actor = Room: Each Actor is an isolated realtime container
- Channels = Sub-rooms: Filter messages within an Actor
- Attachments = Hibernation Survival: WebSocket metadata persists
Everything else follows from these principles.
Related Documentation
- Architecture - System architecture
- Hibernation - Hibernation behavior
- Isolation - Isolation strategies
- Examples - Channels - Channel examples