The iota start command provides a simple way to run a local IOTA network for development and testing.
Basic Usage
Quick Start
Start local network
iota start --force-regenesis
This starts a fresh network with:
1 validator node
1 fullnode with RPC on port 9000
New genesis generated each run
No state persistence
Connect client
In another terminal: iota client new-env \
--alias localnet \
--rpc http://127.0.0.1:9000
iota client switch --env localnet
Get test tokens
iota client new-address ed25519
iota client faucet
Output:
Cluster started
Fullnode URL: http://127.0.0.1:9000
Network Modes
Ephemeral Mode (—force-regenesis)
Start fresh each time with no state persistence:
iota start --force-regenesis [OPTIONS]
Use cases:
Quick testing
Reproducible test environments
CI/CD pipelines
Development iteration
Features:
New genesis every run
No config directory required
Clean state
Fast startup
Persistent Mode
Maintain state between runs:
Generate genesis
iota genesis --force --with-faucet
Start network
This uses the genesis from ~/.iota/iota_config/.
Stop and restart
# Press Ctrl+C to stop
# Restart with same state
iota start
Use cases:
Long-running development
Testing state transitions
Upgrading contracts
Debugging state issues
Custom Config Directory
Use a custom location for network config:
iota start --network.config < PAT H >
Example:
# Generate genesis in custom directory
iota genesis --working-dir ./my-network --force
# Start with custom config
iota start --network.config ./my-network
Network Configuration
Validator Configuration
Committee Size
Set the number of validators:
iota start --force-regenesis --committee-size < N >
Examples:
# Single validator (default)
iota start --force-regenesis --committee-size 1
# Multi-validator setup
iota start --force-regenesis --committee-size 4
Committee size can only be set with --force-regenesis or when generating genesis.
Epoch Configuration
Set epoch duration:
iota start --force-regenesis --epoch-duration-ms < M S >
Examples:
# 10 second epochs (fast testing)
iota start --force-regenesis --epoch-duration-ms 10000
# 1 minute epochs (default)
iota start --force-regenesis --epoch-duration-ms 60000
# 1 hour epochs
iota start --force-regenesis --epoch-duration-ms 3600000
Fullnode Configuration
RPC Port
Customize the RPC port:
iota start --force-regenesis --fullnode-rpc-port < POR T >
Example:
iota start --force-regenesis --fullnode-rpc-port 8080
Then connect:
iota client new-env --alias local --rpc http://127.0.0.1:8080
No Fullnode
Run validators only (no fullnode):
iota start --force-regenesis --no-full-node
Without a fullnode, you cannot use RPC or run an indexer.
Faucet Configuration
Start network with a built-in faucet:
iota start --force-regenesis --with-faucet
Faucet Options
iota start --force-regenesis \
--with-faucet=0.0.0.0:9123 \
--faucet-amount 500000000000 \
--faucet-coin-count 10
Options:
--with-faucet[=HOST:PORT] - Enable faucet (default: 0.0.0.0:9123)
--faucet-amount <NANOS> - Nanos per coin (default: 200,000,000,000)
--faucet-coin-count <N> - Coins per request (default: 5)
Using the Faucet
# Request tokens
iota client faucet --url http://127.0.0.1:9123
# Or use curl
curl -X POST http://127.0.0.1:9123/v1/gas \
-H "Content-Type: application/json" \
-d '{"recipient": "0x1234..."}'
Indexer & GraphQL
Indexer features require PostgreSQL and the indexer build feature.
Start with Indexer
iota start --force-regenesis \
--with-indexer=0.0.0.0:9124 \
--pg-host localhost \
--pg-port 5432 \
--pg-db-name iota_indexer \
--pg-user postgres \
--pg-password postgrespw
Start with GraphQL
iota start --force-regenesis \
--with-indexer \
--with-graphql=0.0.0.0:9125 \
--pg-host localhost \
--pg-port 5432 \
--pg-db-name iota_indexer \
--pg-user postgres \
--pg-password postgrespw
GraphQL requires the indexer. If --with-graphql is set without --with-indexer, the indexer is automatically enabled.
PostgreSQL Setup
Install PostgreSQL
# Ubuntu/Debian
sudo apt install postgresql
# macOS
brew install postgresql
# Start service
sudo systemctl start postgresql
# or on macOS:
brew services start postgresql
Create database
CREATE DATABASE iota_indexer ;
CREATE USER postgres WITH PASSWORD 'postgrespw' ;
GRANT ALL PRIVILEGES ON DATABASE iota_indexer TO postgres;
\q
Start network with indexer
iota start --force-regenesis --with-indexer
Data Ingestion
Specify checkpoint data directory:
iota start --force-regenesis \
--with-indexer \
--data-ingestion-dir ./checkpoints
Migration Snapshots
Start network with migration data:
iota start --force-regenesis \
--local-migration-snapshots ./snapshot1.json ./snapshot2.json \
--remote-migration-snapshots iota \
--delegator 0x1234567890abcdef1234567890abcdef12345678
Options:
--local-migration-snapshots <PATH>... - Local snapshot files
--remote-migration-snapshots <URL>... - Remote snapshots (or iota for default)
--delegator <ADDRESS> - Delegator address (required with snapshots)
Protocol Config Overrides
Override protocol parameters using environment variables:
Enable Overrides
export IOTA_PROTOCOL_CONFIG_OVERRIDE_ENABLE = 1
Set Overrides
# Increase checkpoint interval to >1/s
export IOTA_PROTOCOL_CONFIG_OVERRIDE_min_checkpoint_interval_ms = 1000
# Adjust max transactions per checkpoint
export IOTA_PROTOCOL_CONFIG_OVERRIDE_max_transactions_per_checkpoint = 10000
# Set max transaction size
export IOTA_PROTOCOL_CONFIG_OVERRIDE_max_tx_size_bytes = 131072
# Start network
iota start --force-regenesis
Protocol config overrides must match across all nodes. Mismatched configurations will break the network. Only use in local development.
Complete Examples
Minimal Development Setup
iota start --force-regenesis
Full-Featured Local Network
iota start --force-regenesis \
--committee-size 4 \
--epoch-duration-ms 60000 \
--with-faucet=0.0.0.0:9123 \
--faucet-amount 500000000000 \
--fullnode-rpc-port 9000
With Indexer and GraphQL
Set up PostgreSQL
sudo -u postgres createdb iota_indexer
Start network
iota start --force-regenesis \
--with-indexer=0.0.0.0:9124 \
--with-graphql=0.0.0.0:9125 \
--with-faucet \
--pg-host localhost \
--pg-port 5432 \
--pg-db-name iota_indexer \
--pg-user postgres \
--pg-password postgrespw
Access services
# RPC
curl http://127.0.0.1:9000
# Indexer
curl http://127.0.0.1:9124
# GraphQL
curl http://127.0.0.1:9125/graphql
# Faucet
curl -X POST http://127.0.0.1:9123/v1/gas \
-H "Content-Type: application/json" \
-d '{"recipient": "0x..."}'
Persistent Network with Custom Config
Create config directory
mkdir -p ~/my-iota-network
Generate genesis
iota genesis \
--working-dir ~/my-iota-network \
--force \
--committee-size 4 \
--epoch-duration-ms 60000 \
--with-faucet
Start network
iota start --network.config ~/my-iota-network
Stop and restart
# Ctrl+C to stop
# Restart preserves state
iota start --network.config ~/my-iota-network
Development Workflow
Iterative Development
# Terminal 1: Start network
iota start --force-regenesis --with-faucet
# Terminal 2: Development
iota client switch --env localnet
iota client new-address ed25519
iota client faucet
# Build and publish package
cd my_package
iota client publish --gas-budget 100000000
# Test
iota client call --package 0x... --module my_module --function test_fn
# Restart for clean state
# Terminal 1: Ctrl+C, then:
iota start --force-regenesis --with-faucet
Testing Upgrades
Start persistent network
iota genesis --force --with-faucet
iota start
Publish v1
iota client publish --gas-budget 100000000
# Save UpgradeCap ID
Make changes
Edit your Move code.
Upgrade to v2
iota client upgrade \
--upgrade-capability 0xCAP_ID \
--gas-budget 100000000
Multi-Validator Testing
# Start 4-validator network
iota start --force-regenesis --committee-size 4
# Test consensus behavior
iota client call --package 0x2 --module coin --function mint ...
# Observe epoch changes
iota client active-env
Monitoring
Health Checks
The network performs health checks every 3 seconds:
Cluster started
Fullnode URL: http://127.0.0.1:9000
[Health check passed]
[Health check passed]
...
If a validator fails health checks 3 times consecutively, the network stops.
Logs
Logs are output to stdout:
# Save logs to file
iota start --force-regenesis 2>&1 | tee network.log
# Filter logs
iota start --force-regenesis 2>&1 | grep -E "(ERROR|WARN)"
Network Status
# In another terminal
iota client active-env
# Check validator info
iota client call \
--package 0x3 \
--module iota_system \
--function active_validators
Troubleshooting
Port Already in Use
Error : Address already in use (os error 48)
Solution:
# Find process using port
lsof -i :9000
# Kill process
kill -9 < PI D >
# Or use different port
iota start --force-regenesis --fullnode-rpc-port 9001
Genesis Issues
Error : Cannot pass --force-regenesis and --network.config
Solution:
# Don't mix modes - choose one:
# Ephemeral (no config dir)
iota start --force-regenesis
# Persistent (with config dir)
iota start --network.config < PAT H >
Error : Epoch duration can only be set with --force-regenesis
Solution:
# Either use --force-regenesis:
iota start --force-regenesis --epoch-duration-ms 60000
# Or set in genesis first:
iota genesis --force --epoch-duration-ms 60000
iota start
Indexer Issues
Error : Cannot start the indexer without a fullnode
Solution:
# Remove --no-full-node flag
iota start --force-regenesis --with-indexer
Error : Failed to connect to PostgreSQL
Solution:
# Verify PostgreSQL is running
sudo systemctl status postgresql
# Test connection
psql -h localhost -U postgres -d iota_indexer
# Check credentials
iota start --force-regenesis \
--with-indexer \
--pg-host localhost \
--pg-port 5432 \
--pg-db-name iota_indexer \
--pg-user postgres \
--pg-password postgrespw
Network Hangs
Issue : Network stops responding
Solution:
# Check logs for errors
iota start --force-regenesis 2>&1 | tee network.log
# Restart with clean state
iota start --force-regenesis
# Check disk space
df -h
Best Practices
Development
Use ephemeral mode for quick iterations:
iota start --force-regenesis
Enable faucet for easy token access:
iota start --force-regenesis --with-faucet
Short epochs for faster testing:
iota start --force-regenesis --epoch-duration-ms 10000
Save logs for debugging:
iota start --force-regenesis 2>&1 | tee network.log
Testing
Use persistent mode for upgrade testing:
iota genesis --force --with-faucet
iota start
Multi-validator for consensus testing:
iota start --force-regenesis --committee-size 4
Enable indexer for query testing:
iota start --force-regenesis --with-indexer --with-graphql
Production-like Setup
Realistic epochs :
iota start --force-regenesis --epoch-duration-ms 3600000
Multiple validators :
iota start --force-regenesis --committee-size 10
Full services :
iota start --force-regenesis \
--committee-size 4 \
--with-faucet \
--with-indexer \
--with-graphql
Next Steps
Client Commands Interact with your local network
Move Commands Build and publish packages
Testing Write and run tests
Genesis Commands Advanced network configuration