> For the complete documentation index, see [llms.txt](https://docs.triton.one/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.triton.one/solana/quickstart/streaming/benchmark-grpc-endpoints-with-thorofare.md).

# Benchmark gRPC endpoints with Thorofare

Compare two Yellowstone gRPC endpoints side by side with Triton's open-source Thorofare tool.

[Thorofare](https://github.com/rpcpool/yellowstone-thorofare) is Triton's open-source tool for benchmarking Solana Geyser gRPC (Yellowstone gRPC) endpoints. It connects to two endpoints at the same time, subscribes to the same data on both, and reports which one delivered each update first, and by how much. Running both streams from one machine at once removes the network and timing differences that make single-endpoint numbers hard to compare.

For the methodology behind it, see the [How to benchmark Solana RPC endpoints](https://blog.triton.one/how-to-benchmark-solana-rpc-endpoints/) blog post.

## What Thorofare measures

* **Slot stages**: when each endpoint reports each of the six slot statuses: first shred received, bank created, completed, processed, confirmed, and finalized.
* **Download and replay time**: download runs from first shred received to completed, replay from bank created to processed.
* **Account update propagation** (optional): for accounts owned by a program you choose, how much later one endpoint delivers the same write than the other.
* **Transaction propagation** (optional): the same comparison for non-vote transactions.
* **Ping latency** to both endpoints.

Subscriptions use `processed` commitment. Every metric is reported as P50, P90, and P99.

## When to run it

* Choosing between gRPC endpoints or providers: run both through the same benchmark, from the same machine.
* Checking a region or endpoint change against the endpoint you use today.
* Seeing which endpoint delivers slots, accounts, and transactions first, and by how much, when both run from the same machine.

## Run a benchmark

Download the prebuilt Linux binary for Ubuntu 22.04 or Ubuntu 24.04 from the [Thorofare releases page](https://github.com/rpcpool/yellowstone-thorofare/releases). The release files are named after the OS (for example `yellowstone-thorofare-ubuntu-24.04`), so make the file executable and rename it to `thorofare` to match the commands below. Or build it from source:

```bash
git clone https://github.com/rpcpool/yellowstone-thorofare.git
cd yellowstone-thorofare
cargo build --release
# The binary is target/release/thorofare
```

Pass both endpoints as full URLs, including `https://`; a bare `host:port` fails with a gRPC transport error. Each endpoint takes its own token:

```bash
thorofare \
  --endpoint1 https://<your-endpoint>.mainnet.rpcpool.com \
  --x-token1 <your-token> \
  --endpoint2 https://<other-endpoint> \
  --x-token2 <other-token> \
  --slots 1000
```

To also compare account and transaction propagation, add the optional flags. `--with-accounts` and `--account-owner` must be used together:

```bash
thorofare \
  --endpoint1 https://<your-endpoint>.mainnet.rpcpool.com --x-token1 <your-token> \
  --endpoint2 https://<other-endpoint> --x-token2 <other-token> \
  --with-accounts --account-owner 675kPX9MHTjS2zt1qfr1NYHuzeLXfQM9H24wFSUt1Mp8 \
  --with-transactions
```

| Flag                                       | Default                  | What it does                                                                  |
| ------------------------------------------ | ------------------------ | ----------------------------------------------------------------------------- |
| `--endpoint1`, `--endpoint2`               | required                 | The two gRPC endpoints to compare.                                            |
| `--x-token1`, `--x-token2`                 | none                     | Token for each endpoint, sent as `x-token`.                                   |
| `--slots`                                  | `1000`                   | Number of slots to collect.                                                   |
| `--with-accounts`, `--account-owner <id>`  | off                      | Compare account writes for accounts owned by this program. Use both together. |
| `--with-transactions`                      | off                      | Compare non-vote transactions.                                                |
| `--endpoint1-richat`, `--endpoint2-richat` | off                      | Use the Richat interface for that endpoint instead of Yellowstone gRPC.       |
| `--config`                                 | `config.toml`            | gRPC client tuning. Built-in defaults apply when the file is missing.         |
| `--output`                                 | `benchmark_results.json` | Where to write the results.                                                   |
| `--log-level`                              | `info`                   | Log verbosity.                                                                |

{% hint style="info" %}
Thorofare runs on your machine. Run it from a backend close to where your real production traffic originates; benchmarking from a different region distorts every result.
{% endhint %}

## Read the results

Thorofare writes a JSON report with slot timing comparisons, P50, P90, and P99 for every metric, win and loss counts for account and transaction updates, and ping latencies. Delay metrics count a win as 0 ms, so the percentiles cover every update: a P50 of 0 means that endpoint was faster more than half the time.

To chart a report, load the JSON file into the [Thorofare visualizer](https://thorofare.triton.one/). It shows a timeline of the slot stages, per-update account delays, and the percentile distributions.

## Common pitfalls

* **Comparing separate runs.** Results from different machines or times aren't comparable. Put both endpoints in one run.
* **A quiet program for account tracking.** `--with-accounts` only sees writes to accounts owned by `--account-owner`. A program with few writes gives few samples.
* **Untuned gRPC settings for heavy subscriptions.** `--config` takes a TOML file like `config-example.toml` in the repository. Keep `tcp_nodelay = true`, and raise `initial_connection_window_size` when you track accounts or transactions.

## What's next

<table data-card-size="large" data-view="cards"><thead><tr><th></th><th></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td><i class="fa-gauge">:gauge:</i> <strong>Rate and connection limits</strong></td><td>Per-endpoint and method rate limits, plus streaming connection caps.</td><td><a href="/using-your-endpoint/rate-and-connection-limits.md">Rate and connection limits</a></td></tr><tr><td><i class="fa-compass">:compass:</i> <strong>Streaming overview</strong></td><td>Compare every Triton streaming service and choose the right fit for your workload.</td><td><a href="/solana/real-time-streaming.md">Real-time streaming</a></td></tr><tr><td><i class="fa-lock">:lock:</i> <strong>Auth and security</strong></td><td>Authenticate requests and lock your endpoint to trusted origins.</td><td><a href="/security/authentication.md">Auth and security</a></td></tr><tr><td><i class="fa-book">:book:</i> <strong>Thorofare blog post</strong></td><td>Why most gRPC benchmarks are wrong, and how to do them right.</td><td><a href="https://blog.triton.one/how-to-benchmark-solana-rpc-endpoints/">https://blog.triton.one/how-to-benchmark-solana-rpc-endpoints/</a></td></tr></tbody></table>

***

<i class="fa-life-ring">:life-ring:</i> Contact support by clicking the chat icon in your [customer dashboard](https://customers.triton.one)\ <i class="fa-briefcase">:briefcase:</i> Sales questions? [Contact us](https://triton.one/contact)\ <i class="fa-sparkles">:sparkles:</i> AI agent? Read [llms.txt](https://docs.triton.one/llms.txt)\ <i class="fa-rss">:rss:</i> Follow updates: [Blog](https://blog.triton.one) · [X](https://x.com/triton_one) · [YouTube](https://www.youtube.com/@triton_one_ltd) · [Telegram](https://t.me/tritonone) · [GitHub](https://github.com/rpcpool)
