Chaingateway
10 min read
|
10/4/2023

How to Set Up a Binance Smart Chain (BSC) Node

Set up a BSC node the official way: snapshot sync, the bnb-chain geth fork, a systemd unit, hardware table, costs, and when an API is the better call.

Chapters
C
Chaingateway Team
Blockchain Experts

BNB Smart Chain — still widely searched as Binance Smart Chain, its name until February 2022 — is an EVM chain that produces a block every 0.45 seconds since the Fermi hard fork of January 2026, after Maxwell had already halved the interval to 0.75 seconds in mid-2025. That speed is pleasant for users and demanding for node operators: a BSC full node wants server-grade hardware and the right sync strategy, and getting either wrong means a node that never reaches the chain head. This guide is the copy-paste version the official docs stop short of: snapshot-based setup with the bnb-chain geth fork, a systemd unit, security notes for RPC nodes, sync-time and cost math, plus an honest look at when you should not run one at all.

What is a BSC node, and which type do you need?

A BSC node runs the chain client, validates blocks and gives you a local JSON-RPC endpoint with the same interface as Ethereum: eth_blockNumber, eth_call, eth_sendRawTransaction and the rest. Four variants matter in practice.

A full node keeps recent state and serves RPC — the default, and the subject of this guide. A fast node is a full node started with --tries-verify-mode none; the official docs recommend it for RPC workloads where import speed counts more than strict state-trie verification. An archive node stores every historical state, needs disk space in the two-digit-terabyte range and only makes sense for indexing and analytics. A validator produces blocks, which requires being voted into the small elected set with staked BNB — a separate topic beyond a setup guide.

And a light node? The geth fork inherited light-client code, but in practice almost nothing on BSC serves light peers, so treat “BSC light node” as unavailable. If a pruned full node is more than you need, that is precisely the case for an API — see the last section.

The same choice as a table, with mid-2026 disk numbers:

Node typeDisk (mid-2026)HistoryWho runs it
Pruned full node2–3 TB working setrecent blocksanyone who needs their own RPC
Fast node (--tries-verify-mode none)like a full noderecent blocksRPC serving under heavy load
Archive node~4–5 TB on Erigon-class engines, far more on the geth forkcompleteindexers, analytics platforms
Validatortop-spec hardware per READMErecent blocksthe elected set only

BSC and Geth: one codebase, two chains

BSC’s client is a fork of go-ethereum, maintained at github.com/bnb-chain/bsc, and the binary is literally named geth. It speaks the same JSON-RPC, accepts most of the same flags, and adds BSC specifics: the Parlia proof-of-staked-authority consensus (one process is the whole node — no separate consensus client like on post-merge Ethereum), plus flags such as --tries-verify-mode. Two practical consequences follow. Your Ethereum tooling works unchanged against a BSC node. And you must run the bnb-chain build — upstream Geth cannot sync BSC, which is the single most common beginner mistake with “bsc geth”.

BSC node hardware requirements

The baseline comes from the bnb-chain/bsc README, adjusted for data growth through 2026:

ComponentPruned full nodeValidator / heavy RPC
CPU16 cores16 cores, high clock rate
RAM64 GB128 GB
Disk3 TB NVMe, ≥8k IOPS, ≥250 MB/s, <1 ms read latency4 TB+ NVMe, ≥10k IOPS
Network50 Mbit/s up and down100 Mbit/s+, unmetered

The row that kills most setups is IOPS, not capacity. With 0.45-second blocks the node writes constantly, and cloud block storage at default IOPS falls behind the chain head and never recovers. The README’s reference is AWS gp3 with 8,000 provisioned IOPS and sub-millisecond read latency (instance class m5zn.3xlarge on AWS, c2-standard-16 on Google Cloud); a local NVMe drive in a dedicated server clears that bar with room to spare.

Step by step: BSC full node from the official snapshot

