All articles
Infrastructure·February 8, 2026·6 min read

Yellowstone gRPC Geyser Plugin: Complete Setup Tutorial

Step-by-step guide to compiling, deploying, and subscribing to Yellowstone's gRPC geyser plugin on a Solana validator or RPC node. Covers TLS config, slot update filters, and account change subscriptions for sub-millisecond feed delivery.

If you're building anything latency-sensitive on Solana — a sniper, a copytrading engine, an MEV searcher — you have already hit the wall of polling RPC endpoints. The Yellowstone gRPC Geyser Plugin solves this by streaming account changes, slot updates, and transaction notifications directly from a validator's internal pipeline, before they ever touch the JSON-RPC layer. This tutorial walks through a production setup from zero: compiling the plugin, configuring the validator, locking down the TLS endpoint, and writing the subscription client.

What Yellowstone Actually Is

Yellowstone is a Solana Geyser plugin maintained by Triton One. Geyser is Solana's plugin interface that lets external code hook into the validator's account and transaction notification pipeline. Where the standard websocket accountSubscribe goes through a full JSON-RPC stack, a Geyser plugin receives updates inside the validator process and pushes them out directly.

Yellowstone exposes that feed over gRPC (HTTP/2 with Protocol Buffers), which means:

  • Multiplexed streams — one persistent connection handles account, slot, block, and transaction filters simultaneously.
  • Binary encoding — no JSON parsing overhead; base58 account data arrives as raw bytes.
  • Backpressure control — the client can signal flow control; the server won't flood you into a dropped connection.

The end result is that a well-placed node can deliver account change notifications in the 2–10 ms range from slot confirmation. Compare that to 50–200 ms on a public RPC websocket under load.

Compiling and Installing the Plugin

Yellowstone ships as a Rust .so that you load into agave-validator (the current Anza fork of solana-validator). Pin your build to the same Agave version running on your validator — a mismatch in the solana-sdk ABI will crash on load.

# Check your validator version first
agave-validator --version

# Clone and checkout the matching tag
git clone https://github.com/rpcpool/yellowstone-grpc.git
cd yellowstone-grpc
git checkout v2.x.y+solana.1.18.z   # match your validator

cargo build --release -p yellowstone-grpc-geyser

The output is target/release/libyellowstone_grpc_geyser.so. Copy it somewhere stable — /opt/yellowstone/ works — and set the file immutable until the next upgrade so a stray script doesn't overwrite it mid-run.

Validator Configuration

Add a --geyser-plugin-config flag to your validator startup command pointing at a JSON config file:

{
  "libpath": "/opt/yellowstone/libyellowstone_grpc_geyser.so",
  "grpc": {
    "address": "0.0.0.0:10000",
    "tls": {
      "cert": "/etc/ssl/yellowstone/server.crt",
      "key": "/etc/ssl/yellowstone/server.key"
    },
    "max_decoding_message_size": 67108864
  },
  "log": { "level": "info" },
  "accounts_selector": {
    "owners": ["11111111111111111111111111111111"]
  },
  "transactions_selector": { "vote": false, "failed": false }
}

A few notes on these values:

  • max_decoding_message_size — 64 MB is safe for most account data; bump to 128 MB if you're streaming large program accounts.
  • accounts_selector — the plugin pre-filters before serializing. Listing the program owner public keys here cuts CPU cost significantly; an empty selector streams everything and will saturate a 10 Gbit NIC during heavy activity.
  • transactions_selector.vote = false — vote transactions are 80 % of Solana's volume. Drop them unless you are building validator analytics.

Restart the validator and watch for [yellowstone_grpc_geyser] gRPC server started in the logs. The plugin binds before the validator finishes replaying, so the port is available almost immediately.

TLS Setup

Never expose port 10000 on the open internet without TLS — the gRPC stream carries raw account data and you do not want that unencrypted or open to anyone. Use Let's Encrypt with a DNS record pointing at the node, or a self-signed CA for private clients:

