Open-source, vendor-neutral benchmark for EVM RPC providers. Measure median, p95, success rate, and error patterns of any provider you want to compare — head-to-head, across multiple chains.
Zero SDK dependencies. Single fetch-based core. Run in 30 seconds with no installation:
npx rpc-benchmark-tool --chain ethOr clone for repeatable benchmarking with your own provider mix:
git clone https://github.com/swiftnodes/rpc-benchmark-tool
cd rpc-benchmark-tool
cp .env.example .env
npm install
npm startSample output:
=== Ethereum ===
Provider median mean p95 min max success block
SwiftNodes 42 49 102 38 115 10/10 22512303
Alchemy 57 63 118 49 143 10/10 22512303
dRPC 89 95 188 72 211 10/10 22512303
PublicNode 124 141 287 102 352 10/10 22512303
Infura 188 201 342 167 402 9/10 22512303
Ankr 221 287 1422 143 1503 8/10 22512303
=== Base ===
...
- ✅ No SDK dependencies — uses native
fetch. Works on any Node 18+. - ✅ Pre-configured providers: SwiftNodes, Alchemy, Infura, QuickNode, dRPC, Ankr, PublicNode
- ✅ Multiple chains: Ethereum, Base, Arbitrum, Polygon (extensible)
- ✅ Comprehensive metrics: median, mean, p95, min, max, success rate
- ✅ Configurable samples (default 10) and gap between requests
- ✅ Filter by chain or provider on the CLI
- ✅ JSON output for piping into dashboards or CI
- ✅ Per-chain block-height comparison — quickly catch lagging nodes
- ✅ Detects timeouts vs HTTP errors vs JSON-RPC errors separately
cp .env.example .envEdit .env:
SWIFTNODES_API_KEY=sn_...
ALCHEMY_API_KEY=...
INFURA_API_KEY=...
QUICKNODE_URL_ETH=https://your-name.quiknode.pro/...Providers without configured keys are automatically skipped (the tool prints which ones).
# Default: all configured providers
npm start
# Filter by chain
npm start -- --chain eth
npm start -- --chain base
# Filter by provider
npm start -- --provider SwiftNodes,Alchemy
# More samples for tighter stats
npm start -- --runs 50
# JSON output
npm start -- --json > results.jsonEdit src/providers.js:
export const PROVIDERS = [
// ... existing ...
// Add a custom provider:
{ provider: "MyEnterpriseRPC", chain: "Ethereum", chainKey: "eth", url: "https://rpc.my-enterprise.io/v1/eth?token=ABC" },
// Add a chain not yet listed:
{ provider: "SwiftNodes", chain: "Linea", chainKey: "linea", url: `https://rpc.swiftnodes.io/rpc/linea?key=${env("SWIFTNODES_API_KEY")}` },
];The tool treats each entry independently — add 50 if you want, they all run in parallel.
- median_ms: the 50th-percentile latency — the typical user experience
- mean_ms: average; sensitive to outliers
- p95_ms: the 95th-percentile latency — what's the slowest 5% of your requests
- min_ms / max_ms: fastest and slowest sample
- success rate: how many requests succeeded (vs timeouts, HTTP errors, JSON-RPC errors)
- sampleBlock: latest block returned by
eth_blockNumber— catches nodes that are syncing or lagging
- Throughput under load — this is a serial-latency benchmark, not a load test. For load, use
k6,wrk, orhey. - WebSocket performance — HTTP only.
- Geographic routing — runs from wherever your machine is. Use multiple regions for global view.
- Real workload mix — only
eth_blockNumberby default. For full-method coverage, extendDEFAULT_METHODSinsrc/bench.js.
RPC providers publish their own benchmarks. Of course they win.
Most third-party benchmarks are linked to a specific provider's marketing — hard to trust which numbers are honest.
This tool is:
- Open source (you can see what it measures and how)
- Vendor-neutral (we list SwiftNodes alongside Alchemy/Infura/etc. and let the numbers speak)
- Easy to reproduce (one command, transparent code)
- Auditable (no hidden weights, no clever sampling)
We built it because we wanted reliable numbers ourselves while operating SwiftNodes. Sharing it in case anyone else wants the same thing.
Add to a workflow to monitor your providers over time:
# .github/workflows/rpc-monitor.yml
on:
schedule: [{ cron: '0 */6 * * *' }] # every 6 hours
jobs:
bench:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with: { node-version: '20' }
- run: npm ci
- run: npm start -- --json > bench.json
env:
SWIFTNODES_API_KEY: ${{ secrets.SWIFTNODES_API_KEY }}
ALCHEMY_API_KEY: ${{ secrets.ALCHEMY_API_KEY }}
- uses: actions/upload-artifact@v4
with: { name: rpc-bench, path: bench.json }Run from multiple regions for geographically-distributed measurements.
MIT — fork, customize, share the numbers.
PRs welcome for:
- Additional providers in
src/providers.js - More chains
- Additional benchmark methods beyond
eth_blockNumber(egeth_call,getLogsare interesting comparisons) - Output formatters (CSV, Prometheus, etc.)