Resource Limits
The Actor VM enforces layered, deterministic resource limits to ensure safety, fairness, and consensus across clients. Limits are expressed along two orthogonal dimensions — Cycles (compute) and Cells (data) — and are complemented by strict execution constraints that make Python-on-chain deterministic.Note: Names and examples in this page are conceptual and illustrative. Final interfaces and usage should follow the SDK and Developer Guide; CIP specifications define normative protocol behavior. Scope
- What is limited: compute, data, module imports, numeric ranges, async scheduling, and timers.
- Where it is enforced: at the VM instruction loop, host function boundaries, transaction ingress/egress, and block-level scheduler.
Resource dimensions
Cycles (compute)
- Unit: an abstract instruction step. Charged before executing each Python bytecode and on selected control-flow/runtime events.
- Enforced under protocol-defined cycles limits for execution; when exhausted, execution halts with an Out of Cycles error.
- Partial cost table (consensus-critical; see CIP-3):
Dynamic surcharges (CIP-3): for type/size-dependent operations, a base cost is charged plus a runtime surcharge (e.g., string/list concatenation proportional to length).
Cells (data)
- Unit: 1 Cell = 1 byte. Charged at I/O boundaries via host functions and at transaction ingress/egress.
- Enforced as
cells_limitper transaction. When exhausted, execution halts with an Out of Cells error. - Metering points (CIP-3):
- Intrinsic calldata: charged before VM execution (payload size).
- Host functions: data-bearing calls must charge the exact byte count.
storage_set(key, value):len(key) + len(value)Cells.put_blob(data):len(data)Cells.
- Scratch
/tmp: immediate charge on file writes by number of bytes. - Return data: charged after a successful handler return by byte size.
Deterministic execution constraints (consensus-critical)
These constraints are mandatory to keep all clients in lockstep (CIP-3):- No JIT compilation: the VM executes in pure interpretation mode.
- No arbitrary C extensions: high-performance needs are exposed as deterministic, metered host functions.
- Module import whitelist only:
- Import cost: 100 cycles on first import (+ module init cost), 5 cycles on repeated imports within the same transaction.
- Importing a disallowed module raises
ImportErrorand consumes 50 cycles penalty.
- Floating-point determinism: all FP ops must use a version-locked software library; native FPU use is forbidden.
- Big integer cap: integer bit length must not exceed 4096 bits; operations exceeding the cap raise
OverflowError. Large-int costs scale with operand bit length. - Exception handling is explicitly metered: raising, entering try blocks, and jumping into except/finally each have base costs.
- Async/await scheduling is single-threaded and deterministic: strict FIFO of ready coroutines; no true concurrency; no nondeterministic gather patterns.
- Canonical serialization for messages/state: deterministic encoding with lexicographically sorted dict keys; floats serialized by exact IEEE-754 bits.
Timers and block-level budgets
Timers are delivered and executed under a per-block budget (CIP-1):- The scheduler maintains tiered queues and, at each block, executes due timers within
TIMER_PROCESSING_BUDGET_CYCLES. - Within that budget, due timers are prioritized by an intra-block auction using GBA bids; execution ends when the queue empties or the budget is consumed.
- Scheduling a timer (conceptual API) and cancellation are charged at fixed Cycle costs (see partial table above). Execution of the timer handler itself is subject to the standard cycles/cells limits of the invocation.
Failure modes and enforcement
- Out of Cycles: the VM halts immediately; no further bytecodes execute.
- Out of Cells: the VM halts immediately; no further I/O is performed.
- Disallowed import:
ImportErrorwith penalty cycles charged. - Big integer overflow:
OverflowErrorwhen results exceed the 4096-bit cap. - Determinism violations (e.g., attempting JIT or native FPU): forbidden by implementation and specification; clients must not diverge.
Developer guidance
- Budgeting: estimate Cycles by dominant loops and host calls; estimate Cells by payload, storage writes, blob sizes, and return data.
- Prefer streaming/chunked approaches for large data to stay within Cells limits.
- Keep module usage inside the whitelist; avoid dynamic imports that may fail and waste cycles.
- Validate numeric ranges and payload sizes early to avoid expensive partial work before hitting limits.
- For timer-driven flows, assume best-effort delivery under a fixed per-block budget; timers may defer to subsequent blocks under congestion.

