> For the complete documentation index, see [llms.txt](https://docs.megaeth.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.megaeth.com/spec/megaevm/resource-limits.md).

# Resource Limits

This page specifies the limits MegaETH enforces on transaction execution and block construction. It defines the limit set, the split between pre-execution and runtime enforcement, and the outcomes of transaction-level and block-level violations.

## Motivation

The transaction `gas_limit` alone is insufficient to protect MegaETH from resource-heavy transactions. A transaction may remain within its total gas budget while still producing excessive state growth, too many key-value updates, or too much execution data.

MegaETH therefore enforces independent resource ceilings in addition to the standard gas limit. Without those ceilings, a transaction could remain valid under gas accounting while still imposing disproportionate execution, storage, or networking costs on nodes.

Resource limits also need deterministic block-building semantics. Implementations must agree on which transactions are rejected permanently, which are skipped for the current block, which are included as failed, and when the last transaction that exceeds a block-level runtime limit is still allowed.

## Specification

The named constants referenced in this section are defined later in [Constants](#constants).

### Overview

MegaETH enforces seven distinct resource limits:

1. standard gas limit,
2. transaction encoded size,
3. data-availability size,
4. [compute gas](/spec/reference/glossary.md#compute-gas),
5. data size,
6. KV updates,
7. state growth.

Limits 1–3 are checked before execution. Limits 4–7 are enforced during execution and accumulated at block level after execution.

For exact counting rules of compute gas, data size, KV updates, and state growth, see [Resource Accounting](/spec/megaevm/resource-accounting.md). For the relationship between total gas, compute gas, and storage gas, see [Dual Gas Model](/spec/megaevm/dual-gas-model.md).

### Limit Set

A node MUST enforce the following limits:

| Resource                                                                                | Phase         | Transaction Limit       | Block Limit                        |
| --------------------------------------------------------------------------------------- | ------------- | ----------------------- | ---------------------------------- |
| [Gas Limit](https://ethereum.org/en/developers/docs/gas/#block-size)                    | Pre-execution | Sequencer-configured    | `block.gasLimit` from block header |
| Transaction Size                                                                        | Pre-execution | Sequencer-configured    | Sequencer-configured               |
| [DA Size](https://docs.optimism.io/stack/transactions/transaction-fees#the-l1-data-fee) | Pre-execution | Sequencer-configured    | Sequencer-configured               |
| [Compute Gas](/spec/reference/glossary.md#compute-gas)                                  | Runtime       | `TX_COMPUTE_GAS_LIMIT`  | No separate limit                  |
| Data Size                                                                               | Runtime       | `TX_DATA_LIMIT`         | `BLOCK_DATA_LIMIT`                 |
| KV Updates                                                                              | Runtime       | `TX_KV_UPDATE_LIMIT`    | `BLOCK_KV_UPDATE_LIMIT`            |
| State Growth                                                                            | Runtime       | `TX_STATE_GROWTH_LIMIT` | `BLOCK_STATE_GROWTH_LIMIT`         |

The absence of a separate block-level compute gas limit means that cumulative block compute gas is bounded only indirectly by the block gas limit.

### Pre-Execution Limits

#### Standard Gas Limit

A node MUST apply standard Ethereum gas-limit semantics. The transaction's `gas_limit` field MUST fit within both the sequencer-configured per-transaction gas cap and the remaining block gas budget from the block header.

#### Transaction Size

A node MUST check the EIP-2718 encoded transaction size before execution. Transactions that exceed the configured transaction-size limit MUST be rejected permanently. Transactions that fit the transaction-level size limit but would cause the block's cumulative encoded transaction size to exceed the configured block-level size limit MUST be skipped for the current block.

#### DA Size

A node MUST check the compressed data-availability size of each non-deposit transaction before execution. Transactions that exceed the configured transaction-level DA size limit MUST be rejected permanently. Transactions that fit the transaction-level DA size limit but would cause the block's cumulative DA size to exceed the configured block-level DA size limit MUST be skipped for the current block.

Deposit transactions MUST be exempt from DA size limit checks. Their DA size MAY still be tracked for monitoring purposes.

### Runtime Transaction-Level Limits

A node MUST enforce the following runtime transaction-level limits during execution:

* `TX_COMPUTE_GAS_LIMIT`
* `TX_DATA_LIMIT`
* `TX_KV_UPDATE_LIMIT`
* `TX_STATE_GROWTH_LIMIT`

If any runtime transaction-level limit is exceeded during execution, the transaction MUST:

1. halt,
2. preserve its remaining gas,
3. produce a failed receipt (`status = 0`),
4. and still be included in the block.

The failed transaction's actual resource usage MUST still count toward the block's cumulative resource counters.

<details>

<summary>Rex6 (unstable): system-originated transactions are not halted by transaction-level limits</summary>

Under Rex6, the four runtime transaction-level limits MUST NOT be enforced against a [system-originated transaction](/spec/system-contracts/system-tx.md#system-originated-transaction-metering-exemption). The node MUST still record such a transaction's resource usage; only the per-transaction halt decision is suppressed. The transaction's standard EVM `gas_limit` — for the pre-block system calls, floored at 30,000,000 — remains the only bound that can halt it.

</details>

#### Precompile Compute-Gas Bound

A precompile invocation's compute-gas consumption MUST be bounded by the compute gas remaining in the current call frame. A node MUST cap the gas forwarded into a precompile at the minimum of the caller-supplied call gas limit and the remaining compute-gas budget, so a precompile cannot consume more compute gas than remains. A precompile whose minimum cost exceeds that cap MUST fail without performing its computation, halting with `PrecompileOOG`. On successful or reverting precompile returns, the caller's gas-refund accounting MUST reflect the originally forwarded gas limit minus the precompile's actual spent gas, so the cap does not alter the caller's observed refund on non-halting returns.

### Runtime Block-Level Limits

A node MUST maintain cumulative block counters for:

* data size,
* KV updates,
* state growth,
* and compute gas.

The node MUST update those cumulative counters after transaction execution.

For data size, KV updates, and state growth, the first transaction that causes the cumulative block usage to meet or exceed the block-level limit MUST still be included in the block. Subsequent candidate transactions MUST be skipped before execution once the block is already at or above the corresponding block-level runtime limit.

Although block compute gas usage MAY be tracked, the protocol does not impose a separate block-level compute gas cap.

### Two-Phase Block Building Workflow

When constructing a block, a node or sequencer MUST process candidate transactions in the following order:

1. Perform pre-execution validation.
2. If a transaction violates a transaction-level pre-execution limit, reject it permanently.
3. If a transaction would exceed a block-level pre-execution limit, skip it for the current block.
4. If any stable block-level runtime limit is already reached or exceeded from prior included transactions, skip later candidate transactions that depend on that resource category.
5. Execute the transaction.
6. If a runtime transaction-level limit is exceeded, include the transaction as failed.
7. Update cumulative block counters with the transaction's actual resource usage.
8. Include the transaction in the block.

### Outcomes

| Outcome  | Cause                                                                            | Receipt      | Block Impact                                                 |
| -------- | -------------------------------------------------------------------------------- | ------------ | ------------------------------------------------------------ |
| Success  | Transaction completes within all applicable limits                               | `status = 1` | Counts toward all relevant block counters                    |
| Failed   | Runtime transaction-level limit exceeded                                         | `status = 0` | Still included and counts toward all relevant block counters |
| Skipped  | Current block cannot admit the transaction without violating a block-level limit | No receipt   | Not included; may be reconsidered in a later block           |
| Rejected | Transaction-level pre-execution limit exceeded                                   | No receipt   | Permanently invalid                                          |

### Per-Call-Frame Runtime Budgets

Each [call frame](/spec/reference/glossary.md#call-frame) receives a bounded share of the remaining budget for compute gas, data size, KV updates, and state growth. Each inner call frame receives `remaining × FRAME_LIMIT_NUMERATOR / FRAME_LIMIT_DENOMINATOR` of its parent call frame's remaining budget. These budgets are system-enforced — the calling contract cannot directly control them. Only total gas (the standard EVM gas parameter in CALL-like opcodes) remains under direct contract control. If a child call frame exceeds its local budget, it MUST revert with `MegaLimitExceeded(uint8 kind, uint64 limit)`. The parent call frame MAY continue execution.

The top-level call frame's budget MUST equal the transaction limit minus any resource usage already recorded before the first frame begins. These deductions include transaction-only intrinsic usage and any DB-dependent pre-execution usage that is resolved before the first frame starts. Each resource dimension deducts only the pre-frame items relevant to it:

* **Data size** — base transaction data (110 bytes), calldata byte length, access-list entry sizes, EIP-7702 authorization records, and the caller account update.
* **KV updates** — EIP-7702 authority account updates and the caller account update.
* **State growth** — valid EIP-7702 authorizations that create previously non-existent authority accounts, resolved during pre-execution.
* **Compute gas** — standard EVM transaction intrinsic gas (not enumerated here; see EIP-2028 and related specs).

These deductions ensure that pre-frame costs reduce the budget available to the first call frame, preventing transactions from front-loading pre-frame usage to escape per-frame limits.

<details>

<summary>Rex6 (unstable): EIP-7702 authority accounting moves to validation and adds dynamic SALT account-creation gas</summary>

#### Authority State Growth Resolution

Pre-Rex6, the state-growth contribution of EIP-7702 authorizations that create previously non-existent authority accounts is resolved during pre-execution, after the caller nonce bump.

Under Rex6, a node MUST resolve this contribution during transaction validation, before the gas-limit and fee-affordability checks. The set of authorities and the per-authority effects are derived from the same applied-authorization scan that drives the data-size and KV-update narrowing in [Resource Accounting](/spec/megaevm/resource-accounting.md).

#### Dynamic Authority Account-Creation Gas

Under Rex6, for each *applied* EIP-7702 authorization that materializes a previously non-existent authority account, a node MUST charge dynamic new-account storage gas for that authority using the same SALT bucket pricing as other new-account materialization paths. This charge MUST be folded into the transaction's intrinsic gas so that it is deducted before the first call frame and enforced against the gas limit and fee affordability. A node MUST NOT charge this new-account gas twice when a value-transferring call materializes the same account that an applied authorization materializes.

</details>

## Constants

| Constant                   | Value       | Description                                     |
| -------------------------- | ----------- | ----------------------------------------------- |
| `TX_COMPUTE_GAS_LIMIT`     | 200,000,000 | Maximum compute gas per transaction             |
| `TX_DATA_LIMIT`            | 13,107,200  | Maximum data size per transaction               |
| `BLOCK_DATA_LIMIT`         | 13,107,200  | Maximum cumulative block data size              |
| `TX_KV_UPDATE_LIMIT`       | 500,000     | Maximum KV updates per transaction              |
| `BLOCK_KV_UPDATE_LIMIT`    | 500,000     | Maximum cumulative block KV updates             |
| `TX_STATE_GROWTH_LIMIT`    | 1,000       | Maximum state growth per transaction            |
| `BLOCK_STATE_GROWTH_LIMIT` | 1,000       | Maximum cumulative block state growth           |
| `FRAME_LIMIT_NUMERATOR`    | 98          | Numerator of per-call-frame budget forwarding   |
| `FRAME_LIMIT_DENOMINATOR`  | 100         | Denominator of per-call-frame budget forwarding |

## Rationale

**Why split limits into pre-execution and runtime phases?** Gas limit, encoded transaction size, and DA size are known before execution and can be checked cheaply. Compute gas, data size, KV updates, and state growth depend on actual execution and therefore cannot be known precisely in advance.

**Why include failed runtime-limited transactions?** The node must execute a transaction to know whether it exceeds a runtime limit. If such transactions were excluded from the block, an attacker could force repeated expensive executions at no cost. Including failed transactions ensures that the sender pays for the resources consumed.

**Why allow the first transaction to push a block over a runtime block limit?** Runtime block limits are known only after execution. Allowing the first over-limit transaction to be included maximizes block utilization while preserving deterministic block-building behavior for later transactions.

**Why no separate stable block-level compute gas limit?** Cumulative block compute gas is already indirectly constrained by the block gas limit. The stable protocol therefore does not need a second independent block-level compute gas ceiling.

**Why cap precompile gas at the remaining compute-gas budget?** A precompile whose natural cost exceeds the remaining compute-gas budget would otherwise execute fully and overshoot the budget, with the overshoot detected only after the work was already performed. Capping the forwarded gas at the remaining compute-gas budget converts that overshoot into a fail-fast `PrecompileOOG` before the computation runs, keeping the compute-gas limit enforceable for precompile work as well as ordinary opcodes.

## Security Considerations

**If a transaction that exceeds a runtime limit is excluded from the block rather than included as failed**, an attacker can force the sequencer to execute expensive but failing transactions at no cost — the sender never pays because the transaction is dropped. Including failed transactions ensures the sender always pays for consumed resources.

## Spec History

* [MiniRex](/spec/network-upgrades/minirex.md) introduced compute gas, data size, and KV update limits, with transaction-level data and KV limits set to 25% of the corresponding block limits.
* [Rex](/spec/network-upgrades/rex.md) changed the stable runtime transaction-level limits to `TX_COMPUTE_GAS_LIMIT = 200,000,000`, `TX_DATA_LIMIT = 13,107,200`, `TX_KV_UPDATE_LIMIT = 500,000`, and introduced state-growth limits.
* [Rex3](/spec/network-upgrades/rex3.md) retained the stable resource-limit set.
* [Rex4](/spec/network-upgrades/rex4.md) — added per-call-frame runtime budgets; intrinsic resource costs (always deducted before execution) are now reflected in the top-level frame budget before it is forwarded to child frames.
* [Rex5](/spec/network-upgrades/rex5.md) — bounded a precompile invocation's compute-gas consumption by the remaining compute-gas budget, failing the precompile with `PrecompileOOG` rather than letting it overshoot the budget.
* [Rex6](/spec/network-upgrades/rex6.md) (**unstable**) — moved EIP-7702 authority state-growth resolution from pre-execution to validation, and added dynamic SALT account-creation gas for each net-new applied authority to the pre-frame intrinsic gas deduction.
* [Rex6](/spec/network-upgrades/rex6.md) (**unstable**) — stopped enforcing the four runtime transaction-level limits against system-originated transactions; usage is still recorded.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.megaeth.com/spec/megaevm/resource-limits.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
