Skip to main content
A shared actor is a single Stateful Actor type reachable from two or more Edge Compute functions on the same account. The function that ships the actor class owns the actor; other functions on the same account declare the same type under their own binding name and ship no class — their binding routes to the owner’s actor and its state. Shared actor topology: an owner function ships the Account class under binding ACCOUNT; a reference function ships no class and declares the same type under binding READONLY; both bindings route to one durable Account actor on the same Telnyx account.

Why Share an Actor

  • Split read and write paths into separate functions with their own auth, rate limits, and deploy cadence — without duplicating state.
  • Let a second function call into a domain the first one owns (e.g., a reporting function reads an account actor that a payments function owns).
  • Keep one durable actor behind many entrypoints. Both functions talk to the same per-name state; writes through one binding are visible to reads through the other.
Both functions must be on the same account — shared actors are bounded by account.

The Pattern

The owner function is a normal Stateful Actor project — it ships the class. The reference function declares the same type under a different binding and ships no actor class — its binding routes to the owner’s actor and state; no second instance is created. There’s no new-func flag for “reference-only,” so the workflow is: scaffold with --actor (to mint a func_id and write telnyx.toml), then drop the actor class and rename the binding.

Walkthrough: a Read-Only Account Reference

Prereq: an owner function for the type already shipped on your account (the account from the Quick Start, type Account).

1. Mint a func_id and scaffold, then drop the class

2. Point telnyx.toml at the owner’s type under a new binding

Edit the [[actors]] block — keep type equal to the owner’s type, change binding:
Leave name, main, compatibility_date, and the [edge_compute] func_id as scaffolded.

3. Replace src/index.ts with a class-free handler that calls env.READONLY

Key point: no export class Account in this file. The bundler roots at main, so with nothing importing the class, the reference bundle ships class-free (a few KB) — that’s what makes it reference-only.

4. Install deps and ship (same as the owner)

5. Prove they share one actor

Write through ACCOUNT, read through READONLY, same balance → one durable actor (Account), two functions. Both must be on the same account; the reference’s type must exactly match the owner’s.

Rules of Thumb

  • Same account, same type. Reference bindings whose type doesn’t match an owner already on the account won’t resolve.
  • Only one function owns the class. The owner ships the actor class; every other function declares the same type and ships no class.
  • Renaming the binding is fine. Each function picks its own binding name — that’s the property on env for that function. The type is what glues them together.
  • Reference bundles are small. With no class import, the bundler emits a class-free bundle. Keep it that way: don’t import the actor class from your reference function.

Next Steps

  • Quick Start — ship the owner function this reference calls into
  • Runtime APIActorNamespace, ActorStub, and the binding surface
  • Alarms — schedule deferred work from inside an actor method