> For the complete documentation index, see [llms.txt](https://docs.espressosys.com/network/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.espressosys.com/network/developer/operators/run-a-node/node-configuration.md).

# Node Configuration Reference

Reference for espresso-node modules, environment variables, CLI flags, and the genesis file format.

This page lists the `espresso-node` options that [Run a Validator Node](/network/developer/operators/run-a-node.md) refers to. For the recommended configuration, image tag, and network values, start from that page.

Every option can be set as an environment variable or a CLI flag. Environment variables named `ESPRESSO_SEQUENCER_*` are still accepted with a deprecation warning; use the `ESPRESSO_NODE_*` names.

Durations take one integer and one unit, for example `500ms`, `7s`, `1m`, `14d`.

## Command syntax

```bash
espresso-node [options] -- <module> [module options] -- <module> [module options]
```

A module that depends on another must come after it on the command line, for example `-- http -- query`.

With the Docker image, `ESPRESSO_NODE_EMBEDDED_DB=true` makes the entrypoint prepend `-- storage-sql` with SQLite. Do not pass a storage module again in that mode. See [Command](/network/developer/operators/run-a-node.md#command).

## Modules

| Module         | Requires                 | Purpose                                                                                                                                                                                       |
| -------------- | ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `http`         |                          | HTTP server with healthcheck and version endpoints. The other API modules attach to it.                                                                                                       |
| `status`       | `http`                   | Prometheus metrics at `/status/metrics` and consensus status endpoints. See the [Status API](/network/developer/espresso-api/status-api.md).                                                  |
| `catchup`      | `http`                   | Serves consensus state to peers that fell behind. Included in `query`.                                                                                                                        |
| `config`       | `http`                   | Serves `/config/hotshot` (HotShot config without private keys), `/config/env` (public Espresso environment variables), and `/config/runtime` (effective configuration with secrets redacted). |
| `query`        | `http`, a storage module | Query service backed by the historical database: availability, node, and state APIs.                                                                                                          |
| `light-client` | `http`, `storage-sql`    | Leaves, headers, and stake tables with proofs that a client verifies against the light client contract on Ethereum.                                                                           |
| `explorer`     | `http`, `storage-sql`    | Block explorer API.                                                                                                                                                                           |
| `submit`       | `http`                   | `POST` endpoint for submitting transactions.                                                                                                                                                  |
| `storage-sql`  |                          | Postgres or SQLite storage for consensus state and the query database. Recommended.                                                                                                           |
| `storage-fs`   |                          | Filesystem storage. Used when no storage module is given. No pruning, no state catchup.                                                                                                       |

`hotshot-events` is retired. It is still accepted on the command line and serves nothing.

### `http` options

| Environment variable                | CLI flag            | Default   | Description                                                             |
| ----------------------------------- | ------------------- | --------- | ----------------------------------------------------------------------- |
| `ESPRESSO_NODE_API_PORT`            | `--port`            | `8080`    | Port for the HTTP API, metrics, and healthcheck.                        |
| `ESPRESSO_NODE_API_MAX_CONNECTIONS` | `--max-connections` | unlimited | Maximum concurrent HTTP connections. Further connections receive `429`. |

{% hint style="info" %}
The node serves plain HTTP. For production, place a reverse proxy (for example [Caddy](https://caddyserver.com/), nginx, or a cloud load balancer) in front of the node to terminate HTTPS.
{% endhint %}

### `query` options

| Environment variable      | CLI flag  | Default | Description                                                         |
| ------------------------- | --------- | ------- | ------------------------------------------------------------------- |
| `ESPRESSO_NODE_API_PEERS` | `--peers` | none    | Comma-separated peer query service URLs to fetch missing data from. |

### `storage-sql` options

Connection to Postgres, used when `ESPRESSO_NODE_EMBEDDED_DB=false`:

| Environment variable              | CLI flag     | Description               |
| --------------------------------- | ------------ | ------------------------- |
| `ESPRESSO_NODE_POSTGRES_HOST`     | `--host`     | Postgres server hostname. |
| `ESPRESSO_NODE_POSTGRES_PORT`     | `--port`     | Postgres server port.     |
| `ESPRESSO_NODE_POSTGRES_DATABASE` | `--database` | Database name.            |
| `ESPRESSO_NODE_POSTGRES_USER`     | `--user`     | Database user.            |
| `ESPRESSO_NODE_POSTGRES_PASSWORD` | `--password` | Database password.        |
| `ESPRESSO_NODE_POSTGRES_USE_TLS`  | `--use-tls`  | Connect over TLS.         |

With SQLite, `ESPRESSO_NODE_STORAGE_PATH` (`--path`) sets the data directory and the database is created at `<ESPRESSO_NODE_STORAGE_PATH>/sqlite/database`. `storage-fs` uses the same option.

Storage mode and connection pool:

| Environment variable                           | Default        | Description                                                                                                                                                                             |
| ---------------------------------------------- | -------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `ESPRESSO_NODE_DATABASE_PRUNE`                 | `false`        | Enable the pruner. Retention settings are in [Query database](/network/developer/operators/run-a-node.md#query-database).                                                               |
| `ESPRESSO_NODE_ARCHIVE`                        | `false`        | Retain all history and backfill pruned data from peers. Conflicts with `ESPRESSO_NODE_DATABASE_PRUNE`. See [Archival nodes](/network/developer/operators/run-a-node.md#archival-nodes). |
| `ESPRESSO_NODE_LIGHTWEIGHT`                    | `false`        | Store leaves only. Conflicts with `ESPRESSO_NODE_ARCHIVE`.                                                                                                                              |
| `ESPRESSO_NODE_DATABASE_MAX_CONNECTIONS`       | `25`           | Maximum connections in the node's pool.                                                                                                                                                 |
| `ESPRESSO_NODE_DATABASE_QUERY_MAX_CONNECTIONS` | node pool size | Maximum connections in the separate query pool. Postgres only.                                                                                                                          |
| `ESPRESSO_NODE_DATABASE_STATEMENT_TIMEOUT`     | `10m`          | Abort statements running longer than this.                                                                                                                                              |

Fetching missing data from peers:

| Environment variable               | Description                                                                                               |
| ---------------------------------- | --------------------------------------------------------------------------------------------------------- |
| `ESPRESSO_NODE_FETCH_RATE_LIMIT`   | Maximum simultaneous requests to peers when fetching missing data, for example `25`.                      |
| `ESPRESSO_NODE_ACTIVE_FETCH_DELAY` | Minimum delay between fetch requests to a peer, to stay within its rate limit, for example `50ms`.        |
| `ESPRESSO_NODE_CHUNK_FETCH_DELAY`  | Minimum delay between loading chunks from the local database in a sequential stream, for example `100ms`. |

## Node options

| Environment variable                   | CLI flag                   | Default        | Description                                                                                                                                    |
| -------------------------------------- | -------------------------- | -------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- |
| `ESPRESSO_NODE_GENESIS_FILE`           | `--genesis-file`           |                | Path or `http(s)://` URL of the [genesis file](#genesis-file).                                                                                 |
| `ESPRESSO_NODE_KEY_FILE`               | `--key-file`               |                | Path to the key file. See [Generate keys](/network/developer/operators/run-a-node.md#generate-keys).                                           |
| `ESPRESSO_NODE_STATE_PEERS`            | `--state-peers`            |                | Comma-separated peer URLs used to fetch missing consensus state.                                                                               |
| `ESPRESSO_NODE_CONFIG_PEERS`           | `--config-peers`           |                | Peers to fetch the network config from when none is stored locally. See [First start](/network/developer/operators/run-a-node.md#first-start). |
| `ESPRESSO_STATE_RELAY_SERVER_URL`      | `--state-relay-server-url` |                | URL of the state relay server, provided by Espresso.                                                                                           |
| `ESPRESSO_NODE_CLIQUENET_BIND_ADDRESS` | `--cliquenet-bind-address` | `0.0.0.0:9977` | `host:port` that cliquenet binds for the validator mesh. TCP, reachable from the public internet.                                              |

### Keys

Instead of a key file, keys can be given directly or derived from a mnemonic. A key file cannot be combined with these options.

| Environment variable                | CLI flag                | Description                                                                                |
| ----------------------------------- | ----------------------- | ------------------------------------------------------------------------------------------ |
| `ESPRESSO_NODE_PRIVATE_STAKING_KEY` | `--private-staking-key` | BLS staking key, `BLS_SIGNING_KEY~...`. Signs consensus messages.                          |
| `ESPRESSO_NODE_PRIVATE_STATE_KEY`   | `--private-state-key`   | Schnorr state key, `SCHNORR_SIGNING_KEY~...`. Signs finalized states for the light client. |
| `ESPRESSO_NODE_PRIVATE_X25519_KEY`  | `--private-x25519-key`  | x25519 key, `X25519_SK~...`. Authenticates the node on cliquenet.                          |
| `ESPRESSO_NODE_KEY_MNEMONIC`        | `--mnemonic`            | Mnemonic to derive keys from. Explicit keys take precedence over derived ones.             |
| `ESPRESSO_NODE_KEY_INDEX`           | `--index`               | Derivation index for `--mnemonic`.                                                         |

The staking and state keys are required. Without an x25519 key the node generates a random one on each start, which does not match the key registered in the stake table, so peers reject its connections. Always set a persistent x25519 key.

### L1 client

| Environment variable                           | CLI flag                             | Default     | Description                                                                                                                                                                                                                    |
| ---------------------------------------------- | ------------------------------------ | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `ESPRESSO_L1_PROVIDER`                         | `--l1-provider-url`                  |             | Comma-separated HTTP JSON-RPC endpoints. Further entries are failover providers.                                                                                                                                               |
| `ESPRESSO_L1_WS_PROVIDER`                      | `--l1-ws-provider`                   |             | Comma-separated `ws://` or `wss://` endpoints. Used to stream blocks instead of polling.                                                                                                                                       |
| `ESPRESSO_L1_POLLING_INTERVAL`                 | `--l1-polling-interval`              | `7s`        | Interval for polling-based streams.                                                                                                                                                                                            |
| `ESPRESSO_L1_RETRY_DELAY`                      | `--l1-retry-delay`                   | `1s`        | Delay after a failed request.                                                                                                                                                                                                  |
| `ESPRESSO_L1_RATE_LIMIT_DELAY`                 | `--l1-rate-limit-delay`              | retry delay | Delay after a `429` response.                                                                                                                                                                                                  |
| `ESPRESSO_L1_EVENTS_MAX_BLOCK_RANGE`           | `--l1-events-max-block-range`        | `10000`     | Maximum blocks in one `eth_getLogs` call. Lower it if the provider rejects large ranges.                                                                                                                                       |
| `ESPRESSO_L1_EVENTS_MAX_RETRY_DURATION`        | `--l1-events-max-retry-duration`     | `20m`       | The node exits after retrying an L1 event fetch for this long.                                                                                                                                                                 |
| `ESPRESSO_L1_SUBSCRIPTION_TIMEOUT`             | `--subscription-timeout`             | `1m`        | Reset the block stream after this long without a new block.                                                                                                                                                                    |
| `ESPRESSO_L1_FREQUENT_FAILURE_TOLERANCE`       | `--l1-frequent-failure-tolerance`    | `1m`        | Two failures within this interval trigger failover to the next provider.                                                                                                                                                       |
| `ESPRESSO_L1_CONSECUTIVE_FAILURE_TOLERANCE`    | `--l1-consecutive-failure-tolerance` | `10`        | This many consecutive failures trigger failover.                                                                                                                                                                               |
| `ESPRESSO_L1_FAILOVER_REVERT`                  | `--l1-failover-revert`               | `30m`       | Return to the first provider this long after a failover.                                                                                                                                                                       |
| `ESPRESSO_L1_BLOCKS_CACHE_SIZE`                | `--l1-blocks-cache-size`             | `100`       | Finalized L1 blocks cached in memory.                                                                                                                                                                                          |
| `ESPRESSO_L1_EVENTS_CHANNEL_CAPACITY`          | `--l1-events-channel-capacity`       | `100`       | New block events buffered before events are dropped.                                                                                                                                                                           |
| `ESPRESSO_L1_FINALIZED_SAFETY_MARGIN`          | `--l1-finalized-safety-margin`       | none        | Depth below a known finalized block at which all providers are assumed finalized. Older blocks are fetched by number; newer ones by hash chain from a known finalized block. Without it, every block is fetched by hash chain. |
| `ESPRESSO_NODE_L1_STAKE_TABLE_UPDATE_INTERVAL` | `--stake-table-update-interval`      | `60m`       | Interval for syncing stake table events from L1.                                                                                                                                                                               |

### Telemetry

See [Telemetry and identity](/network/developer/operators/run-a-node.md#telemetry-and-identity).

| Environment variable                       | Default | Description                                    |
| ------------------------------------------ | ------- | ---------------------------------------------- |
| `ESPRESSO_NODE_TELEMETRY_LOGS_ENABLE`      | `false` | Ship logs to Espresso.                         |
| `ESPRESSO_NODE_TELEMETRY_METRICS_ENABLE`   | `false` | Ship metrics to Espresso.                      |
| `ESPRESSO_NODE_TELEMETRY_LOG`              | `warn`  | Filter for shipped logs, in `RUST_LOG` syntax. |
| `ESPRESSO_NODE_TELEMETRY_METRICS_INTERVAL` | `60`    | Seconds between metrics pushes.                |

### Identity

Identity values are published in the `node_identity_*` metrics on `/status/metrics`. `NODE_NAME` and `COMPANY_NAME` also label the node's [telemetry](/network/developer/operators/run-a-node.md#telemetry-and-identity).

| Environment variable                                                              | CLI flag              | Description                                                                                                                               |
| --------------------------------------------------------------------------------- | --------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
| `ESPRESSO_NODE_IDENTITY_NODE_NAME`                                                | `--node-name`         | Display name of the node, for example `acme-mainnet-01`.                                                                                  |
| `ESPRESSO_NODE_IDENTITY_NODE_DESCRIPTION`                                         | `--node-description`  | Free-text description of the node.                                                                                                        |
| `ESPRESSO_NODE_IDENTITY_COMPANY_NAME`                                             | `--company-name`      | Operator organization, for example `Acme Staking`.                                                                                        |
| `ESPRESSO_NODE_IDENTITY_COMPANY_WEBSITE`                                          | `--company-website`   | Operator homepage URL.                                                                                                                    |
| `ESPRESSO_NODE_IDENTITY_NETWORK_TYPE`                                             | `--network-type`      | Hosting type: `Residential`, `Hosted`, `AWS`, `GCP`, `Azure`, or `Cloud Provider`, optionally with a region, for example `AWS us-west-2`. |
| `ESPRESSO_NODE_IDENTITY_COUNTRY_CODE`                                             | `--country-code`      | [ISO 3166-1 alpha-2](https://www.iso.org/iso-3166-country-codes.html) country code, for example `DE`.                                     |
| `ESPRESSO_NODE_IDENTITY_LATITUDE`                                                 | `--latitude`          | Approximate latitude as a decimal, for example `40.4173`. Set together with longitude.                                                    |
| `ESPRESSO_NODE_IDENTITY_LONGITUDE`                                                | `--longitude`         | Approximate longitude as a decimal, for example `-82.9071`. Set together with latitude.                                                   |
| `ESPRESSO_NODE_IDENTITY_OPERATING_SYSTEM`                                         | `--operating-system`  | Defaults to the OS name, for example `linux`. `uname -sr` gives a more specific value.                                                    |
| `ESPRESSO_NODE_IDENTITY_NODE_TYPE`                                                | `--node-type`         | Defaults to `espresso-sequencer <version>`.                                                                                               |
| `ESPRESSO_NODE_IDENTITY_ICON_14x14_1x` ... `ESPRESSO_NODE_IDENTITY_ICON_24x24_3x` | `--icon-14x14-1x` ... | Icon URLs at 14x14 and 24x24 pixels, for 1x, 2x, and 3x displays.                                                                         |

## Genesis file

The genesis file holds settings that must be identical on all nodes: protocol versions, the genesis state, and the parameters that decide block validity. Genesis files for the supported networks ([source](https://github.com/EspressoSystems/espresso-network/tree/main/data/genesis)) are bundled in the image under `/genesis`. Set `ESPRESSO_NODE_GENESIS_FILE=/genesis/mainnet.toml` or `/genesis/decaf.toml`; operators of these networks never edit a genesis file.

A custom network uses its own genesis file, mounted into the container or served over HTTP(S).

### Format

The file is TOML. Abridged from `mainnet.toml`:

```toml
base_version = "0.6"
upgrade_version = "0.6"
genesis_version = "0.2"
epoch_height = 40000
epoch_start_block = 10960201
drb_difficulty = 25000000000
drb_upgrade_difficulty = 25000000000

[stake_table]
capacity = 200

[chain_config]
chain_id = 1
base_fee = "1 wei"
max_block_size = "10mb"
fee_recipient = "0x0000000000000000000000000000000000000000"
fee_contract = "0x..."
stake_table_contract = "0x..."

[header]
timestamp = "1970-01-01T00:00:00Z"

[header.chain_config]
# chain config of the genesis header, same fields as [chain_config]

[l1_finalized]
number = 21116303
```

**Top-level keys**

* `genesis_version`: protocol version of the genesis block. Must not exceed `base_version`.
* `base_version`, `upgrade_version`: protocol version the node starts on, and the version it upgrades to through an [`[[upgrade]]`](#upgrade) entry. Equal when no upgrade is scheduled.
* `epoch_height`, `epoch_start_block`: blocks per epoch and the first epoch block. Required from version `0.3`.
* `drb_difficulty`, `drb_upgrade_difficulty`: difficulty of the distributed randomness beacon. Required from version `0.4`.

**`[stake_table]`**

* `capacity`: maximum number of validators the light client stake table commitment represents. Expanding it after genesis requires a network upgrade. The validator set itself comes from the stake table contract on Ethereum.

**`[chain_config]`**: parameters that decide block validity. Hashed into every block header, so a client can check that a block belongs to the expected chain.

* `chain_id`: identifier of this Espresso network. Protocol transactions reference it to prevent replay across networks.
* `max_block_size`: blocks with a larger payload are rejected. Bytes as an integer, or a number with a unit such as `kb`, `KiB`, `mb`.
* `base_fee`: fee per byte of data, in wei, or a number with unit `wei`, `gwei`, or `eth`.
* `fee_recipient`: address that receives fees.
* `fee_contract` (optional): L1 contract for depositing ETH into the Espresso fee state. Omitted means deposits are disabled. Required in the `chain_config` of every `[[upgrade]]` entry, and never the zero address.
* `stake_table_contract` (optional): address of the stake table contract on Ethereum.

**`[header]`**

* `timestamp`: timestamp of the genesis header, as an [RFC 3339](https://datatracker.ietf.org/doc/html/rfc3339) string or Unix seconds. Later blocks take the proposer's time.
* `[header.chain_config]`: chain config of the genesis header. Required.

**`[l1_finalized]`**: the finalized Ethereum block from which the node processes L1 events. One of:

* `number`, `timestamp`, and `hash`: the node accepts only this exact block.
* `number` only: the node fetches the block once it is finalized.
* `timestamp` only: the node starts from the first L1 block at or after this time.

The first Espresso block processes all L1 events from this block up to the current finalized block, so choose a block recent enough for those events to be processed within one view timeout. If the block is not finalized yet, the node waits before starting consensus.

### Upgrade

An `[[upgrade]]` entry schedules a protocol upgrade from `base_version` to `upgrade_version`. Only the entry whose `version` equals `upgrade_version` applies.

```toml
[[upgrade]]
version = "0.6"
start_proposing_time = "2026-01-01T16:00:00Z"
stop_proposing_time = "2026-01-02T16:00:00Z"

[upgrade.new_protocol]
[upgrade.new_protocol.chain_config]
# chain config after the upgrade, same fields as [chain_config]; fee_contract is required
```

* The window is either view-based (`start_proposing_view`, `stop_proposing_view`) or time-based (`start_proposing_time`, `stop_proposing_time`). Exactly one form is allowed. Optional `start_voting_*` and `stop_voting_*` bound the voting window the same way.
* Leaders propose the upgrade inside the window. Leave enough time for it to succeed, for example 300 views or 5 to 10 minutes.
* Upgrade types: `fee`, `epoch`, `drb_and_header`, `epoch_reward`, `new_protocol`. Each takes a `chain_config` table with the post-upgrade chain config.

More detail: [upgrades.md](https://github.com/EspressoSystems/espresso-network/blob/main/doc/upgrades.md).
