> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/ethereum/go-ethereum/llms.txt
> Use this file to discover all available pages before exploring further.

# Private networks

> Options for running Geth in a private or local test environment, from dev mode to full multi-client testnets.

Since [the Merge](https://ethereum.org/en/roadmap/merge/), Ethereum execution clients require a consensus layer (beacon node) alongside them. This adds complexity when standing up a private network from scratch. Geth provides three solutions depending on how much realism your use case requires.

<CardGroup cols={3}>
  <Card title="Simulated backend" icon="flask">
    In-process, in-memory simulation for Go unit tests and CI pipelines.
  </Card>

  <Card title="Dev mode" icon="laptop-code">
    Single-node, no-networking environment with instant block production. Ideal for local contract development.
  </Card>

  <Card title="Kurtosis" icon="network-wired">
    Full multi-client testnet with real consensus and execution clients. Best for integration testing.
  </Card>
</CardGroup>

***

## Option 1: Simulated backend

If you are writing Go code and need an Ethereum environment for tests or CI, the simulated backend is the simplest option. It runs entirely in memory inside the same process as your tests — no separate process, no ports, no disk.

See the [Native Bindings documentation](https://geth.ethereum.org/docs/developers/dapp-developer/native-bindings#blockchain-simulator) for usage details.

***

## Option 2: Dev mode

Dev mode starts a single Geth node that simulates a fully functional Ethereum environment without any networking or external consensus layer. It is intended for fast, iterative development.

```bash theme={null}
geth --dev
```

### What dev mode does

* **Pre-funded account:** A random developer account is created, pre-funded with a large balance (`10^49 ETH`), and automatically unlocked. The private key is printed to the log at startup so you can import it into tools like MetaMask or cast.
* **Instant block sealing:** Geth only produces a block when there is at least one pending transaction in the mempool. If `--dev.period` is set to a non-zero value, blocks are produced on a fixed interval even when empty.
* **No networking:** Peer discovery is disabled, the maximum peer count is `0`, and there is no listen address. The node cannot connect to or be reached by any other node.
* **In-memory database:** Unless `--datadir` is specified, the chain is stored entirely in memory and is lost when the process exits.

<Warning>
  Dev mode is not suitable for production or for testing security properties. The pre-funded account is temporary and stored in a ramdisk — it will be lost if the machine restarts and `--datadir` is not set.
</Warning>

### Dev mode flags

| Flag             | Default    | Description                                                             |
| ---------------- | ---------- | ----------------------------------------------------------------------- |
| `--dev`          | *(flag)*   | Enable dev mode                                                         |
| `--dev.period`   | `0`        | Block period in seconds (`0` = mine only when transactions are pending) |
| `--dev.gaslimit` | `11500000` | Initial block gas limit                                                 |

### Example: attach a console

```bash theme={null}
# Terminal 1 — start dev node
geth --dev --http --http.api eth,web3,personal

# Terminal 2 — attach interactive console
geth attach http://127.0.0.1:8545
```

***

## Option 3: Custom genesis with `geth init`

For a more realistic private network — for example, one shared among a small team — you can define a custom genesis block and initialise Geth from it.

<Steps>
  <Step title="Create a genesis.json file">
    Define the chain parameters, initial balances, and any network upgrades:

    ```json theme={null}
    {
      "config": {
        "chainId": 12345,
        "homesteadBlock": 0,
        "eip150Block": 0,
        "eip155Block": 0,
        "eip158Block": 0,
        "byzantiumBlock": 0,
        "constantinopleBlock": 0,
        "petersburgBlock": 0,
        "istanbulBlock": 0,
        "berlinBlock": 0,
        "londonBlock": 0,
        "clique": {
          "period": 5,
          "epoch": 30000
        }
      },
      "difficulty": "1",
      "gasLimit": "8000000",
      "extradata": "0x0000000000000000000000000000000000000000000000000000000000000000YOUR_SIGNER_ADDRESS_HERE0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
      "alloc": {
        "YOUR_ADDRESS_HERE": {
          "balance": "1000000000000000000000"
        }
      }
    }
    ```

    Choose a unique `chainId` that does not conflict with any public network.
  </Step>

  <Step title="Initialise the data directory">
    ```bash theme={null}
    geth init --datadir /var/lib/myprivatechain genesis.json
    ```

    This writes the genesis block to the database. Run this on every node that will join the network.
  </Step>

  <Step title="Start Geth">
    ```bash theme={null}
    geth \
      --datadir /var/lib/myprivatechain \
      --networkid 12345 \
      --port 30303
    ```

    Connect additional nodes using `--bootnodes` with the enode URL of the first node.
  </Step>
</Steps>

<Note>
  Post-Merge private networks require a consensus layer running alongside each execution node. For a purely Clique-based (proof-of-authority) private network predating the Merge configuration, this may still work for test scenarios, but a full post-Merge setup requires pairing each Geth instance with a beacon node. Use Kurtosis (below) for that.
</Note>

***

## Option 4: Kurtosis (multi-client testnet)

[Kurtosis](https://geth.ethereum.org/docs/fundamentals/kurtosis) is the recommended approach when you need a realistic multi-node test network that includes both execution and consensus clients.

Kurtosis automates the orchestration of multiple Geth (and other client) instances alongside beacon nodes, giving you:

* Multiple execution + consensus client pairs
* Realistic peer-to-peer networking between nodes
* Configurable genesis and fork parameters
* Support for mixed-client environments (Geth + Lighthouse, Geth + Prysm, etc.)

This is the best option for integration testing, client interoperability work, and simulating mainnet-like conditions.

```bash theme={null}
# Install Kurtosis CLI, then:
kurtosis run github.com/ethpandaops/ethereum-package
```

Refer to the [Kurtosis documentation](https://geth.ethereum.org/docs/fundamentals/kurtosis) for the full setup guide.