Syncing from genesis is possible and a bad idea. The docs themselves discourage it — they suggest 40k+ IOPS hardware for the attempt, and it still takes weeks. The supported path: download the chain-data snapshot, start the node on top of it, let it catch up. Commands assume Ubuntu 24.04.

1. Prepare the server

Terminal window
sudo apt update && sudo apt install -y aria2 lz4 unzip jq
sudo useradd --no-create-home --shell /usr/sbin/nologin bsc
sudo mkdir -p /var/lib/bsc
sudo chown bsc:bsc /var/lib/bsc
sudo ufw allow 30311 comment 'bsc p2p'

Port 30311 is BSC’s peer-to-peer port and the only blockchain port that belongs open. The RPC port stays on localhost.

2. Download the bnb-chain geth binary

Terminal window
cd /tmp
curl -s https://api.github.com/repos/bnb-chain/bsc/releases/latest \
| jq -r '.assets[] | select(.name=="geth_linux") | .browser_download_url' \
| xargs wget -O geth_linux
chmod +x geth_linux
sudo mv geth_linux /usr/local/bin/geth-bsc
geth-bsc version

Renaming the binary to geth-bsc prevents the classic accident of starting a distro-installed upstream geth against BSC data.

3. Fetch config.toml and genesis.json

Terminal window
cd /tmp
curl -s https://api.github.com/repos/bnb-chain/bsc/releases/latest \
| jq -r '.assets[] | select(.name=="mainnet.zip") | .browser_download_url' \
| xargs wget -O mainnet.zip
unzip -o mainnet.zip
sudo mv config.toml genesis.json /var/lib/bsc/
sudo chown bsc:bsc /var/lib/bsc/config.toml /var/lib/bsc/genesis.json

Note: geth-bsc init genesis.json is only needed when syncing from genesis. On the snapshot path you skip init — the snapshot brings its own database.

4. Download and unpack the snapshot

Snapshots live at github.com/bnb-chain/bsc-snapshots, the official repository. It publishes three data sets as of mid-2026: the pruned snapshot at roughly 1.6 TB compressed (recent blocks only — the right one for this guide), the full snapshot at roughly 6 TB, and incremental snapshots that fetch only the changes since a previous one, an addition from the Fermi era (BEP-593). The current generation requires client v1.7.2 or newer, which the download in step 2 already satisfies. The repo also ships a fetch-snapshot.sh script that downloads, checks the MD5 checksum (-c flag) and extracts in one command; the manual route below shows what it does under the hood. Two ways to get the archive onto disk:

Terminal window
cd /var/lib/bsc
# Option A: resumable download, needs space for archive + extracted data
sudo -u bsc aria2c -x8 -s8 -c '<PASTE_SNAPSHOT_URL>'
sudo -u bsc bash -c "lz4 -cd geth.tar.lz4 | tar -x"
# Option B: stream-extract, needs space only once, but no resume
sudo -u bsc bash -c "wget -qO- '<PASTE_SNAPSHOT_URL>' | lz4 -d | tar -x"

aria2c downloads over eight connections and resumes after interruptions (-c) — with plain wget, a broken multi-terabyte download starts over. After extraction, the chain database must sit at /var/lib/bsc/geth/chaindata; the archive layout has changed between snapshot generations, so move the inner geth folder there if needed. Verify before extracting: compare the MD5 from the snapshot page, or let fetch-snapshot.sh -c handle it — a bit-flipped terabyte archive costs you a day. Option A needs space for the archive and the extracted data at the same time, which for the pruned set means roughly 2 TB of headroom and is the real reason behind the 4 TB disk recommendation.

5. systemd unit

Create /etc/systemd/system/bsc.service:

