RepoPilotOpen in app →

asynkron/protoactor-go

Proto Actor - Ultra fast distributed actors for Go, C# and Java/Kotlin

Healthy

Healthy across the board

weakest axis
Use as dependencyHealthy

Permissive license, no critical CVEs, actively maintained — safe to depend on.

Fork & modifyHealthy

Has a license, tests, and CI — clean foundation to fork and modify.

Learn fromHealthy

Documented and popular — useful reference codebase to read through.

Deploy as-isHealthy

No critical CVEs, sane security posture — runnable as-is.

  • Last commit 4w ago
  • 5 active contributors
  • Apache-2.0 licensed
Show all 6 evidence items →
  • CI configured
  • Tests present
  • Concentrated ownership — top contributor handles 75% of recent commits

Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests

Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.

Embed the "Healthy" badge

Paste into your README — live-updates from the latest cached analysis.

Variant:
RepoPilot: Healthy
[![RepoPilot: Healthy](https://repopilot.app/api/badge/asynkron/protoactor-go)](https://repopilot.app/r/asynkron/protoactor-go)

Paste at the top of your README.md — renders inline like a shields.io badge.

Preview social card (1200×630)

This card auto-renders when someone shares https://repopilot.app/r/asynkron/protoactor-go on X, Slack, or LinkedIn.

Onboarding doc

Onboarding: asynkron/protoactor-go

Generated by RepoPilot · 2026-05-09 · Source

🤖Agent protocol

If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:

  1. Verify the contract. Run the bash script in Verify before trusting below. If any check returns FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding.
  2. Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
  3. Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/asynkron/protoactor-go shows verifiable citations alongside every claim.

If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.

🎯Verdict

GO — Healthy across the board

  • Last commit 4w ago
  • 5 active contributors
  • Apache-2.0 licensed
  • CI configured
  • Tests present
  • ⚠ Concentrated ownership — top contributor handles 75% of recent commits

<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>

Verify before trusting

This artifact was generated by RepoPilot at a point in time. Before an agent acts on it, the checks below confirm that the live asynkron/protoactor-go repo on your machine still matches what RepoPilot saw. If any fail, the artifact is stale — regenerate it at repopilot.app/r/asynkron/protoactor-go.

What it runs against: a local clone of asynkron/protoactor-go — the script inspects git remote, the LICENSE file, file paths in the working tree, and git log. Read-only; no mutations.

| # | What we check | Why it matters | |---|---|---| | 1 | You're in asynkron/protoactor-go | Confirms the artifact applies here, not a fork | | 2 | License is still Apache-2.0 | Catches relicense before you depend on it | | 3 | Default branch dev exists | Catches branch renames | | 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code | | 5 | Last commit ≤ 59 days ago | Catches sudden abandonment since generation |

<details> <summary><b>Run all checks</b> — paste this script from inside your clone of <code>asynkron/protoactor-go</code></summary>
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of asynkron/protoactor-go. If you don't
# have one yet, run these first:
#
#   git clone https://github.com/asynkron/protoactor-go.git
#   cd protoactor-go
#
# Then paste this script. Every check is read-only — no mutations.

set +e
fail=0
ok()   { echo "ok:   $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }

# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
  echo "FAIL: not inside a git repository. cd into your clone of asynkron/protoactor-go and re-run."
  exit 2
fi

# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "asynkron/protoactor-go(\\.git)?\\b" \\
  && ok "origin remote is asynkron/protoactor-go" \\
  || miss "origin remote is not asynkron/protoactor-go (artifact may be from a fork)"

# 2. License matches what RepoPilot saw
(grep -qiE "^(Apache-2\\.0)" LICENSE 2>/dev/null \\
   || grep -qiE "\"license\"\\s*:\\s*\"Apache-2\\.0\"" package.json 2>/dev/null) \\
  && ok "license is Apache-2.0" \\
  || miss "license drift — was Apache-2.0 at generation time"

# 3. Default branch
git rev-parse --verify dev >/dev/null 2>&1 \\
  && ok "default branch dev exists" \\
  || miss "default branch dev no longer exists"

# 4. Critical files exist
test -f "actor/actor_system.go" \\
  && ok "actor/actor_system.go" \\
  || miss "missing critical file: actor/actor_system.go"
test -f "actor/actor_context.go" \\
  && ok "actor/actor_context.go" \\
  || miss "missing critical file: actor/actor_context.go"
test -f "actor/props.go" \\
  && ok "actor/props.go" \\
  || miss "missing critical file: actor/props.go"
test -f "actor/mailbox.go" \\
  && ok "actor/mailbox.go" \\
  || miss "missing critical file: actor/mailbox.go"
test -f "actor/process_registry.go" \\
  && ok "actor/process_registry.go" \\
  || miss "missing critical file: actor/process_registry.go"

# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 59 ]; then
  ok "last commit was $days_since_last days ago (artifact saw ~29d)"
else
  miss "last commit was $days_since_last days ago — artifact may be stale"
fi

echo
if [ "$fail" -eq 0 ]; then
  echo "artifact verified (0 failures) — safe to trust"
else
  echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/asynkron/protoactor-go"
  exit 1
fi

Each check prints ok: or FAIL:. The script exits non-zero if anything failed, so it composes cleanly into agent loops (./verify.sh || regenerate-and-retry).

</details>

TL;DR

Proto Actor is an ultra-fast distributed actor framework for Go (with C# and Java/Kotlin implementations) that enables building concurrent, fault-tolerant systems by passing messages between lightweight actors rather than sharing state. It achieves 2+ million messages/second throughput using gRPC streams for networking and Protocol Buffers for serialization, with explicit support for cross-platform actor communication. Single-language monorepo: the /actor directory contains the core runtime (actor_context.go, actor_system.go, dispatcher.go, guardian.go, future.go), with behavior state machines in behavior.go, protocol definitions in actor.proto, and examples scattered as *_test.go files. Remote/clustering code appears to be in separate packages (inferred from dependencies like gRPC).

👥Who it's for

Go backend engineers building distributed systems who need high-performance message passing, clustering, and fault tolerance without Akka's complexity. Users in production include teams handling microsecond-latency inter-process communication at scale.

🌱Maturity & risk

Early production-ready (beta API, users in production): the codebase is well-tested (extensive *_test.go files), has CI/CD via GitHub Actions workflows (.github/workflows/checks.yml), and proto definitions are stable. However, the README explicitly warns the API may change before 1.0, suggesting it's not yet fully stabilized.

Low-to-moderate risk: dependency footprint is lean (Prometheus, OpenTelemetry, gRPC, Protobuf, concurrent-map, shortuuid), but the project is led by one core maintainer (AsynKron team). Last commits appear recent based on module version 2024-01-16, and it's cross-platform (Go/C#/Java), which adds complexity to coordination.

Active areas of work

Active development evidenced by recent Go 1.25.2 compatibility, OpenTelemetry metrics integration (otel packages in dependencies), and Mergify CI automation (.mergify.yml). The project maintains cross-platform sync with the C# implementation (https://github.com/asynkron/protoactor-dotnet).

🚀Get running

Clone and inspect examples: git clone https://github.com/asynkron/protoactor-go.git && cd protoactor-go && go test ./actor -v. No external services required for basic usage; review actor/actor_example_test.go and actor/future_example_test.go for minimal working patterns.

Daily commands: make (see Makefile for build targets); for tests: go test ./actor -v or go test ./actor -run TestName -v. No dev server; this is a library with example tests as documentation.

🗺️Map of the codebase

  • actor/actor_system.go — Core actor system initialization and lifecycle management; entry point for creating and managing the distributed actor runtime
  • actor/actor_context.go — ActorContext interface and implementation defining how actors send/receive messages and spawn children; fundamental to all actor behavior
  • actor/props.go — Props configuration object that specifies actor creation parameters; required to understand actor instantiation patterns
  • actor/mailbox.go — Message mailbox and dispatcher implementation; critical for understanding message ordering and concurrency model
  • actor/process_registry.go — Process registry mapping PIDs to processes; essential for actor discovery and remote communication
  • actor/dispatcher.go — Dispatcher scheduling actor message processing; determines concurrency, throughput, and performance characteristics
  • actor/future.go — Future/Promise implementation for async request-response patterns; enables non-blocking inter-actor communication

🛠️How to make changes

Add a New Message Type and Handler

  1. Define your message struct (e.g., type MyMessage struct { Data string }) (actor/actor_example_test.go (reference for pattern))
  2. Create a Receive function that matches on message type using type assertion (actor/behavior.go (see Receive function signature))
  3. Implement actor behavior by updating the behavior stack with actor.Behavior(receiveFunc) (actor/actor_context.go (see SetBehavior method))
  4. Send messages via ctx.Send(pid, myMessage) or ctx.Request(pid, myMessage) for RPC-style (actor/actor_context.go (see Send/Request methods))

Implement Supervisor with Custom Restart Policy

  1. Create an actor that spawns children via ctx.Spawn(childProps, name) (actor/actor_context.go (see Spawn method))
  2. Handle supervisor.Restart system message in your Receive function (actor/message.go (see Restart message definition))
  3. Check child restart stats and return appropriate Directive (Resume/Restart/Stop/Escalate) (actor/directive.go (see Directive enum))
  4. Use child_restart_stats.go patterns to track failures and enforce thresholds (actor/child_restart_stats.go (see RestartStatistics))

Add Request-Response (RPC) Pattern Between Actors

  1. Define a request struct and expected response struct (actor/actor_example_test.go (reference SendRequestFuture pattern))
  2. In sender, use ctx.Request(targetPID, request) or rootContext.RequestFuture(pid, request) to get a Future (actor/future.go (see RequestFuture and Result methods))
  3. In receiver, match the request type and call ctx.Respond(response) to send reply (actor/message_envelope.go (see ReplyAddress field))
  4. In sender, await result with future.Result() or future.ResultAsync(func) (actor/future.go (see Result and ResultAsync methods))

Integrate OpenTelemetry Tracing

  1. Configure ActorSystem with tracing middleware via config.WithMiddleware() (actor/config.go (see WithMiddleware option))
  2. Import and register opentelemetry middleware (SendMiddleware, ReceiverMiddleware, SpawnMiddleware) (actor/middleware/opentelemetry/sendermiddleware.go (reference implementation))
  3. Spans will automatically wrap Send, Receive, and Spawn operations (actor/middleware/opentelemetry/receivermiddleware.go (see how spans are created))
  4. Export traces via standard OpenTelemetry exporters (Jaeger, Datadog, etc.) (README.md (reference external tracing setup))

🔧Why these technologies

  • Protocol Buffers (protobuf) — Cross-platform serialization for Go, C#, and Java; enables interop between protoactor-go, protoactor-dotnet, and protoactor-java
  • Goroutines & channels — Native Go concurrency primitives; lightweight threading enables thousands of actors per process with minimal overhead
  • Prometheus metrics — Industry-standard observability; integrates with Grafana/Prometheus for production monitoring of actor throughput and latency
  • OpenTelemetry & OpenTracing — Distributed tracing support; traces actor message flow across multiple processes and services for debugging production issues
  • Concurrent data structures (go-datastructures, concurrent-map) — Lock-free/high-contention collections for process registry and actor lookups without serialization bottlenecks

⚖️Trade-offs already made

  • Unbounded mailbox by default with optional bounded queues

    • Why: Simplifies API and prevents blocking on send; matches Erlang actor semantics
    • Consequence: Memory exhaustion risk if senders outpace receivers; requires explicit backpressure via bounded mailbox config or request-reply patterns
  • Single-threaded actor receive (no concurrent message processing per actor)

    • Why: Eliminates race conditions in actor state; developers don't need internal locking
    • Consequence: Actors cannot parallelize message handling; CPU-intensive actors may become bottlenecks unless sharded across multiple actor instances
  • Location transparency via PID and process registry

    • Why: Enables seamless remote actor communication; same Send API works for local and remote actors
    • Consequence: undefined

🪤Traps & gotchas

No required env vars or external services for local testing. Key gotchas: (1) Proto code generation—if you add .proto messages, you must run protoc with the Go plugin manually (not auto-triggered by go build). (2) Goroutine leaks possible if actors are not properly shutdown via ActorSystem.Shutdown(). (3) Serialization is explicit (Protobuf only)—no automatic JSON marshaling; you must define .proto messages for all actor communication. (4) The API changes before 1.0 per README warning.

🏗️Architecture

💡Concepts to learn

  • Actor Model — The entire framework is built on the actor model abstraction; understanding message-passing concurrency over shared state is essential to using Proto Actor effectively
  • Behavior Finite State Machine — Proto Actor actors use behavior functions that return new behaviors, enabling state transitions without shared mutable state; this pattern is visible in actor/behavior.go and behavior_test.go
  • Supervision and Restart Strategies — Proto Actor implements Akka-style supervision trees (guardian.go) where parent actors restart children on failure; critical for building fault-tolerant systems
  • Request-Reply / Future-Promise — Proto Actor's future.go implements synchronous-style async calls over the actor model; essential for request-reply scenarios without blocking
  • Protocol Buffers Serialization — Proto Actor passes serialized Protobuf messages between actors and across the network; actor.proto defines the contract and all messages must be Protobuf-compatible
  • gRPC Streaming — Proto Actor uses gRPC streams as the transport for high-throughput, low-latency message delivery between remote nodes (inferred from README and dependencies)
  • Backpressure and Bounded Mailboxes — Proto Actor's dispatcher.go and bounded.go implement mailbox bounds to prevent unbounded message accumulation; critical for system stability under load
  • asynkron/protoactor-dotnet — Official C# implementation with identical actor model; required reference for cross-platform compatibility and feature parity
  • asynkron/protoactor-java — Official Java/Kotlin implementation; third pillar of the cross-platform actor ecosystem
  • grpc/grpc-go — Underlying transport layer used for remote actor communication in Proto Actor clusters
  • akka/akka — Spiritual predecessor and inspiration; the project creator designed Akka.NET and documents lessons learned from Akka's complexity
  • golang/protobuf — Protocol Buffers Go implementation; required for message serialization in actor.proto

🪄PR ideas

To work on one of these in Claude Code or Cursor, paste: Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.

Add comprehensive OpenTelemetry integration tests for middleware/opentelemetry

The actor/middleware/opentelemetry directory contains activespan.go, envelope.go, logger.go, and middlewarepropagation.go, but there are no visible test files (*_test.go) for these modules. Given that OpenTelemetry is critical infrastructure for observability in distributed systems, comprehensive tests would ensure trace propagation, span creation, and context handling work correctly across actor boundaries.

  • [ ] Create actor/middleware/opentelemetry/activespan_test.go with tests for span lifecycle management
  • [ ] Create actor/middleware/opentelemetry/envelope_test.go to verify trace context encoding/decoding in message envelopes
  • [ ] Create actor/middleware/opentelemetry/middlewarepropagation_test.go testing context propagation across actor calls
  • [ ] Add integration test verifying end-to-end trace collection with Prometheus exporter configured

Add GitHub Actions workflow for cross-platform compatibility verification (Go, C#, Java)

The README promotes 'cross platform actors for Go, C# and Java/Kotlin' but there's no dedicated CI workflow visible for verifying interoperability. The current checks.yml likely only tests Go. A new workflow should validate that proto messages serialize/deserialize correctly across language boundaries and that basic actor communication works in multi-language scenarios.

  • [ ] Create .github/workflows/cross-platform-tests.yml that sets up Go, .NET, and Java environments
  • [ ] Add test cases in examples/ directory demonstrating Go↔C# and Go↔Java message passing
  • [ ] Configure workflow to run protobuf compilation and verify generated code in all three languages
  • [ ] Document the cross-platform testing setup in CONTRIBUTING.md with language-specific requirements

Add deduplication context integration tests and document deduplication strategy

The file actor/deduplication_context.go and actor/deduplication_context_test.go exist, but there's no dedicated documentation explaining the deduplication guarantees, failure scenarios, or best practices. Additionally, there are no integration tests showing how deduplication behaves under concurrent actor interactions, network partitions, or restarts—critical for production use.

  • [ ] Expand actor/deduplication_context_test.go with tests for edge cases: concurrent duplicate messages, actor restart with pending deduplication state, timeout handling
  • [ ] Create DEDUPLICATION.md documenting the deduplication strategy, idempotency guarantees, and limitations
  • [ ] Add example in actor/actor_example_test.go or new file showing idempotent message handling pattern
  • [ ] Document deduplication configuration options in actor/config.go comments and update README.md

🌿Good first issues

  • Add comprehensive documentation and examples for the EventStream pub-sub pattern (actor/eventstream_process.go has minimal tests and examples compared to behavior.go and future.go)
  • Implement benchmark comparisons against Akka and Akka.NET in a new benchmarks/ directory with concrete throughput/latency metrics to substantiate the '2M msgs/sec' claim
  • Write integration tests for cross-platform actor communication (Go↔C#) by importing protoactor-dotnet test scenarios and validating message serialization round-trips

Top contributors

Click to expand

📝Recent commits

Click to expand
  • 288962e — build(deps): bump golang.org/x/net in /examples/cluster-pubsub (#1198) (dependabot[bot])
  • 2e47680 — Handle endpoint connection errors (#1233) (rogeralsing)
  • 9182a3e — feat(config): add KeepAliveTTL and RetryInterval options for etcd configuration (#1258) (pipiaha)
  • f2e2b9c — build(deps): bump github.com/hashicorp/consul/api from 1.32.4 to 1.33.0 (dependabot[bot])
  • 7fcd073 — build(deps): bump github.com/Workiva/go-datastructures (#1260) (dependabot[bot])
  • 7aba3f2 — build(deps): bump golang.org/x/text from 0.31.0 to 0.33.0 (dependabot[bot])
  • ea62016 — Merge pull request #1280 from pipiaha/feat/request_future_concurrency (rogeralsing)
  • 8a4c714 — fix(config): revert to dev branch (pipiaha)
  • 901bcd0 — Merge branch 'dev' into feat/request_future_concurrency (pipiaha)
  • 2b5ab34 — feat(context): update RequestFuture to use NewGrainCallOptions for configuration (pipiaha)

🔒Security observations

The Proto Actor Go codebase has a moderate security posture with several areas of concern. The primary issues are related to infrastructure configuration (unencrypted services, overly permissive access controls in docker-compose.yml) rather than code vulnerabilities. The project itself appears well-structured with CI/CD integration. Key recommendations: (1) secure the development infrastructure by enabling TLS for Consul and etcd, (2) verify and update the Go version specification,

  • High · Outdated Go Version in go.mod — go.mod. The go.mod file specifies Go 1.25.2, which is a future/unrealistic version. This suggests the file may be misconfigured or from a template. Using unrealistic Go versions can lead to unpredictable behavior, missing security patches, and compatibility issues. Fix: Update go.mod to specify a stable, currently-supported Go version (e.g., 1.21 or 1.22). Verify the actual Go version used in the project matches security requirements.
  • Medium · Unencrypted Service Communication in Docker Compose — docker-compose.yml - etcd and consul services. The docker-compose.yml configuration exposes Consul, etcd, and Zookeeper services with HTTP (unencrypted) communication. The etcd service is configured with --listen-client-urls using plain http://0.0.0.0:2379, which transmits data without encryption. Fix: Enable TLS/HTTPS for all inter-service communication. For etcd, use --client-auto-tls=true or configure proper TLS certificates. For Consul, enable HTTPS and mutual TLS. Restrict port exposure to only necessary services.
  • Medium · Overly Permissive Etcd Configuration — docker-compose.yml - etcd service command. The etcd container listens on 0.0.0.0:2379 (all interfaces) without authentication configured. This allows potential unauthorized access to the service from any network that can reach this port. Fix: Restrict the listen address to localhost or specific trusted IPs. Implement etcd authentication with RBAC. Consider using a reverse proxy with authentication in front of etcd.
  • Medium · Missing Security Headers and TLS in Development Infrastructure — docker-compose.yml - consul service. The Consul UI is exposed on port 8500 without apparent TLS or authentication. While this is a development environment, it establishes insecure patterns and could be accidentally deployed to production. Fix: Enable Consul ACLs and TLS. If used in development, add explicit documentation warnings. Consider using .env files with instructions for production security setup.
  • Low · Outdated Dependency Versions — go.mod - indirect dependencies. Several dependencies use older versions that may have known vulnerabilities: prometheus/client_golang (1.23.2), opentelemetry packages (1.38.0), and golang.org/x/sys (0.37.0). While go.mod specifies specific versions, regular updates are recommended. Fix: Run 'go get -u ./...' and 'go mod tidy' regularly. Use 'go list -u -m all' to identify outdated packages. Implement dependency scanning in CI/CD pipeline (e.g., GitHub Dependabot is already configured but ensure it's actively maintained).
  • Low · Missing HTTPS in Actor System Communication — actor/actor_system.go, actor/config.go. Proto Actor framework configuration files don't show explicit TLS/mTLS setup for inter-actor communication. While the framework may support this, the absence of examples or default secure settings could lead to unencrypted RPC traffic. Fix: Review and document TLS configuration options for actor-to-actor communication. Provide secure-by-default examples. Add middleware for automatic encryption of remote actor messages.
  • Low · Incomplete Zookeeper Configuration — docker-compose.yml - zookeeper service. The docker-compose.yml includes a Zookeeper service definition that is incomplete (no command or environment variables specified). This could lead to unexpected behavior or security misconfiguration if the service is activated. Fix: Complete the Zookeeper configuration with proper security settings, or remove it if not in use. If retained, add authentication, ACLs, and secure port configuration.

LLM-derived; treat as a starting point, not a security audit.


Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.

Healthy signals · asynkron/protoactor-go — RepoPilot