How to Run Your Own Ethereum Node
Running your own Ethereum node gives you a private, trustless RPC endpoint with no rate limits and no third party in the loop. Since The Merge, a node is two programs: an execution client (we’ll use Geth) and a consensus client (Lighthouse). This guide is the exact setup we run in production, on Ubuntu 24.04 — copy-paste ready.
Hardware requirements
The one non-negotiable is a fast NVMe SSD. Ethereum’s database is brutally random-I/O heavy; a SATA SSD or (especially) an HDD literally cannot keep up — the node will fall behind the chain and never catch the tip. Don’t skip this.
| Resource | Full node | Archive node |
|---|---|---|
| CPU | 4+ cores | 8+ cores |
| RAM | 16–32 GB | 32 GB+ |
| Disk | ~2 TB NVMe (1.6 TB used + headroom) | 15 TB+ NVMe |
| Initial sync | ~1 day on NVMe | weeks |
Most people want a full node — it serves nearly all RPC and the disk stays around 1.5–2 TB. You only need an archive nodefor historical state queries (e.g. a balance at an old block), and it’s ~10× the disk.
Step 1 — Install Geth (execution client)
sudo add-apt-repository -y ppa:ethereum/ethereum sudo apt-get update sudo apt-get install -y geth geth version # confirm it installed
Step 2 — Install Lighthouse (consensus client)
Grab the latest release binary from Sigma Prime’s GitHub (replace the version with the current one):
LH=v8.2.0 curl -LO https://github.com/sigp/lighthouse/releases/download/$LH/lighthouse-$LH-x86_64-unknown-linux-gnu.tar.gz tar xzf lighthouse-$LH-x86_64-unknown-linux-gnu.tar.gz sudo install -m755 lighthouse /usr/local/bin/ lighthouse --version
Step 3 — Dedicated user, data dirs, and JWT secret
Run the clients as a non-root user. The JWT secret is a shared key the two clients use to authenticate to each other over the Engine API — generate it once.
sudo useradd --system --no-create-home --shell /usr/sbin/nologin eth sudo mkdir -p /data/geth /data/lighthouse sudo openssl rand -hex 32 | sudo tee /data/jwt.hex sudo chown -R eth:eth /data sudo chmod 640 /data/jwt.hex
Step 4 — systemd services
Create /etc/systemd/system/geth.service. RPC is bound to 127.0.0.1 — keep it that way unless you firewall it to specific IPs (an open Ethereum RPC gets abused fast).
[Unit] Description=Geth Execution Client After=network-online.target Wants=network-online.target [Service] User=eth Group=eth Restart=on-failure RestartSec=5 LimitNOFILE=65536 ExecStart=/usr/bin/geth \ --datadir=/data/geth \ --syncmode=snap \ --cache=8192 \ --http --http.addr=127.0.0.1 --http.api=eth,net,web3 \ --ws --ws.addr=127.0.0.1 --ws.api=eth,net,web3 \ --authrpc.addr=127.0.0.1 --authrpc.port=8551 --authrpc.jwtsecret=/data/jwt.hex [Install] WantedBy=multi-user.target
Then /etc/systemd/system/lighthouse.service. The checkpoint-sync-url lets the beacon node sync in minutes instead of days by trusting a recent finalized state (pick any provider from the eth-clients checkpoint-sync list):
[Unit] Description=Lighthouse Beacon Node After=network-online.target Wants=network-online.target [Service] User=eth Group=eth Restart=on-failure RestartSec=5 ExecStart=/usr/local/bin/lighthouse bn \ --network=mainnet \ --datadir=/data/lighthouse \ --execution-endpoint=http://127.0.0.1:8551 \ --execution-jwt=/data/jwt.hex \ --checkpoint-sync-url=https://beaconstate.ethstaker.cc \ --http [Install] WantedBy=multi-user.target
Step 5 — Start and verify
sudo systemctl daemon-reload
sudo systemctl enable --now geth lighthouse
# Execution sync status (returns false when fully synced):
curl -s -X POST -H "Content-Type: application/json" \
--data '{"jsonrpc":"2.0","method":"eth_syncing","params":[],"id":1}' \
http://127.0.0.1:8545
# Consensus sync status:
curl -s http://127.0.0.1:5052/eth/v1/node/syncingLighthouse checkpoint-syncs in a few minutes, then Geth snap-syncs the full state — expect the whole thing to reach the chain tip in roughly a day on NVMe. When eth_syncing returns false and the latest block is seconds old, you’re live. Point your apps at http://127.0.0.1:8545.
The honest part: what running it actually costs
The commands above are the easy 30 minutes. The expensive part is everything after, and it’s worth knowing before you commit:
- Hard-fork upgrades. Ethereum upgrades on a schedule. Miss a client update before a fork and your node silently follows the wrong chain or halts — you’re on the hook to track and apply every one, on time.
- Redundancy. One node is a single point of failure. The moment real users depend on it, you need at least two plus a load balancer — roughly doubling the cost and the babysitting.
- The disk only grows. Budget for migrations to bigger volumes, and for archive that’s 15 TB+ and climbing.
- It’s per chain. This guide is just Ethereum. Every other chain you need is a separate client, separate sync, separate upgrade calendar, separate thing that breaks at 3 a.m.
- The real bill is engineer-hours, not the server. We did the full math in Self-Hosted Node vs RPC Provider.
…or skip all of it
SwiftNodes gives you the same thing — an at-tip Ethereum endpoint with archive and debug support — with none of the hardware, sync waits, fork upgrades, or redundancy to manage. Flat-rate pricing (no per-call compute units), Ethereum plus dozens of other chains under one key, and a free tier to start.
Grab a key at swiftnodes.io and point your app at https://rpc.swiftnodes.io/rpc/eth?key=YOUR_API_KEY.