Reaktor at Mega-Scale

0. TL;DR

Reaktor is not a single-process framework. The current core is local-first per runtime island: a graph runs inside an Android app, iOS app, browser bundle, Cloudflare Worker, Spring server, desktop app, or test process. Those islands are already joined by typed contracts and platform adapters. What Reaktor does not yet have is a general distributed graph runtime where arbitrary nodes, actors, stores, and transports are placed, routed, observed, and rebalanced across a fleet.

That distinction matters:

  • A runtime island is one local graph/container in one process or isolate.
  • A system graph is the product topology across many islands plus external resources.
  • A deployment cut is the edge where a local graph connection becomes HTTP, local invocation, Worker service binding, Pub/Sub, queue, workflow, peer transport, or actor remoting.

The old framing overfit on actors and made Reaktor sound like "one process until actor sharding saves it." The code and docs show a broader model:

AreaReality today
Graph kernelReal: typed graph, nodes, ports, edges, lifecycle, DI, navigation, wiring checks.
Service layerReal: graph-neutral Service, typed handlers, ServiceNode, interceptors, HTTP client, Spring WebFlux adapter, Cloudflare/Hono adapter.
Cloud/server substrateReal: Spring/k3s server, Cloudflare Workers, service bindings, Durable Objects substrate, graph gateway, Pub/Sub adapter, Memgraph/Postgres integration.
Local actorsReal: ActorNode has a single-threaded mailbox, supervision, timers, and ObjectStore state.
Async fabricPartial/design: ServiceTransport names PUBSUB, QUEUE, WORKFLOW, PEER, but only HTTP/local are generally dispatched.
Distributed actorsDesign: location-transparent ActorRef, placement, sharding, membership, and remote wire are not yet built.
Deployment graphDesign: graph visitors can inspect and transform topology, but there is not yet a complete deployment partition pass.

So the mega-scale strategy is not "make actors distributed first." It is:

  1. Make the system graph the source of truth for topology, contracts, ownership, policy, and deployment boundaries.
  2. Make deployment cuts first-class and operable, so a graph edge can honestly become a local call, HTTP route, Pub/Sub topic, queue, workflow, Worker binding, or future actor transport.
  3. Add production backend discipline at those cuts: command boundaries, invariants, durable facts, idempotency, outbox/inbox, ledgers, sagas, reconciliation, rate limits, circuit breakers, and observability.
  4. Use stateful actors and Durable Objects for domains that naturally partition by key. They are one scaling lane, not the center of the whole strategy.

The crisp external claim becomes:

Reaktor gives large teams one typed, inspectable model from client UI to edge workers to server services to stateful runtimes. It keeps local execution fast, makes distributed boundaries explicit, and lets teams adopt it one surface at a time without replacing their backend estate.


1. The corrected mental model

Runtime islands

The Graph class is a scoped runtime container. It owns nodes, provider/consumer ports, lifecycle, DI scope, coroutine scope, navigation state, and a dispatcher. That graph is local to a process or isolate. A phone app graph, a desktop graph, a browser graph, a Spring server graph, and a Cloudflare Worker graph are separate runtime islands.

This is a strength, not a weakness. Local islands keep the hot path simple: no accidental RPC, no remote field access, no hidden network, and no distributed-systems tax on every button click.

System graph

The bigger promise is the system graph: many runtime islands plus the things they depend on. A node can be a screen, route, repository, actor, service, worker, queue, topic, database, secret, deployment target, telemetry stream, or AI tool. An edge can be local wiring, a route, an HTTP operation, a bus publication, a durable workflow handoff, a sync edge, or a deployment relationship.

This is the part that can matter to a very large organization. They already have services, databases, queues, feature platforms, dashboards, and meshes. Reaktor should not ask them to throw those away. It should give them one inspectable model over the application layer and the boundaries where that layer touches the rest of the estate.

Deployment cuts

A deployment cut is where the graph stops being local and becomes infrastructure.

Examples:

  • a ServiceNode provider runs in the same graph during tests, but becomes an HTTP route in Spring;
  • the same service contract becomes a Cloudflare Worker route at the edge;
  • a write command publishes through an outbox into Pub/Sub;
  • a background job becomes a queue consumer or workflow;
  • a per-room stateful object runs as a Cloudflare Durable Object;
  • a future actor reference becomes local channel send, gRPC, Pub/Sub, or Durable Object call by policy.

This is the right abstraction boundary. Reaktor should make each cut explicit, typed, observable, and testable. It should not pretend the network disappeared.


2. What the source tree actually supports

Source scope: the docs and code in /Users/ovd/dev/reaktor and /Users/ovd/dev/bestbuds.

