The WebAssembly runtime turns one compiled Atoll Program into a fleet of
single-threaded execution reactors. Each reactor hosts the link groups it needs,
routes invocations to cached Unit instances, and drives generated continuations
and host I/O.
AtollRuntime
├─ current Program
├─ routing and singleton pins
└─ Store fleet
├─ Store 0: reactor thread + Wasmtime Store
│ ├─ link-group Instance A
│ ├─ link-group Instance B
│ └─ UnitInstance cache
└─ Store 1: reactor thread + Wasmtime Store
├─ link-group Instance A
└─ UnitInstance cacheThe repeated word “Store” is intentional: a runtime Store owns one Wasmtime
Store, but that Wasmtime store can contain several link-group WebAssembly
instances.
Program
A Program is the immutable, compiled deployment artifact shared by the
runtime fleet. It contains:
- one or more JIT-compiled link-group artifacts;
- the decoded
atoll.unitsmanifest; - Unit-to-group mappings;
- debug, cancellation, and runtime metadata;
- stable program-wide Unit identifiers;
- compatibility facts used during redeploy and migration.
AtollRuntime publishes the current Program through an atomic snapshot.
In-flight operations retain the Program they began with, while new routing sees
the replacement after cutover.
Link groups
A link group is one WebAssembly module boundary with its own linear memory and embedded raw allocator. Grouping lets the compiler and deployer choose between one large module and smaller independently replaceable bundles.
Within a Store:
- only groups containing hosted Units are instantiated;
- every hosted group has a distinct Wasmtime
Instanceand memory; - method functions, scheduler functions, globals, and allocator exports resolve through the Unit’s group;
- entering a Unit switches the runtime’s active allocator and collector tables to that group.
This switching is current behavior, not a future design. A Program with one link group follows the same path with no meaningful topology difference.
Stores
A runtime Store is a dedicated operating-system thread running a current-thread Tokio reactor. It owns:
- one non-
SendWasmtime Store; - its hosted link-group instances;
- per-Unit bounded invocation inboxes;
- a cache of Unit instances;
- timers and async host-operation state;
- scheduler and debug state local to the reactor.
Wasmtime state never leaves its reactor thread. Parallelism comes from running several Stores, not from concurrently entering one Wasm instance.
A Store moves through Up, Draining, and Down liveness states. Routing
selects only eligible Stores. Draining stops new placement while allowing
existing work to complete or migrate.
Unit instances
A runtime UnitInstance is an Atoll state container, not a Wasmtime
Instance. It is a cache entry keyed by (UnitId, LocalInstanceId) and owns:
- one persistent arena;
- one root task control block;
- temporary invocation frame-region metadata;
- per-instance host I/O and resource slabs;
- placement, recency, and debug-shelving state.
It executes at most one invocation at a time. Several Unit instances can share the same link-group WebAssembly instance because their mutable Atoll state lives in separate arenas and host slabs.
See Units for identity, placement, and lifecycle.
Routing
An invocation names a Unit, method, and instance target:
Specific(LocalInstanceId)addresses an existing logical instance on an eligible Store;AnyOrSpawnpermits the runtime to select a reusable instance or create one.
Singleton placement pins the Unit to one Store on its first invocation and does not evict its instance during ordinary operation. Replicated placement selects round-robin among Stores that host the Unit and applies the Unit’s instance limit and eviction policy.
Routing does not silently discard overload:
try_invokeis nonblocking and returns the original invocation when the bounded inbox is full;invokewaits for enqueue capacity, not for method completion;invoke_and_waitwaits for the invocation result.
The default per-Unit inbox capacity is 256. It is deployment policy and may be configured.
Concurrency
Concurrency exists at three levels:
| Level | Mechanism |
|---|---|
| Runtime | multiple Store threads execute in parallel |
| Store | current-thread reactor interleaves Units and I/O |
| Invocation | generated CPS scheduler interleaves Atoll tasks |
Within one Unit instance, generated code is a single mutator. Suspension yields to the Store, but no other invocation may enter that same instance until it finishes or is shelved and explicitly resumed. This is why arena reference counts can remain non-atomic.
Isolation
The boundaries contain different classes of failure:
- a failed task is represented in its task tree;
- a terminated invocation poisons its Unit instance;
- instance eviction releases its complete arena and host state;
- a failed Store removes one routing target;
- a redeployed Program can replace only affected Stores when topology permits.
Isolation is not a transactional promise. External I/O may already have taken effect when an invocation fails or times out.
Defaults
Current runtime defaults include:
| Setting | Default |
|---|---|
| per-Unit inbox | 256 invocations |
| eviction sweep | 1 second |
| instance watermark | 1,024 |
| initial arena | 256 KiB |
These values describe current policy, not source-language constants.
Invariants
- a
UnitIdis program-wide and independent of link-group placement; - every hosted Unit resolves code and memory through its declared group;
- a Wasmtime Store is accessed only by its owning reactor thread;
- a Unit instance is entered by at most one invocation at a time;
- in-arena mutation and reference counting remain single-mutator;
- bounded queues report or apply backpressure rather than growing without limit;
- Program replacement does not mutate artifacts already used by in-flight work.
Boundaries
Read Execution for the generated scheduler, Host I/O for suspension, and Deployment for group replacement and instance migration.