# Limits What a module can use, the same in every host. ## A run's budget | key | default | what | |---|---|---| | `inFlight` | 6 | calls in flight at once; more wait their turn | | `subscriptions` | 4 | subscriptions open at once | | `calls` | 100 | calls in the whole run | | `callsPerMinute` | unlimited | calls per minute (a fixed window from the run's start); past it a call fails with `Module exceeded N calls per minute` and the run goes on, as past `calls` | | `events` | 1000 | events the module handles | | `wallMs` | 60000 | wall time of the run, in ms | | `queue` | 256 | events waiting for the module; past it, subscription messages are dropped (`dropped` on the next message) or the subscription closes (`close_on_overflow`) | | `log` | 1000 | call records kept in the result (the last ones) | | `ioBytes` | 1048576 (1 MiB) | the wasm's input and output per event, JSON bytes; never past 16 MiB | | `heldBytes` | 16777216 (16 MiB) | the run's [held values](../modules/calls.md#held-values) together, JSON bytes | A host may change them: `ATLIBS_BUDGET` for the CLIs, `budget` for `runModule`. A host may also set `calls`, `callsPerMinute`, `events` and `wallMs` unlimited: `Infinity` in `runModule`'s `budget`, the string `"unlimited"` in JSON (`ATLIBS_BUDGET='{"calls":"unlimited","wallMs":"unlimited"}'`). Unlimited `wallMs` sets no deadline: the run ends when the module is done, nothing is pending, or the host aborts it. Any other value that is not a positive number leaves the default. `ioBytes` is the one to raise for big values: an event's input holds the module's state and the event (a call's output, binary bodies as `$bytes`), its output the calls it makes. 16 MiB is the ceiling whatever a host sets: the input sits in the module's 64 MiB memory beside its parsed copy, what it decodes and its output, and past that most modules would run out of memory anyway. A manifest's budget only lowers it, like the rest. ```bash run ATLIBS_BUDGET='{"events":1}' atlibs run examples/rust/compose/composition.json ui caller '{"nsid":"com.example.compose.lookup","input":{"n":2}}' \ --handler confirm=wasm:examples/rust/compose#lookup 2>/dev/null | jq -r .error ``` ```output Module exceeded 1 events ``` ### A module that serves The defaults fit a one-shot action. A module that answers requests until the tab closes (an ingress answering HTTP through a relay) needs `calls`, `events` and `wallMs` unlimited; give it a `callsPerMinute` when it holds a session. What still bounds it: `inFlight`, `subscriptions`, `queue`, the time per event, and its `calls` list and session scope. ## The wasm | limit | value | |---|---| | module size | 4 MiB (build release) | | input and output per event | 1 MiB each; a host may raise it to 16 MiB (`ioBytes` above) | | memory | 1024 pages (64 MiB) | | time per event | 5 s | | imports | none | | entry names | `[A-Za-z_][A-Za-z0-9_]{0,63}` | ## Calls - Only NSIDs in `calls` (when the module lists any). - `params` are strings (`"limit": "10"`); bodies are JSON. - Writes: only records this host created for the module, or any record in an `anyRecords` collection. - Signed in: only what the module's own session record's scope allows ([Server sessions](../server/sessions.md)). - Plain HTTP (`com.fedfork.exec.http.fetch`): only origins in both the module's `http` and the host's allowlist; no redirects; the response body arrives whole ([calls](../modules/calls.md#plain-http)). ## Compositions | limit | default | |---|---| | `depth` | 8 routed calls deep | | `calls` | 100 routed calls per run | A manifest's `limits` (and an instance's `budget`) may lower them, never raise them past a host's, and never say unlimited. A host may set `calls` unlimited (`runCompose`'s `limits`). ## Hosts | | | |---|---| | wasm runs at once per Node or Rust process | `ATLIBS_WASM_CONCURRENCY` (default: the core count) | | WebRTC | STUN only, no TURN | Previous: [Lexicons](lexicons.md) | Next: [Environment](env.md)