---
title: "Solana gRPC performance: a public benchmark methodology"
description: "How we measure Solana gRPC delivery latency across six regions, with p50, p90 and p99 results, the full test setup, and the exact commands to reproduce them."
---

# Solana gRPC performance: a public benchmark methodology

<ImageBlock
  src="https://media.alchemy.com/blog/solana-grpc-benchmark-methodology-hero.png"
  alt="Solana gRPC performance benchmark methodology"
  width={1920}
  height={900}
  priority
/>

Solana performance numbers are only as useful as the method behind them. A latency figure without a region, a time window, and a test setup can't be verified, compared, or reproduced.

This post documents how we measure our [Solana gRPC streams](https://www.alchemy.com/solana-grpc), publishes the numbers those measurements produce, and includes the full configuration to reproduce the test against any endpoint, including ours.

## Why publish the methodology at all?

A single latency figure says nothing about where the test ran, what it subscribed to, at what commitment level, or over what time window. On Solana those details decide the number: blocks arrive in under a second, and the margins between streaming endpoints are a few milliseconds wide. We already publish [the measurement rules behind our request benchmarks](https://www.alchemy.com/blog/how-we-benchmark-rpc-performance); this post does the same for Solana streaming.

Anyone can sanity-check a request benchmark by sending the same request. A stream is harder to interrogate. You can't replay a moment of chain activity to see whether your provider delivered it quickly, completely, and in order. A published method lets developers rerun the test against their own workload instead of trusting a party.

## What does the benchmark measure?

Streaming performance is three separate questions: when data arrives, whether all of it arrives, and what happens when the connection breaks. This benchmark answers the first one, per region.

- **Network round trip (p50).** The median TCP connect time from the runner to the endpoint, over 30 connections. It's mostly geography, so it tells you what your location costs before any data moves.
- **Delivery spread (p90, p99).** How many milliseconds later than the fastest delivery in the run a slow or worst-case message arrives. The tail is what your system feels at the worst moment. A liquidation monitor doesn't care that the typical update was fast if the one that mattered arrived late.

We report both per region, never as a single global average.

## How do you time a stream without trusting clocks?

Timing a request is easy. One machine sends it and receives the answer, so one clock covers the whole round trip.

A stream breaks that convenience. The event originates on a validator, passes through the provider's infrastructure, and lands in your subscriber process on a different machine in a different datacenter. Two clocks are now involved, and clocks on separate machines can disagree by several milliseconds even when both run NTP. Delivery margins between well-run endpoints can be smaller than that, which means naive timestamp math can end up measuring clock error instead of performance.

Our endpoint stamps every message with the time it was created, and the runner subtracts that stamp from the time the message arrives. That subtraction compares two clocks, so the runner checks its own clock against a public time server before and after each run. A small fixed error can still remain. Reporting each message relative to the fastest delivery in the run removes it, because a fixed clock error shifts every message by the same amount and cancels out in the subtraction. The round-trip column needs no correction, since the runner times each TCP connection on its own clock.

These numbers don't tell you the total time from the validator to your process, and they don't rank providers. Ranking needs a different test, two streams compared from the same machine, which the reproduce section covers.

Two details keep the measurement honest. The commitment level is pinned to `processed`, the earliest confirmation level, because mixing commitment levels means measuring different points in an event's life. And the chain's own block timestamps stay out of the math entirely. Solana produces blocks in [under a second](https://www.alchemy.com/blog/zero-downtime-zero-gaps-solana-grpc-streaming), while block timestamps only resolve to the second, so they are too coarse to see millisecond margins.

## What does a test run look like?

Every figure in this post comes from a run with the following shape. When the setup changes, we republish the numbers under a new date rather than editing them in place.

- **Stream under test:** a single Yellowstone-compatible gRPC transaction stream per run.
- **Watched account:** PumpSwap, Pump's AMM program, `pAMMBay6oceH9fJKBRHGP5D4bD4sWpmSwMn52FMfXEA`, chosen for its high transaction volume.
- **Commitment level:** `processed` for every run.
- **Sample size:** 20,000 transactions per region.
- **Vantage points:** runners on [Fly](https://fly.io/) machines in six client regions: US East, US West, EU West, EU Central, Singapore, and Tokyo. Each runner's round trip to the endpoint is part of its results, because a benchmark run from a coffee shop measures the coffee shop.
- **Client:** the Rust `latency` example in geyserbench with default client settings over TLS, shown in the reproduce section below.
- **Time window:** October 14 to 16, 2026. Every published table carries the dates of the run that produced it.

## What are the results?

Delivery behavior of our Solana gRPC stream, measured from a client in each region. Each row is 20,000 transactions on a single stream at processed commitment, run October 14 to 16, 2026:

<EmbeddedTable
  table={{
    columns: [
      { key: "region", width: 220, title: "Region", dataType: "object" },
      { key: "p50", width: 120, title: "p50", dataType: "object" },
      { key: "p90", width: 120, title: "p90", dataType: "object" },
      { key: "p99", width: 120, title: "p99", dataType: "object" },
    ],
    data: [
      {
        region: { title: "US East", tooltip: "", icon: "" },
        p50: { title: "1.8 ms", tooltip: "", icon: "" },
        p90: { title: "+13.1 ms", tooltip: "", icon: "" },
        p99: { title: "+17.4 ms", tooltip: "", icon: "" },
        id: 0,
      },
      {
        region: { title: "US West", tooltip: "", icon: "" },
        p50: { title: "15.6 ms", tooltip: "", icon: "" },
        p90: { title: "+7.2 ms", tooltip: "", icon: "" },
        p99: { title: "+12.2 ms", tooltip: "", icon: "" },
        id: 1,
      },
      {
        region: { title: "EU West", tooltip: "", icon: "" },
        p50: { title: "21.9 ms", tooltip: "", icon: "" },
        p90: { title: "+3.5 ms", tooltip: "", icon: "" },
        p99: { title: "+14.3 ms", tooltip: "", icon: "" },
        id: 2,
      },
      {
        region: { title: "EU Central", tooltip: "", icon: "" },
        p50: { title: "5.2 ms", tooltip: "", icon: "" },
        p90: { title: "+2.4 ms", tooltip: "", icon: "" },
        p99: { title: "+6.8 ms", tooltip: "", icon: "" },
        id: 3,
      },
      {
        region: { title: "Asia-Pacific, Singapore", tooltip: "", icon: "" },
        p50: { title: "4.3 ms", tooltip: "", icon: "" },
        p90: { title: "+8.5 ms", tooltip: "", icon: "" },
        p99: { title: "+11.7 ms", tooltip: "", icon: "" },
        id: 4,
      },
      {
        region: { title: "Asia-Pacific, Tokyo", tooltip: "", icon: "" },
        p50: { title: "3.3 ms", tooltip: "", icon: "" },
        p90: { title: "+9.2 ms", tooltip: "", icon: "" },
        p99: { title: "+23.6 ms", tooltip: "", icon: "" },
        id: 5,
      },
    ],
  }}
/>

The p50 column is the median network round trip from the runner to the endpoint. The p90 and p99 columns show how many milliseconds later than the fastest delivery in that run a slow or worst-case message arrives.

Read the p50 as the distance cost of your location and the p90 and p99 as how steady delivery is. Neither is total end-to-end latency from the validator. The right way to size your own expectations is the row for your region: Frankfurt developers should read the EU Central line, not a global average pulled toward whichever region tested fastest. When we [launched Solana gRPC](https://www.alchemy.com/blog/introducing-alchemy-solana-grpc) we published an early version of this claim (delivery 5 to 15ms faster on average than alternatives, measured from us-east-1). This table is the multi-region successor to that single-region, head-to-head snapshot, with a different and complementary metric.

## How do you reproduce this?

You need Rust and an Alchemy API key with access to Solana gRPC (the [quickstart](https://www.alchemy.com/docs/reference/yellowstone-grpc-quickstart) lists the prerequisites). Three commands:

<CodeSnippet
  language="bash"
  code={`git clone https://github.com/clinder777/geyserbench && cd geyserbench && git checkout 463cf8e0b70d5b84defb8092e17486eab13960ad
export ALCHEMY_API_KEY=your-alchemy-api-key
cargo run --release --example latency`}
/>

It opens one Solana gRPC stream, watches 20,000 transactions on a busy account at processed commitment, and prints the median network round trip to the endpoint, then how many milliseconds above the fastest delivery your p50, p90 and p99 messages arrive. Run it on a server in the region you care about and compare against the table above.

We used `pAMMBay6oceH9fJKBRHGP5D4bD4sWpmSwMn52FMfXEA`, PumpSwap, Pump's AMM program. It's a good choice because it's very high volume, so 20,000 transactions arrive quickly. To watch a different program or run a shorter test, set `ACCOUNT` to the program address and `N` to the number of transactions:

<CodeSnippet
  language="bash"
  code={`ACCOUNT=pAMMBay6oceH9fJKBRHGP5D4bD4sWpmSwMn52FMfXEA N=5000 cargo run --release --example latency`}
/>

To compare two providers rather than measure one, run both streams from the same machine and record which delivers each transaction first. The public [geyserbench](https://github.com/hmstudio-labs/geyserbench) does this from a single config file that lists both endpoints, and reports how often each one detects a transaction first.

If you run this and get materially different numbers from ours, tell us. Finding that out is why the method is public.

## What does this benchmark not measure?

Three things deliberately sit outside this benchmark:

- **Stream reliability.** This is a latency benchmark. It does not measure missed events, disconnects, reconnect time, or backfill after a reconnect, so it says nothing for or against those. If your application depends on gap-free delivery, test it directly. Our endpoints keep 48 hours of history (more than 400,000 slots) that a reconnecting client can replay from with `from_slot`.
- **Transaction landing.** Getting a transaction included in a block is a write-path problem with its own infrastructure and its own failure modes. Nothing here says anything about it.
- **Request/response reads.** Polling a JSON-RPC method is a different access pattern with different failure modes, and our [public RPC benchmark](https://www.alchemy.com/benchmarks) covers request traffic separately with its own published rules.

## Frequently asked questions

### How fast is Alchemy's Solana gRPC?

It depends on where you measure from, which is why Alchemy publishes per-region latency distributions rather than one global figure. The regional table above reports the network round trip and p90 and p99 delivery spread, produced by the published methodology on a stated date. The network round trip to the endpoint runs from 1.8 ms in US East to 21.9 ms in EU West, and p99 messages arrive within 6.8 to 23.6 ms of the fastest delivery, depending on region.

### How is Solana gRPC latency measured?

A client in each region opens one gRPC stream at `processed` commitment, watches 20,000 transactions on a high-volume program, and compares each message's arrival time with the time our endpoint created it. Results are reported per region as the p90 and p99 delay above the fastest delivery in the run, alongside the median network round trip from the client to the endpoint.

### Can I reproduce Alchemy's Solana gRPC benchmarks?

Yes. The test runs from the `latency` example in geyserbench, and the exact commands are published in this post. Run it on a server in your serving region, at `processed` commitment, and compare your percentiles against the regional table. To compare two providers, geyserbench can also run both endpoints side by side from the same machine.

### What commitment level do the benchmarks use?

Every run subscribes at `processed`, Solana's earliest commitment level. Mixing commitment levels would measure events at different points in their lifecycle, which makes the percentiles meaningless. Your production application may prefer `confirmed` or `finalized`; the methodology holds commitment constant so the numbers stay comparable across regions and runs.

### Is this a comparison against other providers?

No. This post documents how Alchemy measures and publishes its own Solana gRPC performance. Other providers publish their own benchmarks, and more published methodology in this category is good for everyone. The reproduction section exists so you can run the comparison that matters, on your workload, yourself.

## Start streaming Solana data

Our [Solana gRPC streaming](https://www.alchemy.com/solana-grpc) is Yellowstone-compatible, so pointing an existing client at it is a URL change, not a rewrite. Pricing is $75 per TB with no monthly minimum, and the [Yellowstone gRPC docs](https://www.alchemy.com/docs/reference/yellowstone-grpc-overview) cover the quickstart. Teams building on Solana can also apply for up to $25k in credits through the [$20M Solana Fund](https://www.alchemy.com/solana-20m-fund). Run the benchmark first if you like. That's what it's for.
