> For the complete documentation index, see [llms.txt](/llms.txt)

# Running a Sequencer

## Overview

This guide covers sequencer lifecycle management on the Aztec network: keystore configuration, node setup, registration, ongoing operations, and eventual exit.

Minimum Stake Requirement

To participate as a sequencer on the Aztec network, you must stake a minimum of **200,000 AZTEC tokens**. Ensure you have sufficient tokens before proceeding with sequencer setup and registration.

Sequencer nodes are critical infrastructure responsible for ordering transactions and producing blocks. They perform three key actions:

1. Assemble unprocessed transactions and propose the next block
2. Attest to correct execution of transactions in proposed blocks (when part of the sequencer committee)
3. Submit successfully attested blocks to L1

Before publication, blocks must be validated by a committee of sequencer nodes who re-execute public transactions and verify private function proofs. Committee members attest to validity by signing the block header.

Once sufficient attestations are collected (two-thirds of the committee plus one), the block can be submitted to L1.

### Minimum Hardware Requirements

| Resource | Spec                                    |
| -------- | --------------------------------------- |
| CPU      | 8 cores / 16 vCPU, **Skylake or newer** |
| RAM      | 8 GB                                    |
| Storage  | 1 TB SSD (NVMe recommended)             |
| Network  | 25 Mbps                                 |

These requirements are subject to change as the network throughput increases.

**Before proceeding:** Ensure you've reviewed and completed the [prerequisites](/operate/operators/prerequisites.md).

## Keystore Explanation

Sequencers require private keys to identify themselves as valid proposers and attesters. These keys are configured through a private keystore file.

### Private Keystore Structure

The private keystore file (`keystore.json`) uses the following structure:

```json
{
  "schemaVersion": 1,
  "validators": [
    {
      "attester": {
        "eth": "ETH_PRIVATE_KEY",
        "bls": "BLS_PRIVATE_KEY"
      },
      "publisher": ["PUBLISHER_PRIVATE_KEY"],  // Optional: defaults to attester key
      "feeRecipient": "0x0000000000000000000000000000000000000000000000000000000000000000",  // Not currently used, set to all zeros
      "coinbase": "ETH_ADDRESS"
    }
  ]
}
```

info

The attester field contains both Ethereum and BLS keys:

* **ETH key**: Derives the address that serves as your sequencer's unique identifier in the protocol
* **BLS key**: Used to sign proposals and attestations, as well as for staking operations

### Field Descriptions

#### attester (required)

**Your sequencer's identity.** Contains both Ethereum and BLS keys:

* **Format**: Object with `eth` and `bls` fields
* **eth**: Ethereum private key - the derived address serves as your sequencer's unique identifier in the protocol
* **bls**: BLS private key - actually signs proposals and attestations, and is used for staking operations (validator registration and proof of possession)
* **Purpose**: The ETH address identifies your sequencer, while the BLS key performs the cryptographic signing of consensus messages

#### publisher (optional)

Separate private key(s) for submitting BLS-signed messages to L1. The publisher just pays gas to post already-signed proposals and attestations.

