Skip to content

Singletons ​

A cluster singleton is an actor with exactly one live instance across the whole cluster, reached by the same name from every node. Use it for work that must not run twice at once: a sequence generator, a scheduler, a leader that owns an external resource.

ts
const ref = await system.spawnSingleton("sequencer", Props.create(Sequencer));

A singleton is not a new kind of actor. It is an ordinary named, always-relocatable actor with three guarantees. It is also spawned long-lived, so unlike an ordinary actor it never passivates on an idle window: a quiet period cannot stop the one instance out from under the cluster.

Idempotent to create ​

Call spawnSingleton(name, props) from every node that wants the singleton. The first call wins the name; every other call gets a routed handle to the existing instance instead of ErrActorAlreadyExists. That is the difference from spawn and spawnOn, which refuse a losing caller: spawnSingleton is the one creation call that is safe to run everywhere.

Node ANode BRegistryclaim the nameclaim the namewonlostbuild the instanceresolve the ownerhandle to that instance

Both callers end up holding a handle to the same one instance. When two nodes race with different Props, the winner's Props win. That is the price of idempotence, and the reason a singleton's constructor arguments should be the same everywhere it is created.

Hosted on the coordinator ​

A singleton runs on the coordinator, the oldest live member every node agrees on, so its location is predictable. It moves only when its host departs, and then it is re-established on the new coordinator.

Always relocatable ​

When a singleton's host departs, the ordinary relocation pass recreates it, pinned to the current coordinator rather than chosen by a placement strategy. There is no separate lease and no renewal clock: at-most-one rests on the same cluster-wide name claim that makes every name unique, so there is never a second recovery path that could mint a duplicate.

Shared namespace ​

Singletons share the one actor namespace with every other actor. After spawnSingleton("sequencer"), a spawn("sequencer") anywhere in the cluster is refused as a duplicate, and the reverse holds too. A name is a singleton or an ordinary actor, never both.

WARNING

At-most-one depends on the split-brain resolver. A partitioned cluster whose halves each keep serving could otherwise elect two coordinators and mint two instances of one singleton. Run a clustered deployment with minimumMemberQuorum set so a minority half stops instead.

Released under the MIT License.