[Unit]
Description=BSC full node (bnb-chain geth fork)
After=network-online.target
Wants=network-online.target
[Service]
User=bsc
Group=bsc
Type=simple
Restart=always
RestartSec=5
TimeoutStopSec=600
LimitNOFILE=65536
ExecStart=/usr/local/bin/geth-bsc \
--config /var/lib/bsc/config.toml \
--datadir /var/lib/bsc \
--cache 8000 \
--tries-verify-mode none \
--history.transactions 0 \
--rpc.allow-unprotected-txs \
--http --http.addr 127.0.0.1 --http.port 8545 \
--http.api eth,net,web3
[Install]
WantedBy=multi-user.target

--tries-verify-mode none is the “fast node” switch from the official docs, recommended for RPC serving when you accept the state-consistency trade-off. --history.transactions 0 keeps the transaction index complete; older guides use the deprecated --txlookuplimit 0 for the same purpose. TimeoutStopSec=600 gives the node ten minutes to flush on shutdown — hard kills corrupt the database sooner or later.

6. Start and verify

Terminal window
sudo systemctl daemon-reload
sudo systemctl enable --now bsc
journalctl -fu bsc

Healthy output is a steady stream of “Imported new chain segment” lines. Compare your height against a public explorer:

Terminal window
curl -s -X POST -H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}' \
http://127.0.0.1:8545

Convert the hex result and check it against bscscan.com. When eth_syncing returns false and the height matches, the node is live.

Securing a BSC RPC node

The unit above binds RPC to 127.0.0.1, which is right for a node that only local software uses. If other machines need access, do not open port 8545 raw to the internet. Put nginx or Caddy in front with TLS, an auth token or IP allowlist, and rate limiting. Keep --http.api at eth,net,web3 — never expose admin, debug or txpool on a reachable node. Unauthenticated public BSC endpoints get discovered and hammered within days, and unrestricted eth_getLogs calls can stagger even strong hardware. The P2P port 30311 remains the only open blockchain port. One difference from Ethereum worth naming: there is no engine API and no JWT secret here, because Parlia needs no separate consensus client — the firewall and the localhost binding are the entire perimeter, so they have to be right.

Monitoring and health checks

A BSC node fails in one typical way: the process keeps running while the node falls behind the head. Process-level uptime checks miss that entirely, so check sync state and height instead.

Terminal window
# false = at the head; a sync object = still catching up
curl -s -X POST -H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","method":"eth_syncing","params":[],"id":1}' \
http://127.0.0.1:8545
# peer count as hex
curl -s -X POST -H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","method":"net_peerCount","params":[],"id":1}' \
http://127.0.0.1:8545

The stricter probe compares your eth_blockNumber against a second source — a public endpoint or an explorer — every few minutes and alerts when the gap grows. Calibrate the threshold to BSC’s cadence: 400 blocks sounds like a lot and is three minutes of chain time at 0.45-second blocks. Thresholds copied from Ethereum tooling are far too lax here.

The fork inherits Geth’s metrics stack. Start with --metrics (Prometheus endpoint on port 6060, keep it on localhost) and the standard Geth Grafana dashboards mostly work unchanged. Before any dashboard, set two alerts: disk usage above 85 percent, and local block height flat for five minutes. A daily journalctl -u bsc --since -24h | grep -ci error in a cron mail rounds it off — error counts that trend upward precede most failures by days.

Sync time, and why snapshots stay useful

Arithmetic instead of promises: the 1.6 TB pruned snapshot at a sustained 100 MB/s takes about 4.5 hours to download, at 50 MB/s about 9. Extraction is disk-bound and adds a few hours on NVMe. The snapshot lags the chain head by a day or two; a healthy node imports several times faster than real time, so catch-up costs hours, not days. All in, plan one working day. Genesis sync, for contrast, runs for weeks on extreme hardware — which is why the official recommendation is the snapshot, full stop.

State growth and pruning

The database keeps growing after day one — state with every new contract and account, block data at the pace 0.45-second blocks dictate. Exact growth depends on network activity; instead of trusting a fixed number, run du -sh /var/lib/bsc/geth/chaindata weekly and build your own trend line. The pattern to expect: hundreds of GB per quarter, not per year.

