What is Solana gRPC?
Yellowstone gRPC is the streaming protocol the Solana ecosystem has converged on for real-time blockchain data. It ships as a Geyser plugin on validators, exposing account, transaction, slot, and block updates over a bidirectional gRPC stream. Payloads are protobuf-encoded, subscriptions are server-side filtered, and the connection is bidirectional with explicit flow control.
If you are building a trading bot, an indexer, a wallet, or a block explorer — and you need to see what's happening on Solana as it happens — Yellowstone gRPC is what you use. Standard JSON-RPC and WebSocket pubsub still work, but they are strictly slower and strictly less efficient at scale.
gRPC vs WebSocket vs RPC polling
| Aspect | HTTP RPC polling | WebSocket pubsub | Yellowstone gRPC |
|---|---|---|---|
| Delivery model | Pull (request/response) | Push (per-account subscribe) | Push (filter-based subscribe) |
| Wire format | JSON | JSON | Protobuf (binary) |
| Filter granularity | None (client polls) | Per-account subscribe | Complex server-side filters |
| Flow control | N/A | TCP-level only | Built-in gRPC flow control |
| Typical latency | Poll cadence + 20–200ms | 50–250ms after block | 0–100ms after block |
| Best for | Occasional lookups, batch analytics | Low-volume wallet/UI updates | MEV, indexing, HFT, orderbooks |
What you can subscribe to
The Yellowstone protobuf surface exposes seven subscription types:
subscribeAccounts— account data changes by owner program, address, or lamport filtersubscribeTransactions— transactions filtered by account, by program, with or without votes, with or without failedsubscribeBlocks— full blocks with optional transaction payloadsubscribeBlockMeta— lightweight block headers onlysubscribeSlots— slot status (processed / confirmed / finalized / first-shred-received)subscribeEntry— individual entries (shred groups) as they assemble into a blockping— bidirectional keepalive
Filters combine with logical AND semantics. A subscription like "all successful transactions touching program X and account Y, with account updates for Y" is a single stream, not two.
Quick start — TypeScript
Minimal working subscription that streams new raw transactions touching the pump.fun program:
import Client, {
CommitmentLevel,
SubscribeRequest,
} from "@triton-one/yellowstone-grpc";
const client = new Client(
"https://grpc.allenhark.com",
"YOUR_API_TOKEN",
{ "grpc.max_receive_message_length": 64 * 1024 * 1024 }
);
const req: SubscribeRequest = {
accounts: {},
slots: {},
transactions: {
pumpfun: {
accountInclude: ["6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P"],
accountExclude: [],
accountRequired: [],
vote: false,
failed: false,
},
},
blocks: {},
blocksMeta: {},
entry: {},
accountsDataSlice: [],
commitment: CommitmentLevel.PROCESSED,
};
const stream = await client.subscribe();
stream.on("data", (data) => console.log(data.transaction));
stream.write(req);Quick start — Rust
use yellowstone_grpc_client::GeyserGrpcClient;
use yellowstone_grpc_proto::prelude::*;
let mut client = GeyserGrpcClient::build_from_shared("https://grpc.allenhark.com")?
.x_token(Some("YOUR_API_TOKEN"))?
.connect()
.await?;
let (mut tx, mut rx) = client.subscribe().await?;
tx.send(SubscribeRequest {
transactions: [("pumpfun".into(), SubscribeRequestFilterTransactions {
account_include: vec!["6EF8...".into()],
vote: Some(false),
failed: Some(false),
..Default::default()
})].into_iter().collect(),
commitment: Some(CommitmentLevel::Processed as i32),
..Default::default()
}).await?;
while let Some(update) = rx.next().await {
println!("{:?}", update?);
}Who provides Yellowstone gRPC?
Every serious Solana infrastructure vendor now offers a gRPC endpoint. Pick on geographic proximity to your workload, filter-quality (many providers leak extra data through loose filters), and billing model:
- Helius — strong developer docs, per-connection pricing, multi-region
- Triton One — project of record for the Yellowstone plugin itself
- QuickNode — multi-chain, broader feature set, higher entry pricing
- Chainstack — enterprise-focused, SLA-backed
- Shyft — data-platform-first, gRPC alongside indexed APIs
- AllenHark — Slipstream bundles gRPC with transaction submission and runs from Frankfurt, Amsterdam, Chicago, and beyond — useful when your bot both reads and writes the chain from the same process
Latency optimizations
Four levers to pull in order of impact:
- Co-locate the consumer near the gRPC endpoint. Frankfurt sits at the center of the European Solana validator set — 0-3ms RTT to most EU leaders. AllenHark co-location in Frankfurt is the cleanest way to remove hops.
- Tune server-side filters. Every byte the server sends you is a byte of backpressure risk. Most slow gRPC clients are slow because they asked for everything.
- Use
commitment: processedwhen you can tolerate microscopic rollback risk. You save 400ms overconfirmedand ~10s overfinalized. - Go one layer lower with shred streams. Yellowstone gRPC is still block-boundary limited — you see data after the validator assembles the block. ShredStream surfaces data as shreds arrive, which is the absolute floor for Solana latency.
When not to use gRPC
Counter to common advice: don't default to gRPC for every workload. If you are running a batch indexer that catches up overnight, RPC getSignaturesForAddress is simpler and cheaper. If you are building a wallet that shows a balance, WebSocket pubsub is fine. gRPC's value scales with real-time requirements and subscribed-entity count. A bot that watches 20,000 accounts and must react within one slot — that is the gRPC sweet spot.
Further reading
- AllenHark Slipstream — gRPC transaction submission, four protocols, four regions
- ShredStream — the layer below gRPC, for sub-block latency
- Docs: AllenHark gRPC endpoints
- Blog: The fastest way to land Solana transactions in 2026