---
eip: 7907
title: Meter Contract Code Size And Increase Limit
description: Increases the contract code size limit introduced in EIP-170 and adds gas metering to code loading
author: Charles Cooper (@charles-cooper), Qi Zhou (@qizhou), Matt (@lightclient), Dragan Rakita (@rakita)
discussions-to: https://ethereum-magicians.org/t/eip-remove-contract-size-limit/23156
status: Draft
type: Standards Track
category: Core
created: 2025-03-14
requires: 170, 2929, 3860, 7702
---

## Abstract

This EIP increases the contract code size limit from 24KB (24576 bytes) introduced in [EIP-170](./eip-170.md) to 64KB (65536 bytes), and adds gas metering for excess code loading. It introduces a gas cost of 2 gas per (32 byte) word for contract code exceeding 24KB, allowing deployment of contracts of any size while preventing DoS attacks through appropriate gas metering. Lastly, it also commensurately increases initcode size limit from 48KB, introduced in [EIP-3860](./eip-3860.md), to 128KB (131072 bytes).

## Motivation

EIP-170 introduced a 24KB contract code size limit to prevent potential DoS attacks, as large contract code requires O(n) resource cost in terms of disk reads, VM preprocessing, and Merkle proof sizes, all of which are not directly compensated by gas fees. However, this limit restricts legitimate use cases for large contracts.

This EIP proposes a gas-based solution that allows contracts of larger size while ensuring that users loading large contracts pay gas proportional to the additional resources they consume. This approach aligns with Ethereum's gas model philosophy of paying for the resources consumed. A new limit has been set at 64KB, so that raising the gas limit does not break assumptions in the p2p layer.

Improving developer experience is the primary motivation for increasing the contract size limit. The current 24KB ceiling forces developers to split functionality across multiple contracts, introduce proxies or delegatecall-based indirection, and rely on architectural patterns like the Diamond Standard—even when those patterns aren't otherwise necessary. These workarounds can increase code complexity, deployment costs, and audit surface. By raising the limit, developers can keep more logic in a single contract, improving readability and lowering gas usage by avoiding unnecessary cross-contract calls. This also makes smart contract development more accessible to newer developers, who can move from idea to deployment without first learning advanced contract composition patterns.

## Specification

### Definitions

| Name | Value | Description |
| --- | --- | --- |
| `COLD_SLOAD_COST` | `2100` | The cost charged for cold loading storage as defined by [EIP-2929](./eip-2929.md). |
| `WARM_STORAGE_READ_COST` | `100` | The cost charged for loading warm storage as defined by [EIP-2929](./eip-2929.md). |
| `COLD_ACCOUNT_ACCESS_COST` | `2600` | The cost charged for loading a cold account as defined by [EIP-2929](./eip-2929.md). |
| `GAS_PER_CODE_WORD` | `2` | The cost charged per word of code loaded beyond the initial `24KB` amount. |
| `FORK_BLKNUM` | TBD | The block number of the hard fork that this EIP is activated. |

The following values are updated:

| Name | Old Value | New Value | Description |
| --- | --- | --- | --- |
| `MAX_CODE_SIZE` | 24KB (`0x6000`) | 64KB (`0x10000`) | The maximum size for code as set in [EIP-170](./eip-170.md) |
| `MAX_INITCODE_SIZE` | 48KB (`0xc000`) | 128KB (`0x20000`) | The maximum size for code as set in [EIP-3860](./eip-3860.md). Always set at `2 * MAX_CODE_SIZE` |

#### Helpers

```python
def ceil32(n: int) -> int:
    return ((n + 31) // 32) * 32

def excess_code_size(n: int) -> int:
    return max(0, n - 0x6000)
```

### Behavior