Three tools keep the size in check. geth-bsc snapshot prune-state is the built-in offline pruning: it discards state nodes nothing references anymore, takes many hours on a multi-terabyte database, and the node serves nothing meanwhile. Wipe-and-restore is the alternative many operators prefer: every few months, delete the datadir and restore the newest pruned snapshot. Total downtime is often lower than with pruning, and you get a freshly compacted database as a bonus.

The third tool arrived with Fermi: incremental snapshots (BEP-593). Instead of re-downloading 1.6 TB for every refresh, you fetch only what changed since the snapshot generation you already have, which turns the periodic refresh from an overnight job into a matter of hours. The bsc-snapshots README documents that workflow next to the classic archives.

Erigon on BSC — and its successor

For years the answer to BSC archive needs was bsc-erigon, NodeReal’s port of Erigon: a full archive sync from scratch in about three days, stored in roughly 4.3 TB where the geth fork needs tens of terabytes. That chapter closed. Maintenance ended with 2025, and the node-real/bsc-erigon repository was archived in April 2026 — read-only, no fixes, no support for future forks. NodeReal points operators to Reth-BSC, the Rust-based successor, as the recommended archive client going forward.

What that means in practice as of mid-2026: for the pruned RPC node in this guide, the official geth fork stays the reference and the safest choice. For archive workloads, evaluate Reth-BSC first, and treat existing bsc-erigon machines as migrations waiting to happen — an unmaintained client misses the next hard fork on schedule.

What a BSC node costs

Treat this as a way to calculate, not a price list. The 16-core / 64 GB / 4 TB NVMe class is dedicated-server territory — no honest VPS tier covers it. At European hosts, machines with those specs sit in the low-to-mid three-digit euro range per month, as an order of magnitude. The same specs built from cloud instances with 8k provisioned IOPS (the README’s AWS reference) typically land higher, often by a factor of two or more, because provisioned IOPS are billed separately.

Then add your hours: initial setup one working day with this guide, plus hard-fork upgrades and snapshot refreshes at a few hours per month. Multiply by your hourly rate. For most teams the labor line ends up larger than the hosting line — worth knowing before you commit.

Maintenance: hard forks and upgrades

BSC hard-forks at a pace that surprises Ethereum operators. 2025 alone brought Lorentz and Maxwell, each cutting the block interval in half; Fermi followed on January 14, 2026 and took blocks from 0.75 to 0.45 seconds while adding incremental snapshots and tightening fast finality. Every fork has a minimum client version — v1.6.4 for Fermi — and a node below it stalls at the fork block with consensus errors. By mid-2026 the release line is at v1.7.x, and the current snapshots assume at least v1.7.2.

So subscribe to the bnb-chain/bsc release feed on GitHub and treat upgrades as routine rather than as events. The procedure is short: download the new geth_linux, verify it, stop the service, replace /usr/local/bin/geth-bsc, start again — the database carries over. Release notes call out config changes, and BSC renames flags more often than upstream Geth, so skim them before the restart, not after. Budget a quarter hour per release, and expect a fork every few months.

For development setups, a local private network is available through the BSC-Deploy toolkit rather than by running mainnet nodes.

Troubleshooting

The node imports blocks but keeps falling behind the head

Almost always disk IOPS. Benchmark with fio and compare against the 8k IOPS reference; network-attached storage with default IOPS is the usual offender. Confirm --tries-verify-mode none is set. If the hardware sits below the requirements table, no flag will close the gap.

”missing trie node” errors, or the node starts syncing from block 0 after a snapshot restore

The datadir layout is wrong. The chain database must be at <datadir>/geth/chaindata — if the log shows “Writing custom genesis block”, geth found an empty datadir and started fresh. Stop the service, move the extracted geth folder to the right place, start again.

Peer count stays near zero

Check that port 30311 is open and forwarded. A stale config.toml is the second suspect: bootstrap and static node lists change over time, so re-download mainnet.zip from the latest release. On home connections, double-check NAT.

