moxzi
Docs / Reference / Limits

Limitsalpha

What is every hard number and bound in the system?

Every number on this page is a constant in this repository or a figure measured against mainnet, with its source named so you can re-check it. Where a bound is a decision rather than a measurement, the reason is in the source file's comment beside it — this page gives the value, not the argument.

Internet Computer limits the toolchain builds against#

These are the replica's, not moxzi's. They are what the on-chain compiler is engineered around; source: ic-limits-understanding.md, quoting dfinity/ic rs/config/src/subnet_config.rs.

BoundValue
Instructions per update message (with DTS)40 B
Instructions per DTS slice / round2 B
Instructions per round, subnet-wide4 B
Instructions per query5 B
Instructions per install_code300 B
wasm64 instruction cost2 cycles/instruction (2× wasm32)
wasm32 heap / wasm64 heap4 GiB / 6 GiB
wasm_memory_limit default3 GiB (exceeding it traps)
Stable memory500 GiB
Ingress payload2 MiB
Same-subnet inter-canister payload10 MiB
Chunk store1 MiB chunks, 100 chunks / 100 MiB
Heap-delta rate limit, per canister75 MiB dirtied per round

Exceeding the message cap is not a moxzi diagnostic: the replica kills the canister with Canister exceeded the limit of 40000000000 instructions for single message execution (quoted at bin/compiler-canister/Main.mo:3848).

Compiler canister step budgets#

The on-chain compiler ends its own messages before the replica does. All in bin/compiler-canister/Main.mo.

ConstantValueLine
onchainStepUnitBudget24 units per message3811
onchainStepInstrBudget6 B instructions per message3882
CONCLUDE_FRESH_START2 B — a conclude unit only starts below this3885
batchGarbageLimit1 GiB estimated garbage ends the batch3840
Allocation ceiling per message16 MiB (rts_total_allocation delta)4209
Sched.defaultHeapGrowthLimit4 MiB growth since last yieldmops/mo-sched/src/Sched.mo:72
DEFAULT_CODEGEN_INSTR_BUDGET30 B1677
START_PARSE_WINDOW300 M, doubles on a no-progress message1704
MAX_PARSE_WINDOW30 B1682

On-chain build storage quotas#

StoreCapSource
VFS, per caller64 MiBvfsMaxBytesPerCaller, Main.mo:446
VFS, all callers1 GiBvfsMaxBytesTotal, Main.mo:447
Content-addressed blob store256 MiBblobStoreMaxBytes, Main.mo:960
Whole-build cache200 MiBbuildCacheMaxBytes, Main.mo:1215
Retained artifact100 MiBretainedArtifactMaxBytes, Main.mo:3500

A caller over quota gets a trap naming the number, not a truncated upload. Files materialised from a mops tag are not charged against the VFS quota — they are references into the blob store.

Escrow pricing#

quoteEscrowFor(sourceBytes) = max(escrowCyclesFloor, sourceBytes × escrowCyclesPerByte).

ConstantValueSource
escrowCyclesPerByte750,000Main.mo:2969
escrowCyclesFloor500 B cycles (0.5 T)Main.mo:2970
Settlement charge3× measured actual, remainder refundeddocs/onchain-builds.md

Both are operator-settable. 750,000 is 3× the worst measured rate (200,657 cycles per source byte, the compiler compiling itself).

Measured on-chain builds#

