> ## Documentation Index
> Fetch the complete documentation index at: https://seilabs-docs-evm-cookbook.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Optimizing Contracts for Parallelization

> Design patterns to reduce state conflicts and maximize Sei EVM parallel execution while lowering gas usage.

Sei EVM executes non-conflicting transactions in parallel. If you design contracts that minimize shared state access and avoid unnecessary storage writes, you can increase throughput significantly and reduce gas.

<Info>
  This guide is based on Sei's recommendations to reduce gas usage and improve parallel execution. For the engine design, see the [parallelization engine](/learn/parallelization-engine) page.
</Info>

## Principles for parallel-friendly contracts

* **Minimize shared writes**: The scheduler can parallelize transactions that do not write to the same storage keys. Avoid hot globals (for example, a single counter that every call updates).
* **Partition state**: Shard storage by user, asset, or ID so that independent transactions touch disjoint keys.
* **Prefer pull over push**: Let users claim funds instead of paying many recipients in a loop.
* **Avoid unbounded loops**: This applies especially to loops that write to storage or iterate over dynamic arrays or mappings.
* **Batch internal work and isolate external effects**: Do heavy computation in memory and commit a minimal set of storage writes.
* **Use precompiles when available**: Precompiles are highly optimized and cost less than the same logic written in Solidity.

<Tip>
  **Parallelization checklist:**

  * Partition storage by user, asset, or ID, and avoid hot globals
  * Minimize the number of storage writes per call: batch work in memory and commit once
  * Avoid loops with storage writes, and switch to pull-based flows
  * Favor precompiles for supported features
  * Apply standard gas optimizations (`external`, packing, `unchecked`, memory-first)
</Tip>

## Storage design patterns

### Partition state by key

Isolate per-user and per-asset data instead of centralizing writes.

```solidity theme={null}
// Good: disjoint keys by user and id enable parallelism
mapping(address => mapping(uint256 => Position)) public positions;

function updatePosition(uint256 id, int256 delta) external {
    Position storage p = positions[msg.sender][id];
    // in-memory arithmetic first
    int256 newQty = p.qty + delta;
    // commit minimal writes
    p.qty = newQty;
}
```

Anti-patterns:

* Writing a global `totalVolume += amount;` in every transaction
* Maintaining a single on-chain queue or registry that most calls update

Prefer to compute aggregates off-chain from events. Alternatively, update them periodically through a dedicated maintenance transaction and place them in the calldata.

### Prefer pull payments

Avoid writing to many recipients in a single transaction. Emit events, and let recipients call `withdraw()` when they need to.

```solidity theme={null}
// Better: users pull their own rewards, isolating writes to their key
mapping(address => uint256) public accrued;

function accrue(address user, uint256 amount) internal {
    accrued[user] += amount; // isolated write
}

function withdraw() external {
    uint256 due = accrued[msg.sender];
    accrued[msg.sender] = 0; // single-key write
    (bool ok, ) = msg.sender.call{value: due}("");
    require(ok, "TRANSFER_FAILED");
}
```

### Avoid large storage writes in loops

If you must process many items, keep the work in memory and commit a compact result. Alternatively, split the work across multiple transactions keyed by different IDs.

## Gas-efficient Solidity practices

* **Use `external` for externally called functions**. Mark pure and read-only functions with `pure` and `view`.
* **Pack variables** to share storage slots (for example, multiple `uint8` values in one slot).
* Prefer **`bytes32` over `string`** when applicable.
* **Cache array lengths** in loops and short-circuit cheap conditions first.
* Use **`unchecked`** for arithmetic when overflow is impossible.
* Prefer **memory** over storage for temporary data, and commit only final values.

These practices reduce gas and often reduce storage access, which also improves parallelism.

## Leverage Sei precompiles

Sei has precompiled contracts for common functionality. They are cheaper and simpler than custom Solidity equivalents:

* [JSON](/evm/precompiles/json) (`0x1003`)
* [P256](/evm/precompiles/p256-precompile) (`0x1011`)

See [precompile examples](/evm/precompiles/example-usage) for quick starts.

## Testing and analysis

* Use Foundry or Hardhat gas reporters to track changes per function.
* Benchmark under concurrent load to detect hot keys (addresses or IDs) that serialize execution.
* Inspect execution with [JavaScript tracers](/evm/tracing/javascript-tracers) and runtime logs.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.