Skip to main content

Why any instead of proto.Message (v4)?

v4 allows any type as actor messages. Benefits:
  • Flexibility β€” Plain Go structs, protobuf, or custom types
  • Simplicity β€” No mandatory .proto definitions for simple cases
  • CBOR β€” Efficient serialization for arbitrary Go types
ProtoSerializer remains the default for protobuf messages. CBOR and custom serializers extend the set of supported types.

Why a custom TCP frame protocol?

GoAkt uses length-prefixed binary frames over TCP instead of gRPC:
  • Low overhead β€” No HTTP/2, HPACK, or stream multiplexing
  • Control β€” Connection pools, compression, buffer pooling tuned for actor traffic
  • Fewer dependencies β€” Leaner than gRPC

Why Olric for cluster state?

Cluster state (actor/grain placement) needs replication. Olric provides:
  • Embedded β€” No external database
  • Distributed hash map β€” Configurable quorum for consistency
  • Memberlist β€” Same membership layer as the cluster

Why CRDTs in addition to Olric?

Actor and grain registry entries are strongly consistent via Olric quorums. Application data that must stay available under partition and merge without a single writer uses CRDTs in the crdt package, replicated by a dedicated Replicator actor. Deltas fan out over the existing topic busβ€”separate concern from registry reads and writes. See Distributed data.

Why reactive streams on top of actors?

The stream package composes Source β†’ Flow β†’ Sink graphs that materialize as actors per stage, inheriting supervision, lifecycle, and demand-driven backpressure instead of unbounded queues. Streams are optional; they do not replace Tell/Ask. See Streams.

Why a tree-based actor hierarchy?

Mirrors Erlang/OTP and Akka:
  • Lifecycle ordering β€” Stopping a parent stops descendants first (depth-first)
  • Scoped supervision β€” Parent defines failure policy for children
  • Namespacing β€” Addresses reflect tree path; no name collisions

Why separate Actor and Grain?

  • Actors β€” Explicit spawn/stop; caller controls lifecycle. Best for services and infrastructure.
  • Grains β€” Identity-addressed; framework manages activation and passivation. Best for entity-per-identity patterns.
Both share the same runtime; choose based on use case.