How to Run Your Own BNB Smart Chain (BSC) Node

A BNB Smart Chain node is a single clientbnb-chain/bsc, a fork of Geth — so it’s simpler to run than a post-Merge Ethereum node (no separate consensus client). It gives you a private endpoint on chain ID 56 with no rate limits. The one thing that defines the BSC experience: the chain is huge and grows fast(3-second blocks, high throughput, 40M+ blocks), so you don’t sync from genesis — you bootstrap from a snapshot. This guide is the official setup on Ubuntu 24.04.

Hardware requirements

BSC publishes two practical tiers. A fast node keeps the latest world state in a lighter footprint (what most people running their own RPC want); a full nodekeeps more history and needs more disk. Both want a fast NVMe SSD — BSC’s throughput makes disk I/O the bottleneck.

ResourceFast nodeNotes
CPU16 coresHigh single-thread performance helps.
RAM32 GB+
Disk2 TB+ NVMe SSDgp3-class: ~8k IOPS, 250 MB/s, read latency <1ms. Snap sync needs NVMe. State grows continuously — leave headroom.
NetworkStable, 5 MB/s+More is better; snapshot download is hundreds of GB.

Because BSC is a Geth fork, the client mechanics (snap vs full sync, path-based state, pruning) will feel familiar if you’ve read Geth vs Erigon vs Reth. Want the full transaction history and old state? That’s an archive node— dramatically more disk; most people don’t need it.

Step 1 — Download the geth binary and mainnet config

Grab the pre-built binary and the mainnet config bundle (genesis.json + config.toml) from the latest bnb-chain/bsc release:

# the geth binary
wget $(curl -s https://api.github.com/repos/bnb-chain/bsc/releases/latest \
  | grep browser_ | grep geth_linux | cut -d'"' -f4)
mv geth_linux geth && chmod +x geth

# mainnet genesis.json + config.toml
wget $(curl -s https://api.github.com/repos/bnb-chain/bsc/releases/latest \
  | grep browser_ | grep mainnet | cut -d'"' -f4)
unzip mainnet.zip     # -> genesis.json, config.toml

Step 2 — Bootstrap from a snapshot (don’t sync from genesis)

Syncing BSC from block 0 would take an impractically long time. Instead, download a recent chaindata snapshot and drop it into your data directory. Snapshots are published at bnb-chain/bsc-snapshots:

sudo mkdir -p /data/bsc
# Follow the current instructions on the bsc-snapshots repo to fetch the latest
# snapshot (it changes constantly). Extract its "geth" chaindata under:
#   /data/bsc/geth/chaindata
# The snapshot IS the initialized chaindata — no separate 'geth init' needed.

Snapshots are large (hundreds of GB) and go stale quickly; once restored, the node only needs to catch up the blocks produced since the snapshot was taken.

Step 3 — Dedicated user and systemd service

Run as an unprivileged bsc user and manage the process with systemd. Create /etc/systemd/system/bsc.service (the start command matches the official recommendation):

sudo useradd --system --no-create-home --shell /usr/sbin/nologin bsc
sudo mkdir -p /data/bsc && sudo chown -R bsc:bsc /data/bsc /opt/bsc

# put geth, config.toml, genesis.json under /opt/bsc

sudo tee /etc/systemd/system/bsc.service >/dev/null <<'EOF'
[Unit]
Description=BNB Smart Chain Full Node
After=network-online.target
Wants=network-online.target

[Service]
User=bsc
WorkingDirectory=/opt/bsc
ExecStart=/opt/bsc/geth \
  --config /opt/bsc/config.toml \
  --datadir /data/bsc \
  --syncmode snap \
  --cache 10000 \
  --rpc.allow-unprotected-txs \
  --history.transactions 0 \
  --history.logs 576000
Restart=always
RestartSec=5
LimitNOFILE=200000

[Install]
WantedBy=multi-user.target
EOF

--cache 10000 gives the DB plenty of memory; --history.transactions 0 and --history.logs 576000 keep the node lighter by trimming old history (raise or remove these if you need deeper lookups). Edit config.toml to enable the HTTP/WS RPC on 127.0.0.1and expose only the namespaces you need — then firewall it.

Step 4 — Start and verify

sudo systemctl daemon-reload
sudo systemctl enable --now bsc

# watch it import blocks
tail -f /data/bsc/bsc.log        # look for "Imported new chain segment"

# once RPC is up, confirm chain ID 56 (0x38)
curl http://localhost:8545 -s -X POST -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":1,"method":"eth_chainId","params":[]}'
# -> {"jsonrpc":"2.0","id":1,"result":"0x38"}

Don’t trust “it responds” as “it’s synced” — confirm the head is actually at the tip and advancing using the checks in Is your RPC node actually at the chain tip?.

The honest part: what running it actually costs

BSC is deceptively simple to start and genuinely demanding to keep running:

  • The disk never stops growing. Fast blocks and high volume mean state and history expand continuously; a node that fit last quarter can fill its disk this quarter. You’ll be managing storage forever.
  • Snapshots are a recurring chore. Bootstrapping and (after any corruption or fresh start) re-bootstrapping means downloading hundreds of GB and babysitting the restore. High-IOPS NVMe isn’t optional.
  • Hard forks need prompt upgrades. BSC ships frequent client releases with scheduled fork blocks; miss one and your node stops following the chain.
  • One node is a single point of failure. Production use wants at least two, plus a load balancer and health checks — doubling all of the above. See Self-Hosted Node vs RPC Provider.

…or skip all of it

SwiftNodes runs load-balanced BNB Smart Chain nodes for you — flat-rate pricing (no per-call compute units), HTTP + WebSocket, no KYC — alongside 75+ other chains under one API key. No snapshot babysitting, no disk-space firefighting.

Grab a key at swiftnodes.io and point your app at https://rpc.swiftnodes.io/rpc/bsc?key=YOUR_API_KEY.