# Self-signed CA for internal bots (valid 10 years)
openssl req -x509 -newkey rsa:4096 -keyout ca.key -out ca.crt -days 3650 -nodes \
  -subj "/CN=yellowstone-ca"

openssl req -newkey rsa:4096 -keyout server.key -out server.csr -nodes \
  -subj "/CN=your-node.example.com"

openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key \
  -CAcreateserial -out server.crt -days 3650

Ship ca.crt to your client machines. On the client, pass it as the TLS root certificate when constructing the channel — do not skip verification in production.

Writing the Subscription Client

The protobuf definitions live in the repo under yellowstone-grpc-proto/proto/. Generate client stubs for your language of choice (tonic for Rust, grpc-js for Node, grpcio for Python). A minimal Rust subscription that filters for all updates to a specific account looks like this:

use yellowstone_grpc_client::GeyserGrpcClient;
use yellowstone_grpc_proto::prelude::*;

let mut client = GeyserGrpcClient::build_from_shared(endpoint)
    .tls_config(channel_tls_config(ca_cert))?
    .connect()
    .await?;

let mut accounts: HashMap<String, SubscribeRequestFilterAccounts> = HashMap::new();
accounts.insert("my_filter".into(), SubscribeRequestFilterAccounts {
    account: vec!["<PUBKEY>".into()],
    owner: vec![],
    filters: vec![],
    ..Default::default()
});

let request = SubscribeRequest {
    accounts,
    slots: HashMap::from([("slots".into(), SubscribeRequestFilterSlots {
        filter_by_commitment: Some(CommitmentLevel::Processed as i32),
    })]),
    ..Default::default()
};

let (_, mut stream) = client.subscribe_with_request(Some(request)).await?;

while let Some(msg) = stream.next().await {
    match msg?.update_oneof {
        Some(UpdateOneof::Account(acc)) => { /* handle */ }
        Some(UpdateOneof::Slot(slot)) => { /* handle */ }
        _ => {}
    }
}

Commitment level matters: Processed gives you the fastest feed (one slot confirmation), Confirmed waits for 2/3 stake supermajority, Finalized waits ~32 slots. For a sniper or copytrader that needs to act before others, Processed is the right choice — just account for the fact that a small number of processed slots get rolled back.

Slot Filters and Reconnection

Slot update messages come in several sub-types: FirstShredReceived, Completed, CreatedBank, Frozen, and Dead. For timing-sensitive work, FirstShredReceived is the earliest signal that a slot is being processed — useful for pre-warming caches. Frozen is what you want for "slot is done, act now."

Implement reconnection with exponential backoff capped at 5 seconds. The validator plugin does not buffer during disconnects; you will miss updates while reconnected. For production copytrading bots like the ones we build at TierZero (see our Solana services), we maintain two parallel connections to geographically separated nodes and reconcile on slot number — the first valid update wins, duplicate slot updates are dropped.

Trade-offs Versus Helius / Triton Hosted Geyser

Running your own node with Yellowstone costs roughly $400–800/month in bare-metal hosting (128 GB RAM, NVMe RAID, 10 Gbit uplink). Triton's hosted geyser.rpcpool.com and Helius's Atlas stream are cheaper to start but add 5–20 ms of network RTT because they are not colocated with your execution path. If you are running transactions through a private Jito relayer co-located on Latitude or Equinix, self-hosting Yellowstone on the same rack cuts end-to-end latency to the bone. If you are still prototyping, use the hosted options and migrate later.

The other operational consideration is plugin version pinning. Every Agave release potentially requires a matching Yellowstone build. Budget 30–60 minutes per validator upgrade for the recompile and test cycle. Automating this with a CI pipeline that watches Agave release tags is worth the setup time on any production system.


If you need a Geyser-powered data pipeline wired directly into a sniper, copytrader, or MEV searcher, get in touch — we've shipped these stacks in production and can cut your time-to-live significantly.

Need a bot like this built?

We design, build and run trading bots on Solana, Hyperliquid and Polymarket.

Start a project
#Infrastructure#Solana#gRPC#Geyser#Yellowstone#RPC#Low Latency