PrimitiveCurrent shapeScale implication
GraphLocal runtime container with lifecycle, DI, concurrency, navigation, nodes, and ports.It is a runtime island, not a global distributed VM.
autoWire() / requireFullyWired()Local provider/consumer port matching plus explicit failure on unconnected consumers.The wiring model is inspectable and compiler/tool friendly.
ServiceGraph-neutral typed request/response contract; client and server handlers share serializers and operation identity.This is the strongest current cross-process seam.
ServiceNodeProjects a Service into the graph as provider ports; consumers do not need to know whether the handler is local or remote.This is how local and remote execution stay one model without hiding deployment.
ServiceTransportHTTP, LOCAL, PEER, PUBSUB, QUEUE, WORKFLOW.The intent vocabulary exists; delivery implementations beyond HTTP/local are still work.
Spring adapterService.toRouter() mounts typed handlers on WebFlux.JVM/k3s service hosting is real.
Cloudflare adapterWorker services, Hono routes, bindings, Durable Object substrate, D1/R2/KV/Hyperdrive adapters.Edge/serverless hosting is real, but not a generic distributed graph runtime.
ActorNodeLocal single-threaded mailbox via limitedParallelism(1), bounded channel, ask/tell, timers, supervision, ObjectStore state.Great local state machine; not cluster-routable yet.
Pub/Sub adapterJVM Pub/Sub publish/pull/ack/topology support exists and is used in server-worker hello paths.Good durable wire substrate; not yet unified as reaktor-bus.
Graph gatewayCloudflare Worker reaches private Memgraph through the Spring server's authenticated HTTP gateway.Existing code already crosses runtime islands through explicit adapters.
MultitenancyMemgraph has strong mandatory tenant parameterization; other stores are mostly design.Scale requires tenant scope to become a framework-wide ambient constraint.
Data layerOn-device store, Postgres, Memgraph, R2, Cloudflare stores are present in pieces; DataDescriptor and sync engine are designed.The topology is credible, but not yet one declared data plane.

The accurate summary is:

Reaktor has strong local runtime islands and real service/edge/server adapters. It does not yet have a complete distributed placement, transport, data-authority, and deployment-control layer.

That is much more useful than "single process." It tells builders where to invest.


3. What must not be diluted

Mega-scale features are only valuable if they preserve the reasons Reaktor is interesting.

  1. Explicit typed wiring. Dependencies should remain visible as ports, edges, handlers, facets, and deployment cuts. Hidden service lookup is a regression.
  2. Local fast path. In-process graph calls, local actor sends, local stores, and local UI state should stay simple and fast. Distribution is opt-in at a declared cut.
  3. No fake network transparency. Remote work must remain suspend, fallible, observable, and bound to a delivery contract. Location can be abstracted; latency and partial failure cannot.
  4. Service contracts stay graph-neutral. Modules can use the graph internally, but their public API should remain usable from normal Kotlin, Spring, Workers, tests, or existing systems.
  5. Production effects are not CRUD. Commands, invariants, durable facts, ledgers, outbox/inbox, idempotency, reconciliation, and sagas belong in the model where money, inventory, credits, reservations, notifications, or entitlements are involved.
  6. Adapters over rewrites. Large orgs will keep their stores, brokers, service mesh, identity provider, feature platform, and observability stack. Reaktor must wrap and project them before it tries to replace anything.
  7. Evidence before scale claims. Distributed features need benchmark artifacts, failure-mode tests, trace propagation, and operational runbooks.

4. Where Reaktor can matter to very large teams

Large organizations rarely need a new "app framework" in the abstract. They need safer ways to change large systems without losing topology, contracts, ownership, policy, or runtime behavior. The adoption lanes below are ordered by trust required, not by ambition.

A. Client + edge + BFF convergence

This is the lowest-risk landing zone.

Use Reaktor to model one product surface across Android, iOS, web, edge, and BFF:

  • one typed graph for routes, screens, interactors, service calls, and policy;
  • one Service contract shared between clients and server/edge;
  • one generated or inspected topology for tests, docs, telemetry, and AI tooling;
  • one migration path that does not disturb the core backend.

This is where runtime islands are an advantage. A client session, edge request, and BFF request are naturally partitioned. The platform does not need a distributed actor cluster to prove value here.

B. Graph-visible service contracts over brownfield systems

Most large teams already have the backend. Reaktor should describe how product surfaces talk to it.

The first useful enterprise feature is not "replace Kafka" or "replace the mesh." It is:

  • wrap existing services behind typed Service contracts;
  • project those contracts into the graph with ServiceNode;
  • attach interceptors for auth, retries, idempotency, rate limits, circuit breakers, telemetry, shadow traffic, and policy;
  • render the result as topology that engineers and agents can inspect.

This turns Reaktor into a control surface for application composition while the existing data plane continues to run where it already runs.

