> For the complete documentation index, see [llms.txt](https://docs.arcology.network/arcology-concurrent-programming-guide/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.arcology.network/arcology-concurrent-programming-guide/utility/deferred-execution.md).

# Deferred Execution

Consider the following example contracts. They demonstrate another key feature called [**deferred execution**](https://doc.arcology.network/parallel-execution-design/scheduler#deferred-transaction)**,** where the [**scheduler** ](https://doc.arcology.network/parallel-execution-design/scheduler)moves transactions to the next [**generation** ](https://doc.arcology.network/parallel-execution-design/scheduler#generation)to create a custom aggregation point after parallel execution.

#### Example1

`VisitCounterWithDeferred` uses `U256Cumulative` for parallel-safe increments and adds a **deferred join** step: all `visit()` calls in a generation run in parallel, with **one promoted to** **the next generation** to emit the aggregated result after the generation boundary.

```solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.0;

import "@arcologynetwork/concurrentlib/lib/commutative/U256Cum.sol"; 
import "@arcologynetwork/concurrentlib/lib/runtime/Runtime.sol"; 

// This counter supports commutative updates, allowing safe aggregation
// of increments from multiple transactions in parallel.
contract VisitCounterWithDeferred { 
    // A cumulative counter instance that allows concurrent increments
    // from multiple transactions without conflicts.   
    U256Cumulative totalVisit; 
    
    event CounterQuery(uint256 value);

    constructor()  {
        // Initialize the cumulative counter with a starting value of 0
        // and an upper limit of 1,000,000. Any attempt to exceed the
        // range will cause the transaction to revert.
        totalVisit = new U256Cumulative(0, 1000000);

        // Inform the scheduler when there are multiple transaction 
        // calling visit(), one of them will be executed in the
        // deferred transaction. Each call to visit() is charged an 
        // extra 2,000 gas to fund the deferred join step run later
        // in the block. If the deferred transaction fails, 
        // the unused gas is refunded.
        Runtime.defer("visit()", 2000);
    }

    // Increments the visit counter by 1.
    // Multiple invocations in the same generation can be executed in parallel
    // and will be merged deterministically by Arcology at commit time.
    function visit() public {
        // The line below adds 1 to the visit counter, which will executed anyway.
        totalVisit.add(1);

        // If the transaction is in a deferred generation, emit the counter value.
        // The code is executed in the deferred transaction only.
        if (Runtime.isInDeferred()) {
            emit CounterQuery(totalVisit.get());
        }
    }
}
```

#### Example 2

```solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;

import "@arcologynetwork/concurrentlib/lib/array/Address.sol"; 
import "@arcologynetwork/concurrentlib/lib/runtime/Runtime.sol"; 

// SUPER SIMPLE educational lottery — not secure for real funds.
// join(): send ≥0.005 ETH to join the round.
contract EduLottery {
    Address private _players = new Address(false);

    error InsufficientFee(uint256 sent, uint256 required);
    error NoPlayers();

    constructor() {
        // Inform the scheduler that when there are multiple invocations, move one of 
        // them to the next generation for aggregation. All the senders need to pay
        // extra gas fees of 20,000 wei for the deferred execution.
        Runtime.defer("join()", 20000);
    }

    // Joins the lottery by sending ETH. This function can be called in parallel 
    // by multiple users.
    function join() external payable {
        if (msg.value < 0.005 ether) revert InsufficientFee(msg.value, 0.005 ether);
        _players.push(msg.sender);

        // Only draw if this is the deferred transaction
        if (Runtime.isInDeferred()) {
            _draw();
        }
    }

    // Generates a pseudo-random seed.
    function _randomSeed() private view returns (uint256) {
        // Educational pseudo-randomness (prev blockhash, timestamp, contract)
        return uint256(
            keccak256(
                abi.encodePacked(
                    blockhash(block.number - 1),
                    block.timestamp,
                    address(this)
                )
            )
        );
    }

    // Draws a random winner from the players.
    function _draw() internal {
        require(Runtime.isInDeferred(), "only deferred");

        if (_players.fullLength() == 0) revert NoPlayers();
        uint256 idx = _randomSeed() % _players.fullLength();
        address winner = _players.get(idx);

        _players.clear(); // Clear players for the next round
        uint256 prize = address(this).balance;
        (bool ok, ) = payable(winner).call{value: prize}("");
        require(ok, "transfer failed");
    }
}
```
