Architecture
Each node runs one topic actor (GoAktTopicActor). Local actors subscribe to and publish through their local topic actor. The topic actor maintains a registry of topics and their local subscribers.
Standalone mode

Publish to the local topic actor. The topic actor delivers the message to all local subscribers via Tell.
Cluster mode
In a cluster, each node has its own topic actor. Topic actors communicate with each other to disseminate messages. When a publish occurs:- The publisher sends
Publishto its local topic actor. - The local topic actor delivers to its local subscribers.
- The local topic actor sends a
TopicMessage(serialized) to each peer node’s topic actor via remoting. - Each remote topic actor receives the
TopicMessage, deserializes it, and delivers to its local subscribers.

When to use
- Decouple publishers from subscribers—publishers do not need to know who is listening
- Broadcast application events (e.g. order created, inventory updated) to multiple actors
- Event-driven architectures where actors react to domain events
Enabling PubSub
The topic actor is spawned when either:WithPubSub()is passed when creating the actor system, or- Cluster mode is enabled (
WithCluster)
Topic actor
The topic actor has a reserved name (
GoAktTopicActor). From within an actor, use ctx.ActorSystem().TopicActor(). From outside (e.g. main), use system.TopicActor(). Returns nil if PubSub is not enabled.
Subscribe and Unsubscribe
Actors send messages to the local topic actor to subscribe or unsubscribe from topics:
The topic actor watches subscribers. When a subscriber terminates, it is automatically removed from all topics.
Publish
Receive invocation—the payload is the published message, not a wrapper.
Cluster behavior
- Local delivery: The topic actor that receives the
Publishdelivers to its local subscribers immediately. - Remote dissemination: The topic actor sends a serialized
TopicMessageto each peer’s topic actor via remoting. Each peer’s topic actor deserializes and delivers to its local subscribers. - Deduplication: Uses sender ID, topic, and message ID to avoid processing the same message twice (e.g. when a topic actor receives a
TopicMessagefrom multiple paths).
Deduplication retention
The topic actor remembers recently delivered message identifiers so it can suppress duplicate deliveries. This state is bounded by a retention window: each entry expires after the window elapses, keeping memory flat under sustained, high-rate publishing instead of growing for the lifetime of the actor system. The window defaults to 2 minutes and is configurable withWithMessageRetention:
A duplicate that arrives after the retention window has elapsed may be redelivered, which is acceptable under at-least-once delivery. Size the window to the largest plausible redelivery delay for your transport (network retries and cross-node dissemination), not to your total publish volume.
Example
Topic statistics
ActorSystem.TopicStats returns a read-only, point-in-time snapshot of a topic’s subscription state, without ever exposing subscriber identities. TopicStats is immutable and exposes its values through accessor methods:
Topic() stringis the topic these stats describe.LocalSubscriberCount() int32is the number of subscribers registered on this node’s topic actor for the topic.TopicInstanceCount() int32is the number of topic-actor instances (nodes) cluster-wide that currently have at least one subscriber for the topic.
TopicInstanceCount is simply 0 or 1 depending on whether this node has local subscribers.
TopicStats is an eventually consistent, point-in-time snapshot with no delivery guarantee: subscribers may join or leave between the query and the response.TopicStats requires the topic actor to be running (WithPubSub() or clustering enabled); otherwise it returns ErrTopicActorNotStarted.