C. Production backend discipline

At scale, the server story is not "CRUD endpoints." It is command processing with durable evidence and controlled side effects.

Reaktor should make these first-class backend patterns:

PatternWhy it mattersReaktor surface
Command boundaryA user intent should be validated before mutation.RequestHandler plus facets/interceptors.
Idempotency keyOne real command should create one durable business effect, even under retries.ServiceInterceptor, dedup store, inbox/outbox.
Transactional outboxAvoid unsafe dual writes between DB and broker.Server module plus bus relay.
Inbox / consumer dedupAt-least-once delivery becomes exactly-once effect.Bus consumer interceptor.
Saga / process managerLong workflows span banks, humans, warehouses, queues, and time.Actor, Durable Object, workflow, or reaktor-work.
LedgerConserved or scarce things need balanced movements, not mutable counters.Data descriptor, event log, projections, reconciliation.
ReconciliationExternal truth will drift; the system needs repair loops.Work scheduler, service commands, audit facts.

The ledger point is especially important. Money, wallet credits, loyalty points, escrow, inventory reservations, seats, API credits, entitlements, and quotas should usually be modeled as movements between accounts or states. That gives operators the answers mutable fields cannot: why the balance is what it is, what campaign created it, whether a retry is safe, and how to repair drift without rewriting history.

Enterprise operation requires explicit state ownership and distributed contracts. Actors are one way to serialize a state machine. The business value is the invariant and the durable fact.

D. Workbench and graph control plane

Once a team has a graph-visible surface, the workbench becomes useful:

  • topology inspection;
  • deployment impact analysis;
  • generated docs;
  • traces with graph attribution;
  • policy review;
  • change approval;
  • AI agents operating through typed graph tools instead of source-code guesses.

This is the "Unreal Engine for applications" direction: the graph is the product model, and tools operate on that model. It matters to large organizations because onboarding, review, and change coordination become visible.

E. Stateful partitioning with actors and Durable Objects

Actors enter when the domain is naturally keyed:

  • room by room;
  • cart by user;
  • booking slot by resource and time;
  • game/session by match id;
  • rate limit by principal;
  • saga by workflow id;
  • entitlement ledger by account.

In those cases, a single-threaded actor or Durable Object is a good shard implementation. The current ActorNode is local. Cloudflare Durable Objects are already a native edge actor-like substrate. The missing layer is a general placement and remoting model that can route by key across JVM pods, Pub/Sub, gRPC, and Durable Objects.

The key correction:

An actor can be a shard. It is not the whole mega-scale strategy.

Stateful partitioning should be built after the service, bus, data, tenant, and observability cuts are honest enough to operate it.


5. The target architecture

                        System graph
        topology, ownership, contracts, policy, data roles, deployment cuts
                                      |
             -----------------------------------------------------
             |                     |                             |
      Runtime island          Runtime island                Runtime island
      mobile/web app          Cloudflare edge               Spring/k3s server
      local graph             worker/DO graph               service graph
             |                     |                             |
       local ports        service binding / HTTP           HTTP / local / bus
             |                     |                             |
             ---------------- deployment cuts -------------------
                                      |
                  HTTP | Pub/Sub | Queue | Workflow | DO | future actor wire
                                      |
             -----------------------------------------------------
             |                     |                             |
        Data authority          Async fabric                Operability plane
   Postgres/Memgraph/D1       outbox/inbox/DLQ          traces/metrics/snapshots
   ClickHouse/R2/SQLite       ordering/backpressure      budgets/runbooks

The architecture has three important properties.

First, local development and local runtime stay ergonomic. A graph can still be created, wired, tested, and run in one process.

Second, production distribution is not accidental. The cut from local call to remote route, message, queue, workflow, or actor wire is a thing the graph can name and tools can inspect.

Third, scale work lands as adapters, visitors, interceptors, deployment passes, and stores around the graph, not as a forked "enterprise runtime" that changes how normal app code is written.


6. Roadmap: scale the graph before scaling actors

The old order put cluster actors first. The better order is to make the distributed boundaries observable and production-safe, then put stateful partitioning on top.