lz4 reports “Decoding error” during extraction

The archive is incomplete. Resume the download with aria2c -c and compare the file size with the one on the snapshot page before extracting again. Remember that option A needs free space for the archive and the extracted data at the same time.

The OOM killer ends the node

journalctl -k | grep -i oom settles the question. The unit sets --cache 8000, and real memory use peaks well above the cache figure during catch-up — fine on the recommended 64 GB, not fine on trimmed-down hardware. Lower --cache before lowering anything else, keep swap enabled as a crash buffer, and remember that an OOM-killed node flushes nothing: the next start may greet you with the “missing trie node” case above.

The disk runs full

df -h first, then du -h --max-depth=2 /var/lib/bsc to find the growth. Forgotten snapshot archives are the most common finding — the pruned .tar.lz4 alone is around 1.6 TB, and option A leaves it behind if you skip the cleanup. If chaindata itself is the problem, refresh from the newest pruned snapshot or run offline pruning (see the state-growth section). On BSC’s growth curve a full disk is a scheduling failure, not bad luck; the 85-percent alert from the monitoring section exists to buy you the week you need.

FAQ

Is a Binance Smart Chain node the same as a BNB Smart Chain node?

Yes. The chain was renamed from Binance Smart Chain to BNB Smart Chain in February 2022. Documentation, binaries and this guide all describe the same network; only the branding changed.

How big is a BSC full node in 2026?

The official pruned snapshot is roughly 1.6 TB compressed as of mid-2026, the full snapshot around 6 TB, and the working database plus catch-up data lands around 2–3 TB. With the temporary space needed during snapshot extraction, a 4 TB NVMe drive is the realistic size.

Can I run a BSC node with regular Ethereum Geth?

No. BSC uses the Parlia consensus and its own protocol rules; only the fork at github.com/bnb-chain/bsc can sync it. The identical binary name causes this confusion — hence the geth-bsc rename in step 2.

Is there a BSC light node?

Effectively no. The light-client code exists in the fork, but the network barely serves light peers. Your realistic options are a pruned full node, a fast node, or an API.

Do I earn BNB by running a full node?

No. Block rewards go to the elected validator set, which requires substantial staked BNB and community votes. A full node buys you independent chain access, not income.

Run your own node — or use an API?

An honest comparison, since Chaingateway sells the alternative.

Run the node when you consume raw JSON-RPC at heavy, sustained volume — indexing, backtesting, log scanning across millions of blocks — or when no third party may sit between you and the chain. A dedicated server is a fixed cost with unlimited requests, and past a certain call volume it beats every metered plan. The break-even arrives faster on BSC than on most chains precisely because the hardware bar is high but flat.

Use an API when the node would only be plumbing for payments. A synced BSC full node hands you eth_sendRawTransaction and logs; everything a payment system actually needs — deposit addresses per customer, detection of incoming BEP-20 transfers, signed webhooks, key storage, retries — is software you would build on top and keep running. Those engineering hours, at the rates from the cost section, dwarf the server bill.

Chaingateway’s BNB Smart Chain API covers that layer as REST: import addresses (POST /api/v2/bsc/addresses/import), send BEP-20 tokens (POST /api/v2/bsc/transactions/bep20), and receive HMAC-signed deposit webhooks — GET /api/v2/bsc/webhooks/notifications/failed lists failed deliveries, and each one can be resent via the retry endpoint. The break-even in one line: dedicated server + your build-and-operate hours versus a plan on /pricing/. For payment flows the API stays cheaper until well past small-business scale; for raw RPC firepower the node wins early. The quickstart and webhook guide get you to a first test in minutes, and the 7-day trial needs no KYC (register).

Also running other chains? See the setup guides for Ethereum and TRON.

C
Chaingateway Team
Blockchain Experts

The Chaingateway team is dedicated to simplifying blockchain integration for developers worldwide.