Reproducible benchmarks for RPC Plane — the Solana RPC proxy that sits between your app and your providers.
Run it yourself. Don't trust our numbers — clone this repo, point it at any RPC endpoint, and see for yourself. Every number below was produced by the
bench.shin this repo; the raw output is committed underresults/.
A client that opens a fresh connection per request pays the full TLS handshake to the remote provider every single time. Put RPC Plane in front and that same client pays it once — the proxy keeps a warm, pooled connection to the provider and reuses it.
| getHealth, same provider | Direct (naive client) | Via RPC Plane | |
|---|---|---|---|
| p50 latency | 888 ms | 296 ms | 3.0× faster |
| average | 894 ms | 304 ms | 2.9× faster |
| p99 latency | 998 ms | 360 ms | 2.8× faster |
| connection setup / request | 595 ms | 0.3 ms | — |
| success rate | 100% | 100% |
The ~590 ms gap is the TLS+TCP handshake. The naive client repays it on every request; the proxy amortizes it across all of them.
Run: 24 requests, concurrency 3, throttled to 2 QPS, against the public
api.mainnet-beta.solana.com from a single host. rpc-plane v0.9.0. See
disclaimer — this is intentionally the proxy's best case.
One scenario, two paths, the same naive client (--disable-keepalive, a new
connection per request) both times. The only thing that changes is whether RPC
Plane sits in front:
Direct: naive client ──new TLS handshake every request──▶ provider
Via proxy: naive client ──▶ RPC Plane ──warm pooled connection──▶ provider
We deliberately do not let the proxy path cheat with client-side keep-alive. Even reconnecting to the local proxy on every request, it wins — because the expensive hop (the TLS handshake to the remote provider) is paid once and reused, while the cheap hop (localhost) is all the naive client repeats.
# 1. Get the proxy (or build it / set RPC_PLANE_BIN to a local build)
curl -sSf https://rpcplane.dev/install.sh | sh
# 2. Get the load tool
cargo install oha
# 3. Run it. QPS=2 keeps the shared public endpoint happy.
QPS=2 REQUESTS=24 CONCURRENCY=3 ./bench.shAgainst your own provider (high rate limits), drop QPS and turn it up:
RPC_URL="https://mainnet.helius-rpc.com/?api-key=YOUR_KEY" \
REQUESTS=500 CONCURRENCY=20 ./bench.sh| Env var | Default | Meaning |
|---|---|---|
RPC_URL |
public mainnet-beta | The provider endpoint both paths hit |
REQUESTS |
200 | Requests per path |
CONCURRENCY |
8 | Concurrent connections |
QPS |
(unset) | Cap queries/sec — set for rate-limited public endpoints |
BODY |
getHealth |
JSON-RPC body to send |
RPC_PLANE_BIN |
auto-detected | Path to the rpc-plane binary |
Raw oha output lands in results/direct.txt and results/proxy.txt.
This is intentionally the proxy's best case, and the absolute numbers are network-dependent. Read this before quoting it.
- It models a client that doesn't reuse connections. That's extremely common — serverless/Lambda, per-request HTTP clients, many scripts and SDKs — but a client that maintains its own warm keep-alive pool to the provider pays the handshake once too. Against that client, RPC Plane's win shrinks to its raw overhead (sub-millisecond at the median). A fair "warm vs warm" overhead benchmark is the next one we'll publish here.
- Absolute latencies reflect the network path, not the proxy. These numbers are from one host to the public mainnet-beta endpoint (~300 ms round trip, ~590 ms fresh-connection handshake). Closer to a dedicated provider both numbers shrink — but the relative win scales with your round-trip time, because the thing being saved is one or two RTTs of handshake per request.
- Throttled to 2 QPS to be polite to a shared public endpoint. This is a per-request latency test, not a throughput test.
The point isn't "the proxy beats the network." It's "if your client doesn't pool connections, the proxy does it for you — for free, with no code changes."
MIT — see LICENSE.