How to Run Your Own Solana RPC Node

A Solana RPC node is the same software as a validator — the Agave validator(the Anza-maintained client) — run in a non-voting mode with the full RPC API enabled. It gives you a private, high-throughput endpoint with no rate limits. Be warned up front: this is the most demanding node in crypto to operate— hundreds of gigabytes of RAM, two NVMe drives, and near-constant maintenance. This guide is the honest, accurate setup on Ubuntu 24.04; read the cost section at the bottom before you commit.

Hardware requirements

Solana’s requirements are in a different league from an Ethereum or Bitcoin node. An RPC node needs more than a voting validator, and the two big non-negotiables are a lot of ECC RAM and two separate high-endurance NVMe drives — accounts and ledger must not share a disk, or IOPS contention will make the node fall behind.

ResourceRPC node (minimum)Notes
CPU16 cores / 32 threadsAMD Gen 3+ / Intel Ice Lake+, 2.8 GHz+, SHA extensions. Clock speed > core count.
RAM256 GB (ECC)512 GB if you enable all account indexes. ECC required.
Accounts disk1 TB+ NVMe, high TBWSeparate physical drive.
Ledger disk1 TB+ NVMe, high TBWSeparate physical drive from accounts.
OS disk500 GB (SATA OK)Can also hold snapshots (500 GB+).
Network1 Gbit/s symmetric, public IPv4UDP + TCP 8000–8020 open. Solana is UDP-heavy.

The high-TBW requirement is easy to overlook and expensive to ignore: Solana writes constantly, so consumer SSDs wear out in months. Use enterprise/data-center NVMe rated for heavy sustained writes.

Step 1 — System tuning (do this first, or it won’t sync)

Solana relies on large UDP buffers and a huge number of memory-mapped files. On a stock kernel the node simply can’t keep up. Apply the sysctl and file-descriptor limits before starting:

# /etc/sysctl.d/21-agave-validator.conf
sudo tee /etc/sysctl.d/21-agave-validator.conf >/dev/null <<'EOF'
# Increase UDP buffer sizes
net.core.rmem_default = 134217728
net.core.rmem_max = 134217728
net.core.wmem_default = 134217728
net.core.wmem_max = 134217728
# Increase memory-mapped files limit
vm.max_map_count = 1000000
# Increase number of allowed open file descriptors
fs.nr_open = 1000000
EOF
sudo sysctl -p /etc/sysctl.d/21-agave-validator.conf

# Raise the open-files limit for the service user
sudo tee /etc/security/limits.d/90-solana-nofiles.conf >/dev/null <<'EOF'
sol soft nofile 1000000
sol hard nofile 1000000
EOF

# Pin the CPU governor to performance
sudo apt-get install -y linux-tools-common
sudo cpupower frequency-set --governor performance

Step 2 — Dedicated user and the Agave CLI

Run the node as an unprivileged sol user, and install the Agave toolchain (which includes agave-validator, solana, and solana-keygen) for that user:

sudo adduser --disabled-login --gecos "" sol
sudo -iu sol

# Install the Agave release (adds ~/.local/share/solana/install/active_release/bin to PATH)
sh -c "$(curl -sSfL https://release.anza.xyz/stable/install)"
export PATH="$HOME/.local/share/solana/install/active_release/bin:$PATH"
agave-validator --version

# An RPC node is still a validator process, so it needs an identity keypair
# (non-voting — it will not stake or vote, but the process requires an identity)
solana-keygen new -o /home/sol/validator-keypair.json

Step 3 — Mount the two data disks

Mount your two NVMe drives and give sol ownership. Accounts and ledger go on different physical disks:

sudo mkdir -p /mnt/accounts /mnt/ledger
# (format + add to /etc/fstab as appropriate for your drives, e.g. ext4)
sudo chown -R sol:sol /mnt/accounts /mnt/ledger

Step 4 — systemd service

The startup command is where an RPC node differs from a validator: --no-voting(don’t participate in consensus), --full-rpc-api (serve every RPC method), --private-rpcand a localhost bind (so the port isn’t gossiped publicly — front it with your own proxy/firewall), and the --known-validatorset for trusted snapshot download. Create /etc/systemd/system/sol.service:

