Skip to content

Limits

Every figure here comes from a named constant; when the code and this page disagree, the code wins.

VMLimits::default (crates/runtime/src/logic.rs) bounds one run. Exceeding a limit traps the run, which then leaves an empty diff.

Limit Default
Memory 1024 pages = 64 MiB
Stack 200 KiB
Gas 1 000 000 000 (one point per executed WASM operator)
Host calls 1 000 000
Registers 100; 100 MiB each; 1 GiB in all
Logs 1024 lines of at most 16 KiB (a longer line traps)
Events 100; kind 100 bytes; data 16 KiB
Cross-app calls 8; function name 100 bytes; parameters 16 KiB
Storage key / value 1 MiB / 10 MiB
Storage writes 100 000, and 128 MiB in all
Blob handles 100; chunk 10 MiB; 512 MiB written in all
Ordered-index scan 100 000 entries
Return value 16 MiB
Commit artifact 16 MiB
Method name 256 bytes
WASM module 128 MiB (256 MiB precompiled)
Table elements 100 000

A run’s result also has to fit the log: its whole entry — arguments, diff, events — must stay under 1 MiB.

Limit Value Constant
One log entry 1 MiB calimero_log::MAX_ENTRY_BYTES
One sealed request, one HTTP body 64 MiB MAX_SEALED_BYTES, DefaultBodyLimit
A raw development bundle 16 MiB bundle_put
One blob (an uploaded file, a package .mpk, uploaded or fetched from a registry) 47 MiB: it reaches the other nodes base64-encoded in one sealed request MAX_BLOB_BYTES, MAX_MPK_BYTES
Metadata (organization, member, team, app) 16 KiB of JSON MAX_METADATA_BYTES
Passkeys per account 10 AddPasskey
Registered web origins 8 per package, 4096 per cluster, 255 bytes each MAX_ORIGINS_PER_PACKAGE, MAX_PACKAGE_ORIGINS, MAX_ORIGIN_BYTES
Aliases per account 1000, each 1–64 characters MAX_ALIASES
Passkey label 64 characters MAX_LABEL_CHARS
Upgrade runs kept per organization 20 UPGRADE_RUNS_KEPT
Follow-up depth 3 MAX_FOLLOWUP_DEPTH
Events kept per app 10 000 EVENT_RING
Entries whose touched entities search remembers 4096 TOUCHED_RING
Presence 512 authors per app, 4 KiB state, 7 s TTL MAX_AUTHORS_PER_APP, MAX_STATE_BYTES, PRESENCE_TTL_MS
Event and presence streams per node 4096 MAX_EVENT_STREAMS
Open passkey ceremonies per node 10 000, each 5 minutes MAX_PENDING_CHALLENGES
Sealed sessions per node 16 384; 1 h lifetime, 10 min idle MAX_SESSIONS, SESSION_LIFETIME
Forward to an app’s leader 5 s, then retry FORWARD_TIMEOUT
Compute runs, files and job nodes See Compute actions MAX_COMPUTE_WALL_SECS, MAX_COMPUTE_MEMORY_MIB, MAX_COMPUTE_FUEL
Replicas per app --replicas, 3 by default; moves keep at least 3

A body past a limit is answered 413, error code TOO_LARGE, with the limit in the message. Under 64 MiB the node’s own check answers, sealed like any answer. Past 64 MiB the sealed envelope is refused before it can be opened, so its 413 ({"error":{"code":"too_large",...}}, which calimero-client reports as TOO_LARGE) comes back in the clear: sealing it would mean spending the request id on bytes nobody has authenticated, letting a relay make the node vouch for a refusal of a request the client never sent. The node reads and drops the rest of such a body before it answers, up to 1 GiB and 120 s (MAX_DISCARDED_BYTES, SEALED_READ_TIME), because a client that sends its whole body before reading would otherwise meet a reset, not the answer; past that, or for a declared length past 1 GiB or a client waiting on Expect: 100-continue, it answers at once and closes.

What Lifetime
Session token 15 minutes
Refresh token 30 days; exchanged by the first refresh once an hour old
Session-signing key rotation 6 hours by default, at least 30 minutes
API key Up to 1 year
Invite 7 days by default; 1 use by default
Client idempotency record 24 hours; the newest 10 000 kept regardless; at most 1 000 000
Node idempotency record (node:…) 10 minutes; the newest 1000 kept regardless
Revoked session remembered 1 hour
sys_until / read-index wait 2 seconds

Per account, set by the operator (POST /ops/quotas), checked at apply (The system group); a refusal is 429 QUOTA_EXCEEDED.

Quota Default
Apps owned 100
Bundle and package bytes uploaded 1 GiB
API keys 50
Organizations owned 20
Accounts on the cluster 100 000
Stored file bytes per organization (maxFileBytesPerOrg) 50 GB
Concurrent compute runs per organization (maxConcurrentRunsPerOrg) 4
Reserved compute fuel per organization (computeFuelPerOrg) 10 times MAX_COMPUTE_FUEL
Fuel per developer per UTC day (maxFuelPerDeveloperPerDay; the developer usage is billed to: a deployment’s owner for its instances, else the app’s org or owner, D78) 0 (no limit); checked before a client’s call or an xcall to any of its apps runs, not at apply: init, timer ticks and event handlers still run and count (D76)

The fuel cap is approximate by at most one refresh interval (5 s). A call never asks a peer: the node reads the apps it replicates from its own replicas, and the others from what every peer answered at its last refresh, which asks all peers at once every 5 s while a cap is set. A developer can so run past its cap for up to one interval. A peer that stops answering keeps the figures it last reported. An app no peer has reported yet counts as nothing, so the cap fails open rather than closed: refusing every call to all of a developer’s apps whenever one replica of one of them is unreachable would be worse than a developer briefly exceeding a daily cap. The cap is a decimal string in JSON (D20); a node writes a non-zero cap only once every node runs its release or newer (409 UPGRADE_PENDING).

Organization roles (guest < member < admin < owner), team row roles (lead, member, read-only) and the capability bits are on Organizations, teams & access. The storage crate’s per-entity write mask (OpMask: WRITE, DELETE, ADMIN) is unchanged; it is checked inside the run, on the leader.