1. Update the [EIP-170](./eip-170.md) introduced `MAX_CODE_SIZE` constant of 24KB (`0x6000` bytes) to 64KB (`0x10000` bytes).
2. Introduces a new cold/warm state for contract code. Specifically, change the gas schedule of operations that load code, e.g. the opcodes `CALL`, `STATICCALL`, `DELEGATECALL`, `CALLCODE` and `EXTCODECOPY` are modified so that dynamic `EXCESS_CODE_COST= ceil32(excess_code_size(len(code))) * GAS_PER_CODE_WORD // 32` gas are added to the access cost if the code is cold. When the code is an [EIP-7702](./eip-7702.md) delegation to another account, if target account code is cold add additional gas should be accounted. Warming of the contract code is subjected to the journaling and can be reverted similar to other state warming in [EIP-2930](./eip-2930.md).
3. Update the [EIP-3860](./eip-3860.md) introduced `MAX_INITCODE_SIZE` limit of 48KB (`0xc000` bytes) to 128KB (`0x10000` bytes).
4. If a large contract is the entry point of a transaction, the cost calculated in (2) is charged before the execution and contract code is marked as warm. This fee is not calculated towards the initial gas fee. In case of out-of-gas halt, execution will stop and the balance will not be transferred.
6. Empty code ( with `keccak("") = "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470"`) is always considered warm.

| Contract                | Gas changes (only opcodes that load code)                          | How?                                                                                                                       |
| ----------------------- | ------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------- |
| Cold account and code   | Add `COLD_SLOAD_COST=2100`, `EXCESS_CODE_COST`, and `COLD_ACCOUNT_ACCESS_COST=2600`         | Contract not in access list nor accessed prior in the txn                                                           |
| Warm account and cold code | Add `COLD_SLOAD_COST=2100`, `EXCESS_CODE_COST`, and `WARM_STORAGE_READ_COST=100`         | Already accessed balance, storage, or included in access list ([EIP-2930](./eip-2930.md))                                               |
| Warm account and code | `WARM_STORAGE_READ_COST=100`         | Already accessed account code                                               |

`COLD_ACCOUNT_ACCESS_COST`, `COLD_SLOAD_COST`, and `WARM_STORAGE_READ_COST` are defined in [EIP-2929](./eip-2929.md#parameters).

### Migration

This EIP adds a new field to the account tuple, `codesize`. That is, the account tuple goes from having the following four fields, `(nonce, balance, storage_root, code_hash)` to `(nonce, balance, storage_root, code_hash, codesize)`. The reason for this is that most key-value databases in use by production clients do not allow peeking at the size of a value pointed to by a given key without actually loading the full contents of the value.

To avoid forcing a full migration, the following rules are followed:

1. Any account created or updated on or after `FORK_BLKNUM` should additionally have its codesize written into the account tuple.
2. Any account which does not have the `codesize` field is assumed to have codesize less than 24KB.

## Rationale

The gas cost of 2 per word was chosen to account for:

1. The additional disk I/O for retrieving larger contract code
2. The increased computational resources for preprocessing larger code for execution (a.k.a. "JUMPDEST analysis").
3. The growth in Merkle proof sizes for blocks containing larger contracts

This EIP introduces the gas cost as an additional cost for contracts exceeding 24KB. It could have been specified as a simpler `ceil32(contract_size) * GAS_PER_CODE_WORD // 32`, without hardcoding the existing contract size limit. However, for the sake of being conservative and avoiding lowering the cost of loading existing contracts (which could be small, under the 24KB limit), the 24KB floor was added to the formula.

The `EXTCODECOPY` opcode could theoretically be exempt from this, since clients could just load the parts of the bytecode which are actually requested. However, this might require a change at the protocol level, since the full code is required for the block witness. For this reason, `EXTCODECOPY` is included in the pricing scheme, and a carveout could be considered at a later date.

The new limit has been set at 64KB. The limit has been put in place so that increasing the gas limit won't have unexpected side effects at the db or p2p layer. For instance, in devp2p, the maximum packet size is 10MB (<https://github.com/ethereum/devp2p/blob/5713591d0366da78a913a811c7502d9ca91d29a8/caps/eth.md#basic-operation>). As of time of this writing, the maximum packet size in snap sync is even lower, at 96KB.

The limit for initcode has also been increased to 128KB, following the pattern set in EIP-3860 that the initcode limit is double the runtime code limit. While initcode is different from deployed code in that it does not live in the state and therefore isn't visible in devp2p or in the db, fully removing the limit could have unforeseen consequences.

## Backwards Compatibility

This EIP introduces additional gas costs for certain operations. Specifically, `CALL`, `STATICCALL`, `DELEGATECALL`, `CALLCODE`, `EXTCODESIZE`, and `EXTCODECOPY` may now require extra gas when accessing cold contract code.

## Test Cases

## Reference Implementation

## Security Considerations

## Copyright

Copyright and related rights waived via [CC0](../LICENSE.md).