StepBuildWhy it comes here
R1Status-truth snapshots. Machine-readable status for each doc/module: real, partial, designed, absent.Prevents roadmap pages from overstating the runtime.
R2Service contract hardening. Operation identity, generated clients, schema/version policy, interceptor ordering, auth and trace propagation.This is the cross-process surface already closest to real.
R3Deployment cut model. A graph visitor/pass that can classify edges as local, HTTP, Worker binding, Pub/Sub, queue, workflow, DO, or future actor wire.Makes topology and deployment one model instead of prose.
R4Bus and outbox. A reusable reaktor-bus envelope, routing table, outbox relay, inbox dedup, DLQ, claim-check, and retry classifier.Server, notifications, workflows, sync, and actor remoting all need the same durable wire.
R5Data authority and tenancy. DataDescriptor, tenant-scoped stores, Postgres RLS, tenant-qualified actors/DOs, sync buckets, residency, quotas, cells.Distributed execution without data authority and tenant isolation is not enterprise-ready.
R6Operability plane. OTel propagation, graph-attributed traces, metrics export, health/readiness, load tests, budgets, chaos/failure-mode tests.Large teams buy what they can operate.
R7Stateful partitioning. Cluster-routable actor references, placement directory, local/gRPC/PubSub/DO transports, passivation, rebalancing, recovery.Actors become credible once the transport, data, tenancy, and observability layers exist.

R7 remains important. It should not be the first proof point. It is a stateful scaling lane that depends on the earlier lanes.


7. Open-source and commercial split

For large organizations, the scaling capability itself must be open and self-hostable. Otherwise they will either reject it or fork it.

Open sourceCommercial value
Graph kernel, ports, services, local actors, adapters, CLI, workbench primitives.Migration of real product surfaces and design-system integration.
Service transports, bus, outbox, generated clients, deployment cut model.Bespoke adapters to existing meshes, brokers, feature systems, observability, and identity.
Data descriptor, tenant model, reference stores, sync primitives.Tenant/cell/residency design for a specific organization.
Distributed actor runtime and Durable Object/JVM reference backends.Managed control plane for placement, rebalancing, fleet visibility, and failure drills.
Performance harnesses, OTel wiring, topology snapshots.Scale audits, SLO design, CI gates, runbooks, and support.
Workbench and graph tool protocol.Hosted governance, review, and AI-agent operation over an enterprise fleet.

Do not paywall "can run at scale." Charge for integration, operation, support, and time-to-value.


8. Anti-patterns

Anti-patternWhy it fails
"Reaktor is single process until actors are distributed."It erases the real multi-runtime service/edge model and makes one planned feature carry the whole story.
"The actor is the shard" as the central message.Good for per-key stateful workloads; misleading for service contracts, data authority, workbench, policy, and brownfield adoption.
Fake transparent RPC.Hiding latency and partial failure recreates the old distributed object mistake. Remote edges need explicit delivery contracts.
CRUD-first backend framing.Production flows need commands, invariants, logs, ledgers, idempotency, outbox, sagas, and reconciliation.
Replacing a large org's infrastructure too early.The first adoption path should wrap and project existing systems, not demand a rip-and-replace.
Distributed actors before bus/data/tenancy/observability.Placement without durable delivery, authority, isolation, and telemetry is not operable.
Closed-core scale features.Large teams need trust, auditability, and the option to self-host. Capability gates invite forks.

9. Recommendation

Use this sequence:

  1. Rewrite the public story around runtime islands, system graph, and deployment cuts. Stop calling the framework single-process. Say the current graph runtime is local-first and multi-target, and that the missing work is a distributed control/deployment layer.
  2. Lead enterprise adoption with client/edge/BFF and service-contract pilots. These create value without requiring a distributed actor cluster.
  3. Build production server discipline as a graph-native layer. Commands, facts, ledgers, idempotency, outbox/inbox, sagas, queues, and reconciliation are the backend patterns that serious systems need.
  4. Make topology and deployment cuts inspectable. A large team should be able to ask "what talks to what, through which transport, under which policy, with which owner and SLO?" and get an answer from the graph.
  5. Then build stateful partitioning. Keep ActorNode local and simple. Add placement and remoting around it. Treat actors and Durable Objects as the right tool for keyed state, not as the only way Reaktor scales.

The one-sentence version:

Reaktor scales by making application topology explicit across many runtime islands, turning deployment boundaries into typed and operable cuts, and adding stateful partitioning only where the domain actually needs a single-writer shard.

  • Framework Overview - The full shipped-vs-designed map of the framework.
  • Graph Kernel - The graph, node, port, edge, facet, visitor, event, snapshot, and command model.
  • Service Layer - The graph-neutral typed service contract and its Spring/Workers projections.
  • Server - Production backend primitives: idempotency, outbox, ledgers, sagas, resilience, bus, and high-scale operation.
  • Reaktor Bus - The durable async delivery fabric over Pub/Sub, queues, outbox, DLQ, replay, and graph-visible routing.
  • Data Layer - Data authority, stores, sync, analytics, and graph-visible topology.
  • Multitenancy - Tenant scope, isolation, cells, residency, quotas, and enforcement.
  • Distributed Actors - The stateful partitioning lane for keyed actor workloads.
  • Competitive Landscape - Where Reaktor should integrate instead of compete.