* **Format**: Array of Ethereum private keys
* **Default**: Uses attester key if not specified
* **Purpose**: Posts signed messages to L1 and pays for gas (doesn't participate in signing)
* **Funding**: around 0.01 ETH per attester served is a comfortable opening top-up at current L1 prices. Use the [funding calculator](/operate/operators/solo-sequencer/fund-accounts.md#fund-the-publisher) to scan the real network with your RPC and size against your own gas-price assumptions.

tip

If you're using the attester ETH key for publishing (no separate publisher keys), you can omit the `publisher` field entirely from your keystore, but you will still need to fund the attester account so it can pay L1 gas.

#### feeRecipient

Aztec address that would receive L2 transaction fees.

* **Format**: 32-byte Aztec address (64 hex characters)
* **Current status**: Not currently used by the protocol - set to `0x0000000000000000000000000000000000000000000000000000000000000000`
* **Purpose**: Reserved for future fee distribution mechanisms

#### coinbase (optional)

Ethereum address that receives all L1 block rewards and tx fees.

* **Format**: Ethereum address
* **Default**: Uses attester address if not specified

### Generating Keys

Use the Aztec CLI's keystore utility to generate both your private and public keystores:

```bash
aztec validator-keys new \
  --fee-recipient 0x0000000000000000000000000000000000000000000000000000000000000000 \
  --staker-output \
  --gse-address 0xa92ecFD0E70c9cd5E5cd76c50Af0F7Da93567a4f \
  --l1-rpc-urls $ETH_RPC
```

**Relevant parameters:**

* `--fee-recipient`: Set to all zeros (not currently used by the protocol)

* `--staker-output`: Generate the public keystore for the staking dashboard

* `--gse-address`: The GSE (Governance Staking Escrow) contract address: `0xa92ecFD0E70c9cd5E5cd76c50Af0F7Da93567a4f` on mainnet, `0xb6a38a51a6c1de9012f9d8ea9745ef957212eaac` on testnet. The commands on this page use the mainnet address.

* `--l1-rpc-urls`: Your L1 RPC endpoint (Ethereum mainnet, or Sepolia for testnet)
  <!-- -->
  * Set `ETH_RPC` environment variable, or replace `$ETH_RPC` with your L1 RPC URL (e.g., `https://mainnet.infura.io/v3/YOUR_API_KEY` on mainnet)

* `--count`: Number of validator identities to generate (default: 1)

  <!-- -->

  * Use this to generate multiple attester identities in a single keystore
  * Example: `--count 5` generates 5 validator identities with sequential addresses
  * All identities are derived from the same mnemonic using different derivation paths
  * Useful for operators running multiple sequencer identities or delegated staking providers

* `--publisher-count` Number of publisher accounts per validator (default 0)

**This command creates two JSON files:**

1. **Private keystore** (`~/.aztec/keystore/keyN.json`) - Contains your ETH and BLS private keys for running the node
2. **Public keystore** (`~/.aztec/keystore/keyN_staker_output.json`) - Contains only public information (public keys and proof of possession) for the staking dashboard

Where `N` is an auto-incrementing number (e.g., `key1.json`, `key2.json`, etc.)

**What gets generated:**

* Automatically generates a mnemonic for key derivation (or provide your own with `--mnemonic`)
* Creates an ETH key (for your sequencer identifier) and BLS key (for signing)
* Computes BLS public keys (G1 and G2) and proof of possession
* Outputs your attester address, publisher address and BLS public keys to the console

**Example output (single validator):**

```text
No mnemonic provided, generating new one...
Using new mnemonic:

word1 word2 word3 word4 word5 word6 word7 word8 word9 word10 word11 word12

Wrote validator keystore to /Users/aztec/.aztec/keystore/key1.json
Wrote staker output for 1 validator(s) to /Users/aztec/.aztec/keystore/key1_staker_output.json

acc1:
  attester:
    eth: 0xA55aB561877E479361BA033c4ff7B516006CF547
    bls: 0xa931139040533679ff3990bfc4f40b63f50807815d77346e3c02919d71891dc1
```

**Example output (multiple validators with `--count 3`):**

```text
No mnemonic provided, generating new one...
Using new mnemonic:

word1 word2 word3 word4 word5 word6 word7 word8 word9 word10 word11 word12

Wrote validator keystore to /Users/aztec/.aztec/keystore/key1.json
Wrote staker output for 3 validator(s) to /Users/aztec/.aztec/keystore/key1_staker_output.json

acc1:
  attester:
    eth: 0xA55aB561877E479361BA033c4ff7B516006CF547
    bls: 0xa931139040533679ff3990bfc4f40b63f50807815d77346e3c02919d71891dc1
acc2:
  attester:
    eth: 0xB66bC672988F590472CA144e5D8d9F82307DA658
    bls: 0xb842240151644780ff4991cfd5f51c74f61918926e88457f4d13020e82902ed2
acc3:
  attester:
    eth: 0xC77cD783999F601583DB255f6E9e0F93418EB769
    bls: 0xc953351262755891ff5aa2dfe6f62d85f72a29a37f99568f5e24131f93a13fe3
```

**Critical: Save your mnemonic phrase!**

* The mnemonic is the **only thing you must save** - it can regenerate all your keys, addresses, and keystores
* Store it securely offline (not on the server running the node)

**For convenience, note:**

* **Attester address** (eth): Your sequencer's identifier (e.g., `0xA55aB...F547`) - useful for registration and monitoring
* **File paths**: Where the keystores were saved

All other information (BLS keys, public keys, addresses) can be re-derived from the mnemonic if needed.

Provide Your Own Mnemonic

For deterministic key generation or to recreate keys later, provide your own mnemonic:

```bash
aztec validator-keys new \
  --fee-recipient 0x0000000000000000000000000000000000000000000000000000000000000000 \
  --staker-output \
  --gse-address 0xa92ecFD0E70c9cd5E5cd76c50Af0F7Da93567a4f \
  --l1-rpc-urls $ETH_RPC \
  --mnemonic "your twelve word mnemonic phrase here"
```

Generate Multiple Validator Identities

To generate multiple validator identities (useful for delegated staking providers or operators running multiple sequencers):

```bash
# Generate 5 validator identities from the same mnemonic
aztec validator-keys new \
  --fee-recipient 0x0000000000000000000000000000000000000000000000000000000000000000 \
  --staker-output \
  --gse-address 0xa92ecFD0E70c9cd5E5cd76c50Af0F7Da93567a4f \
  --l1-rpc-urls $ETH_RPC \
  --count 5
```

Each identity gets a unique attester address derived from sequential derivation paths. All identities are included in:

* The same private keystore file (`keyN.json`)
* The same public keystore file (`keyN_staker_output.json`)

For detailed instructions, advanced options, and complete examples, see the [Creating Sequencer Keystores guide](/operate/operators/keystore/creating_keystores.md).

## Setup with Docker Compose

### Step 1: Set Up Directory Structure

Create the directory structure for sequencer data storage:

```bash
mkdir -p aztec-sequencer/keys aztec-sequencer/data
cd aztec-sequencer
touch .env
```

### Step 2: Generate and Move Private Keystore to Docker Directory

If you haven't already generated your private and public keystores, do so now (see [Generating Keys](#generating-keys) above).

Move the private keystore (not the public keystore) into the Docker directory:

```bash
# Move the private keystore to Docker directory (replace N with your key number)
cp ~/.aztec/keystore/keyN.json aztec-sequencer/keys/keystore.json

# Keep the public keystore for later use with the staking dashboard
# It will be at ~/.aztec/keystore/keyN_staker_output.json
```

### Step 3: Fund Your Publisher Account

Your sequencer needs ETH to pay for gas when submitting blocks to L1. Fund the account that will act as the publisher.

**Determine which address to fund:**

```bash
# Get your attester address (this will be your publisher if no separate publisher is configured)
jq -r '.[0].attester' ~/.aztec/keystore/keyN_staker_output.json

# If you have a separate publisher configured: (Note this returns the publisher private key)
jq -r '.validators[0].publisher[0]' aztec-sequencer/keys/keystore.json
```

The publisher account pays L1 gas each time it submits a checkpoint. At current mainnet gas levels the cost is small (around 0.03 ETH per attester per year), but balance decays continuously and the system does not retry with a different publisher if a transaction fails due to insufficient funds.

**Sizing the top-up:**

* 1 attester → 0.01 ETH gives several months of runway
* 10 attesters sharing one publisher → roughly 0.1 ETH for a similar window
* For exact runway estimates, use the [funding calculator](/operate/operators/solo-sequencer/fund-accounts.md#fund-the-publisher) with your L1 RPC to scan the last 30 days of network activity

tip

Set a refill threshold and an alert on the publisher balance so you can top up before it dries up at the worst-case gas price you expect.

### Step 4: Configure Environment Variables

Add the following to your `.env` file:

```bash
DATA_DIRECTORY=./data
KEY_STORE_DIRECTORY=./keys
LOG_LEVEL=info
ETHEREUM_HOSTS=[your Ethereum mainnet execution endpoint, or a comma separated list if you have multiple]
L1_CONSENSUS_HOST_URLS=[your Ethereum mainnet consensus endpoint, or a comma separated list if you have multiple]
ETHEREUM_DEBUG_HOSTS=[your trace capable L1 execution endpoint]
P2P_IP=[your external IP address]
P2P_PORT=40400
AZTEC_PORT=8080
AZTEC_ADMIN_PORT=8880
```

tip

Find your public IP address with: `curl ipv4.icanhazip.com`

Nethermind Users (versions before v1.36.0)

If you are using Nethermind as your L1 execution client with a version before v1.36.0, you must add the following environment variable:

```bash
# Required for Nethermind versions before v1.36.0
L1_FIXED_PRIORITY_FEE_PER_GAS=1
```

This issue was fixed in Nethermind v1.36.0, so users on that version or later do not need this setting.

Trace-capable L1 endpoint required

The node needs an L1 execution endpoint that serves `trace_transaction` or `debug_traceTransaction`. A checkpoint published through a non-standard contract, rather than by a direct call to the rollup, cannot be read from the transaction calldata alone. The node traces that transaction to recover the checkpoint, and without a trace it stops syncing at that checkpoint.

Set `ETHEREUM_DEBUG_HOSTS` to your trace-capable endpoint. If you leave it unset, the node uses `ETHEREUM_HOSTS` for trace calls. The node only uses `ETHEREUM_DEBUG_HOSTS` for traces, not for regular L1 interactions.

At startup the node checks that it can trace a recent L1 transaction on that endpoint, and refuses to start if neither method works. To start anyway, set `ETHEREUM_ALLOW_NO_DEBUG_HOSTS=true`. The node then logs a warning and runs, but stalls on the first checkpoint it cannot read until you point it at a trace-capable endpoint and restart it.

### Step 5: Create Docker Compose File

Create a `docker-compose.yml` file in your `aztec-sequencer` directory:

```yaml
services:
  aztec-sequencer:
    image: "azteclabs/aztec:6.0.0"
    container_name: "aztec-sequencer"
    ports:
      - ${AZTEC_PORT}:${AZTEC_PORT}
      - ${P2P_PORT}:${P2P_PORT}
      - ${P2P_PORT}:${P2P_PORT}/udp
    volumes:
      - ${DATA_DIRECTORY}:/var/lib/data
      - ${KEY_STORE_DIRECTORY}:/var/lib/keystore
    environment:
      KEY_STORE_DIRECTORY: /var/lib/keystore
      DATA_DIRECTORY: /var/lib/data
      LOG_LEVEL: ${LOG_LEVEL}
      ETHEREUM_HOSTS: ${ETHEREUM_HOSTS}
      L1_CONSENSUS_HOST_URLS: ${L1_CONSENSUS_HOST_URLS}
      ETHEREUM_DEBUG_HOSTS: ${ETHEREUM_DEBUG_HOSTS}
      P2P_IP: ${P2P_IP}
      P2P_PORT: ${P2P_PORT}
      AZTEC_PORT: ${AZTEC_PORT}
      AZTEC_ADMIN_PORT: ${AZTEC_ADMIN_PORT}
    entrypoint: >-
      node
      --no-warnings
      /usr/src/yarn-project/aztec/dest/bin/index.js
      start
      --node
      --sequencer
      --network mainnet
    networks:
      - aztec
    restart: always

networks:
  aztec:
    name: aztec
```

Security: Admin Port Not Exposed

The admin port (8880) is intentionally **not exposed** to the host machine for security reasons. The admin API provides sensitive operations like configuration changes and database rollbacks that should never be accessible from outside the container.

If you need to access admin endpoints, use `docker exec`:

```bash
docker exec -it aztec-sequencer curl -X POST http://localhost:8880 \
  -H 'Content-Type: application/json' \
  -H 'x-api-key: [ADMIN_API_KEY]' \
  -d '{"jsonrpc":"2.0","method":"aztecAdmin_getConfig","params":[],"id":1}'
```

The admin API requires an API key by default. The node generates one at first startup and prints it once to the logs; pass it with the `x-api-key` header (or `Authorization: Bearer [ADMIN_API_KEY]`). See [admin API key authentication](/operate/operators/reference/changelog/v4.md#admin-api-key-authentication).

This configuration includes only essential settings. The `--network mainnet` flag applies network-specific defaults—see the [CLI reference](/operate/operators/reference/cli-reference.md) for all available configuration options. For testnet, replace every `--network mainnet` in this guide with `--network testnet`, and use Sepolia L1 endpoints.

### Step 6: Start the Sequencer

Start the sequencer:

```bash
docker compose up -d
```

## Verification

Once your sequencer is running, verify it's working correctly:

### Check Sync Status

Check the current sync status (this may take a few minutes):

```bash
curl -s -X POST -H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","method":"aztec_getChainTips","params":[],"id":67}' \
http://localhost:8080 | jq -r ".result.proven.block.number"
```

Compare the output with block explorers (see [Networks page](/networks.md) for explorer links).

### Check Node Status

```bash
curl http://localhost:8080/status
```

### View Logs

```bash
docker compose logs -f --tail 100 aztec-sequencer
```

## Next Steps: Registering Your Sequencer

Now that your sequencer node is set up and running, you need to register it with the network. There are two ways to participate as a sequencer:

### Option 1: Self-Staking via Staking Dashboard

Register your sequencer and provide your own stake through the staking dashboard. This is the most common approach for individual operators.

**→ [Register Your Sequencer (Self-Staking)](/operate/operators/setup/registering_sequencer.md)**

You'll use the **public keystore** file (`keyN_staker_output.json`) that was generated when you created your keys.

### Option 2: Running with Delegated Stake

Operate sequencers backed by tokens from delegators. This non-custodial system allows you to run sequencer infrastructure while delegators provide the economic backing.

**→ [Run as a Staking Provider](/operate/operators/setup/become_a_staking_provider.md)**

As a provider, you'll register with the Staking Registry and manage a queue of sequencer identities that activate when delegators stake to you.

Which Option Should I Choose?

* **Self-staking**: You have tokens and want to run your own sequencer
* **Delegated staking**: You want to operate sequencer infrastructure and earn commission from delegators' stake

Both options use the same node setup from this guide.

## Monitoring Sequencer Status

You can query the status of any sequencer (attester) using the Rollup and GSE (Governance Staking Escrow) contracts on L1.

### Prerequisites

* Foundry installed (`cast` command)
* Ethereum RPC endpoint
* Registry contract address for your network

### Get Contract Addresses

First, get the canonical Rollup contract address from the Registry:

```bash
# Get the canonical rollup address
cast call [REGISTRY_CONTRACT_ADDRESS] "getCanonicalRollup()" --rpc-url [YOUR_RPC_URL]
```

Then get the GSE contract address from the Rollup:

```bash
# Get the GSE contract address
cast call [ROLLUP_ADDRESS] "getGSE()" --rpc-url [YOUR_RPC_URL]
```

### Query Sequencer Status

Check the complete status and information for a specific sequencer:

```bash
# Get full attester view (status, balance, exit info, config)
cast call [ROLLUP_ADDRESS] "getAttesterView(address)" [ATTESTER_ADDRESS] --rpc-url [YOUR_RPC_URL]
```

This returns an `AttesterView` struct containing:

1. **status** - The sequencer's current status (see Status Codes below)
2. **effectiveBalance** - The sequencer's effective stake balance
3. **exit** - Exit information (if the sequencer is exiting)
4. **config** - Attester configuration (withdrawer address and public key)

#### Status Codes

| Status | Name       | Meaning                                                                                                                         |
| ------ | ---------- | ------------------------------------------------------------------------------------------------------------------------------- |
| 0      | NONE       | The sequencer does not exist in the sequencer set                                                                               |
| 1      | VALIDATING | The sequencer is currently active and participating in consensus                                                                |
| 2      | ZOMBIE     | The sequencer is not active (balance fell below ejection threshold, possibly due to slashing) but still has funds in the system |
| 3      | EXITING    | The sequencer has initiated withdrawal and is in the exit delay period                                                          |

### Performance Monitoring

Track your sequencer's performance by monitoring:

* **Effective balance** - Should remain above the ejection threshold
* **Status** - Should be VALIDATING for active participation
* **Attestation rate** - How many attestations you've successfully submitted
* **Proposal success rate** - How many of your proposed blocks were accepted
* **Network participation metrics** - Overall participation in network consensus

## Exiting a Sequencer

warning

Information about the exit process will be added when the mechanism is finalized. Check the [Aztec Discord](https://discord.gg/aztec) for the latest information on exiting the sequencer set.

## Troubleshooting

### Port forwarding not working

**Issue**: Your node cannot connect to peers.

**Solutions**:

* Verify your external IP address matches the `P2P_IP` setting
* Check firewall rules on your router and local machine
* Test connectivity using: `nc -zv [your-ip] 40400`

### Sequencer not syncing

**Issue**: Your node is not synchronizing with the network.

**Solutions**:

* Check L1 endpoint connectivity
* Verify both execution and consensus clients are fully synced
* Review logs for specific error messages
* Ensure L1 endpoints support high throughput

### Private keystore issues

**Issue**: Private keystore not loading or errors about invalid keys.

**Solutions**:

* Ensure `keystore.json` is properly formatted
* Verify private keys are valid Ethereum private keys
* Check file permissions on the keys directory

### Docker issues

**Issue**: Container won't start or crashes.

**Solutions**:

* Ensure Docker and Docker Compose are up to date
* Check disk space availability
* Verify the `.env` file is properly formatted
* Review container logs: `docker compose logs aztec-sequencer`

### Common Issues

See the [Operator FAQ](/operate/operators/operator-faq.md) for additional common issues and resolutions.

## Additional Resources

After setting up and registering your sequencer:

* **[Register Your Sequencer](/operate/operators/setup/registering_sequencer.md)** - Complete registration via staking dashboard
* **[Monitor Sequencer Status](#monitoring-sequencer-status)** - Track performance and attestation rate
* **[Operator FAQ](/operate/operators/operator-faq.md)** - Common issues and resolutions
* **[Governance Participation](/operate/operators/sequencer-management/creating_and_voting_on_proposals.md)** - Participate in governance
* **[Advanced Keystore Patterns](/operate/operators/keystore/advanced-patterns.md)** - Manage multiple sequencer identities

**Community support:**

* Join the [Aztec Discord](https://discord.gg/aztec) for operator support and network updates
