Every Solana RPC provider says they are fast. Almost none of them show you a live number, and none that we know of show you the number when it is bad. Our benchmarks page streams the real latency of the same nodes that serve customer traffic, wins and losses alike. This post explains exactly how those numbers are produced, and a couple of things we got wrong along the way.
What the probe actually does
Each site — New York and Frankfurt — runs a small probe process that fires real JSON-RPC calls at the node roughly every five seconds: getSlot, getLatestBlockhash, getAccountInfo, getBalance, getMultipleAccounts, getTransaction, getTokenAccountsByOwner and getSignaturesForAddress. The calls hit the same process, over the same path, that customer requests take. Wall-clock latency for every sample lands in Prometheus, and the page shows the rolling five-minute median.
The queries are not softballs. getTokenAccountsByOwner runs against an exchange hot wallet with a mint filter, and getTransaction chains off the oldest signature returned by the getSignaturesForAddress probe, so the node cannot serve the whole benchmark out of a warm cache.
Why p50 and not an average
Our first version showed a 60-second average. It looked terrible — not because the node was slow, but because an average over ~12 samples is fragile: one 100 ms outlier in an otherwise sub-millisecond window dominates the number and makes the display jump around. Real request latency on a busy box has a tail; that is physics, not marketing. The five-minute p50 answers the question a user actually has — “what latency does a typical request get right now?” — while a sustained degradation still moves the number and flips the status badge. We kept percentiles for the places where tails matter (more below).
getBlock is measured differently
getBlock is the one method we do not synthesize: the displayed value is the p50 of our getBlock-serving layer’s latency histogram over real production traffic. Synthetic getBlock probes mostly measure how big the requested block happened to be; the production histogram measures what customers actually experienced.
Racing other providers, honestly
For Yellowstone gRPC we run a continuous head-to-head: our gateway endpoint and a well-known alternative in the same region (PublicNode in New York, Corvus in Frankfurt) subscribe to the same transaction stream, and every transaction is scored by which connection delivered it first. We publish win rate, p50/p95/p99 delivery delay, and time-to-first-shred, updated every ten minutes — plus our measured network latency to the competitor’s endpoint, so you can judge whether the race is fair from our vantage point.
Some weeks we lose some of these races. The numbers stay up. A benchmark page that only renders when you are winning is an ad, not a benchmark.
The crawler problem
One wrinkle worth sharing: a page whose every value arrives via JavaScript is invisible to most crawlers — they see a table of dashes. The fix we shipped is a snapshot layer: the last-known values are stored server-side and rendered into the HTML with a timestamp, then your browser swaps in live values within seconds. If you are building a status or benchmark page of your own, it is worth doing; the “live” page you are proud of may be an empty skeleton to everyone who is not a human with JavaScript enabled.
Run your own numbers
The only benchmark that fully matters is one run from your own infrastructure against your own workload. Grab a key (there is a free tier), point your tooling at New York or Frankfurt, and compare. If you want the stream-level detail, see Kaldera, our Yellowstone gRPC service, or ShredPrism for raw shred delivery over gRPC.