Measured on mainnet, 2026-08-21 (docs/onchain-builds.md; hashes also on the site's proof table).

BuildSourceMessagesCyclesArtifact hash
hello.mo1 file, 217 B52~0.001 T
the compiler, self-compiling177 files, 8.0 MB2,345~1.6 T830f3e87…
evm_engine661 files, 15.3 MB4,138~1.6 T/attempt178c6429…

instructionsUsed under-reports real spend by 2.3×–3.4×. Do not price from it.

Parser depth#

BoundValueSource
MAX_PARSE_DEPTH (expressions and types)128mops/mo-frontend/src/Parser.mo:1176

Past it you get expression nested too deeply (limit 128) or type nested too deeply (limit 128) — a diagnostic, never a stack overflow. Gated by scripts/parser_depth_gate.sh, which fires a 600-deep operator chain and a 3000-deep type.

Browser stack#

Measured by scripts/web_page_compile_gate.sh (numbers in its header comment, lines 9–15 and 140–146).

QuantityJS-frame-equivalents
Compiler requirement, before the frame diet~13,759
Compiler requirement, today~8,426
A Chrome tab's main thread~11,154
A worker~5,303 — smaller than a tab

A worker is not a workaround for a stack problem. Separately, expression nesting is the binding constraint on generated code: ~60 chained operators compile in a tab, and past ~400 the limit moves into parsing (docs/limits.md).

moxzid request limits#

BoundValueSource
Request body, authenticated endpoints64 MiBMAX_BODY, moxzi/server/src/main.rs:1117
Request body, open /site gateway8 MiBSITE_MAX_BODY, main.rs:1122

The /site cap is lower because that gateway has no bearer token in front of it.

moxzid execution defaults#

All settable on the command line; source moxzi/server/src/main.rs.

FlagDefault
--instruction-limit40,000,000,000 (0 disables)
--cycles100 T (DEFAULT_CYCLES)
--heartbeat-ms1000
--timer-ms100
--outcall-timeout-secs30
--history50 messages per actor
--listen127.0.0.1:7000

Runtime caps shared by every runtime#

Both the native and browser backends use these constants so a program refused in one is refused in the other. Source moxzi/runtime/src/.

CapValueSource
Nested self-call depth512machine.rs:285
Per-(sender, receiver) queue500sys.rs:301
Retained log lines per actor4096sys.rs:45
History argument preview128 bytesmachine.rs:1259
Wasm stack (server and CLI)4 MiBlib.rs:76, moxzi/src/main.rs:213
Best-effort call deadlinecapped at 300 ssys.rs:803

Management-canister caps#

CapValueSource
Outcall response, when unspecified2 MiBmanagement.rs:344
Chunk size1 MiBmanagement.rs:371
Chunks per store100management.rs:377
Snapshots per canister10management.rs:416
Retained canister-change records20management.rs:30
wasm_memory_limit default4 GiBmanagement.rs:613

Off-chain cycle prices#

The off-chain runtimes bill with the IC's own formula so a program developed here does not under-attach on mainnet. Source moxzi/runtime/src/lib.rs and sys.rs.

ItemCycles
Per message590,000
Per ten instructions4
Canister creation500,000,000,000
HTTP outcall, base400,000,000
HTTP outcall, per byte100,000
Threshold signature26,000,000,000

Things that are not bounded here#

Not boundedConsequence
Browser instructionsV8 has no fuel, so metering is opt-in instrumentation (meter: true): +16% to +20% module size, +49% run time on call-heavy code. Unmetered, preemption is a wall-clock worker deadline rather than a count
Off-chain storage growthquotas exist on-chain only; a moxzid state directory grows until the disk says no
Number of moxzid processesnothing coordinates two of them; each is a separate world

Metering (browser instrumentation)#

Measured on 2026-08-21. Instrumentation is a host-side transform at install time; the compiled artifact is untouched, so byte-identity is unaffected.

QuantityValue
Module size, counter.mo+19.3%
Module size, the asset canister+20.1%
Module size, the compiler itself (7.5 MB)+15.8%
Run time, call-heavy code+49%
Run time, a tight arithmetic loop (one basic block)+87%
Default per-message limit40,000,000,000 instructions — the IC's own cap
Fuel global__moxzi_fuel, exported, mutable i64, initialised to 0

The tight-loop figure is the worst case by construction: the loop body is the only basic block, so every charge also tests. Straight-line blocks charge without testing, because a block that cannot cycle only repeats a check the next loop header or function entry is about to do.

Source: moxzi/runtime/src/meter.rs, scripts/web_meter_gate.sh.

Next#

On this pageInternet Computer limits the toolchain builds againstCompiler canister step budgetsOn-chain build storage quotasEscrow pricingMeasured on-chain buildsParser depthBrowser stackmoxzid request limitsmoxzid execution defaultsRuntime caps shared by every runtimeManagement-canister capsOff-chain cycle pricesThings that are not bounded hereMetering (browser instrumentation)Next