Overview

The nine metered dimensions of a transaction’s resource budget, with each dimension’s default, hard bound, and what happens when it is exceeded. For how the effective value of a dimension is composed from the global default, packet governance, the source clause, and the signed envelope, see Resource Limits. The budget is metered over the whole transaction, including the work to decode the signed envelope — not only the transaction body.

A transaction aborts the instant any one dimension is exceeded. When it does, the exhaustion message names the meter and the budget it exceeded; on the main metering paths — the operation reduction tick, evaluator calls, and call depth — it also names which layer bound it. See Choosing your limits.

Consumption dimensions

These count a running total over the whole transaction.

fuel_ops

Weighted operations consumed by the transaction. Each primitive is charged according to the fuel cost model; the transaction aborts when the running total would exceed the cap.

  • Default: 1,048,576 (2^20)
  • Hard bound: none — governance may raise it (raising it only spends more deterministic fuel)

eval_calls

The number of evaluator node evaluations performed by the transaction.

  • Default: 1,048,576 (2^20)
  • Hard bound: none

constructed_elems

The number of runtime values the evaluator constructs over the transaction. Bounds the total amount of value construction a transaction can perform regardless of the shape of any single value.

  • Default: 1,048,576 (2^20)
  • Hard bound: 1,048,576 (2^20)

Structural dimensions

These are peaks — the largest value reached at any single point, not a running total.

call_depth

The deepest lambda-call (recursion) nesting reached. Checked before each call frame is entered: a transaction that reaches exactly the limit of frames runs; one more frame aborts it.

  • Default: 4,096
  • Hard bound: none — reachable past the default only by reconfiguring the machine’s process stack

value_height

The deepest value nesting constructed. Bounds how deeply nested a single constructed value may be.

  • Default: 4,096
  • Hard bound: none

elem_count

The most elements in a single container (dictionary/array).

  • Default: 16,777,216 (2^24)
  • Hard bound: 16,777,216 (2^24)

string_bytes

The longest string or blob, in bytes. Enforced on decode: a string or blob whose length exceeds the cap is rejected as the value is read.

  • Default: 4,294,967,296 (2^32)
  • Hard bound: 4,294,967,296 (2^32)

packet_elems

The number of runtime elements in one packet, checked when the packet is sealed. Its value comes only from the global default and packet governance — a transaction source clause and a signed envelope do not apply to it. The ceiling equals the serialization stream item cap, so a packet whose element count is admissible here is also admissible to a decoder.

  • Default: 16,777,216 (2^24)
  • Hard bound: 16,777,216 (2^24)

render_bytes

The number of bytes produced by a single value render (_str, _code_str, JSON rendering, error/ diagnostic text). Charged as each byte is produced, so an over-budget render stops mid-render rather than materializing the full output. A render feeding committed state aborts the transaction on overflow; a diagnostic render emits a sentinel marker and stops (see Resource Limits).

  • Default: 16,777,216 (16 MiB)
  • Hard bound: 4,294,967,296 (2^32) — the one dimension whose default sits below its hard bound, so governance may raise the effective value toward the ceiling

Abort reasons

Every rejection on the limits path carries a deterministic message — the same input is rejected the same way on every node.

When Message
fuel_ops budget exhausted Transaction operation budget exceeded: <n> weighted operations consumed (bound by <scope>)
eval_calls budget exhausted Transaction evaluation budget exceeded: <n> evaluate() calls consumed (bound by <scope>)
call_depth exceeded Transaction call-depth limit exceeded: the call would nest <n> (bound by <scope>)
render_bytes exceeded on a committed render render aborts the transaction (a diagnostic render truncates with a sentinel instead)
a structural cap (elem_count, value_height, constructed_elems, packet_elems, string_bytes) exceeded the transaction aborts at the point the cap is reached (packet_elems at seal, string_bytes on decode)
a governance / clause / envelope value out of range ... '<name>' is out of range [1, <ceiling>]
a limits update that is not a {name -> count} dictionary ... argument must be a dictionary of {name -> count}
a non-string dimension key ... dimension name must be a string
an unknown dimension name ... unknown limit dimension '<name>'
observe-mode metering requested outside test mode observe-mode metering is not permitted outside test mode

<scope> is global, packet, clause, or envelope — the layer that bound the dimension, so an operator knows which knob to raise.

A signed envelope’s __limits is parsed as part of envelope decoding, before the transaction’s read-only and eligibility checks run. So a call carrying a malformed __limits is rejected with the deterministic ... must be a dictionary of {name -> count} parse error rather than the read-only (or other eligibility) rejection — the malformed dictionary is caught first. The two paths are distinct and each deterministic.