[Unit]
Description=Solana RPC Node (Agave)
After=network-online.target
Wants=network-online.target

[Service]
User=sol
LimitNOFILE=1000000
Environment=PATH=/home/sol/.local/share/solana/install/active_release/bin:/usr/bin:/bin
ExecStart=/home/sol/.local/share/solana/install/active_release/bin/agave-validator \
  --identity /home/sol/validator-keypair.json \
  --no-voting \
  --full-rpc-api \
  --private-rpc \
  --rpc-port 8899 \
  --rpc-bind-address 127.0.0.1 \
  --dynamic-port-range 8000-8020 \
  --ledger /mnt/ledger \
  --accounts /mnt/accounts \
  --log /home/sol/agave-validator.log \
  --entrypoint entrypoint.mainnet-beta.solana.com:8001 \
  --entrypoint entrypoint2.mainnet-beta.solana.com:8001 \
  --entrypoint entrypoint3.mainnet-beta.solana.com:8001 \
  --entrypoint entrypoint4.mainnet-beta.solana.com:8001 \
  --entrypoint entrypoint5.mainnet-beta.solana.com:8001 \
  --expected-genesis-hash 5eykt4UsFv8P8NJdTREpY1vzqKqZKvdpKuc147dw2N9d \
  --known-validator 7Np41oeYqPefeNQEHSv1UDhYrehxin3NStELsSKCT4K2 \
  --known-validator GdnSyH3YtwcxFvQrVVJMm1JhTS4QVX7MFsX56uJLUfiZ \
  --known-validator DE1bawNcRJB9rVm3buyMVfr8mBEoyyu73NBovf2oXJsJ \
  --known-validator CakcnaRDHka2gXyfbEd2d3xsvkJkqsLw2akB3zsN1D2S \
  --only-known-rpc \
  --wal-recovery-mode skip_any_corrupted_record \
  --limit-ledger-size
Restart=always
RestartSec=5

[Install]
WantedBy=multi-user.target

Want indexed lookups by token owner/mint (needed by many apps calling getProgramAccounts)? Add --account-index program-id spl-token-owner spl-token-mint— but that’s the flag that pushes you to 512 GB of RAM. Leave it off if you don’t need it.

Step 5 — Start and verify

On first start the node fetches a recent snapshot from the known validators (hundreds of GB) and then catches up to the tip. Start it and watch it converge:

sudo systemctl daemon-reload
sudo systemctl enable --now sol

# How far behind the cluster are we? (run as the sol user)
solana catchup --our-localhost

# Is the RPC healthy?
curl http://localhost:8899 -s -X POST -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":1,"method":"getHealth"}'
# -> {"jsonrpc":"2.0","result":"ok","id":1}

# Current slot
curl http://localhost:8899 -s -X POST -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":1,"method":"getSlot"}'

Once getHealth returns ok and solana catchup shows you at the tip, the node is serving. Keep 127.0.0.1as the bind address and put a reverse proxy / firewall in front before exposing it — an open Solana RPC port is a well-known abuse target.

The honest part: what running it actually costs

Of every chain we serve, Solana is the one where self-hosting is the hardest to justify:

  • Hardware is genuinely expensive. 256–512 GB of ECC RAM plus two high-endurance NVMe drives and a 16-core CPU is a $500–$1,500+/month bare-metal machine (or a large upfront buy) — before redundancy.
  • Maintenance is near-constant. Agave ships frequent releases, sometimes with urgent, coordinated network upgrades and restarts that require an operator to be awake and acting. This isn’t a set-and-forget node.
  • SSD wear is real. The constant write load burns through consumer drives; enterprise NVMe is a recurring cost, not a one-time one.
  • One node is a single point of failure. Any serious use needs at least two — doubling all of the above — plus a load balancer.
  • See the full breakdown in Self-Hosted Node vs RPC Provider and the full vs archive node trade-offs.

…or skip all of it

SwiftNodes runs load-balanced Solananodes for you — flat-rate pricing (no per-call compute units), HTTP + WebSocket, no KYC — alongside 75+ other chains under one API key. No 512 GB machines, no 3 a.m. network restarts.

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