Skip to main content
Use a stateful actor when an entity has state that must be mutated coherently across many requests — a cart, a chat room, a call leg’s media state, a per-user rate limiter, a job coordinator. One instance per name gives you serialized, durable, private state for that entity without locks or a shared database.

When Not to Reach for One

  • Stateless work (routing, transforms, independent fan-out): use a plain function. An actor only adds a routing hop and a serialization point you don’t need.
  • A global counter or singleton: one name is one single-threaded instance is one throughput ceiling. Route everything through idFromName("global") and you’ve rebuilt the single-lock bottleneck. Shard across many names so load spreads across instances.
  • Large blobs or bulk scans: the keyspace holds one entity’s working set, not a warehouse. Use object storage or a database.
  • Cross-entity transactions or ad-hoc queries: each instance is its own consistency domain. Within one actor, writes are serialized and transaction() gives you atomic multi-key updates — but there is no transaction across two actors, and there’s no JOIN across them. If you need a transaction spanning many entities, or to query across them, that’s what a database is for — keep it.
A single instance processes calls serially, so its ceiling is roughly 1 / (method wall-time) calls per second — the same ceiling one thread per account gives you. Sharding by a well-chosen name is how you scale.

Next Steps