Solana gRPC Streaming Guide: Yellowstone, Geyser & the Production Gotchas (2026)
How Solana gRPC streaming really works with Yellowstone Geyser — setup, subscription filters, and the connection-leak, memory, and reconnection gotchas we hit running a dual-region firehose in production. Written from a live pipeline, not a docs page.
MadeOnSol·· 13 min read
Disclosure: This article contains affiliate links. If you sign up through them, MadeOnSol may earn a commission at no extra cost to you. This never affects our rankings, ratings, or reviews.
If you are building anything on Solana that needs real-time data — trading bots, analytics dashboards, copy-trading systems, or token monitors — you have probably hit the limitations of traditional RPC polling. Calling getAccountInfo or getSignaturesForAddress in a loop is slow, wastes resources, and misses events between polls.
gRPC streaming solves this. Instead of asking the network "what changed?" every second, you tell it "notify me when something changes." The difference in latency, reliability, and efficiency is dramatic.
This guide explains how Solana gRPC streaming works, how to set it up using Yellowstone and Geyser plugins, and the practical patterns that power production applications.
This isn't theory for us. MadeOnSol runs a production Yellowstone gRPC pipeline across two regions (Frankfurt + New York), processing the full Solana DEX trade firehose and every buy and sell from 2,000+ tracked wallets in real time — hundreds of millions of swaps. The setup below is the standard path; the production gotchas near the end are the things that actually broke for us at scale and aren't in anyone's docs.
What Is Geyser and Why Does It Matter?
Geyser is Solana's plugin system for validators. It allows validators to stream real-time data about accounts, transactions, slots, and blocks to external consumers as they are processed — not after they are confirmed, not after you poll for them, but as they happen.
The Geyser interface defines several types of updates:
Account updates: Any account that changes state (balance, data, ownership)
Transaction notifications: Full transaction data including instructions, logs, and status
Slot updates: New slots being processed, confirmed, or finalized
Block metadata: Block-level information including rewards and timing
Without Geyser, the fastest way to detect a change is WebSocket subscriptions via accountSubscribe or logsSubscribe. These work but have significant limitations: connection instability, missing events during reconnection, no historical replay, and limited filtering capabilities.
Geyser plugins, particularly the Yellowstone gRPC plugin, solve all of these problems.
Yellowstone gRPC: The Standard
Yellowstone is the most widely adopted Geyser plugin implementation. Developed originally by Triton and now maintained as open source, it exposes Geyser data over a gRPC interface that clients can subscribe to with fine-grained filters.
How It Works
Solana Validator → Geyser Plugin → Yellowstone gRPC Server → Your Client
The data flow:
The validator processes a transaction that modifies an account
Building a product on Solana or Robinhood Chain data?
Skip the Geyser pipeline — embed KOL flow, deployer reputation, and the all-DEX firehose over REST, WebSocket, or webhooks. The Business tier (€400/mo) is the self-serve embed license at 500k calls/day — Enterprise adds white-label & redistribution.
Building a product on Solana or Robinhood Chain data?
MadeOnSol isn't an RPC or another generic token API — it's Solana & Robinhood Chain memecoin intelligence that's painful to build in-house, pulled from dual-region gRPC shred streams and our own Robinhood Chain node, pushed to your app as events land.
Signals you'd otherwise build
KOL & smart-money flow from 2,000+ labeled wallets, deployer reputation, coordination clusters, linked-wallet entity resolution, and an all-DEX firehose.
Embed it in your product
The Business tier (€400/mo, self-serve) licenses you to display MadeOnSol data inside your own product — 500k calls/day, 10 WS + 5 firehose connections. Enterprise above adds white-label & redistribution rights and custom endpoints.
Evaluate first, commit later
Test everything on a free ULTRA key — no commitment. If it fits, we scope volume or white-label pricing.
The Geyser plugin captures the account update and transaction data
Yellowstone serializes it into a protobuf message
Your gRPC client receives the update in real-time over a persistent connection
The latency from validator processing to your client receiving the data is typically 1-10 milliseconds, compared to 500-2000ms for RPC polling.
Key Advantages Over WebSocket RPC
Feature
WebSocket RPC
Yellowstone gRPC
Latency
100-500ms
1-10ms
Filtering
Basic (program, account)
Rich (memcmp, datasize, owner, txn type)
Reconnection
Lose events
Replay from slot
Throughput
~100 updates/sec
10,000+ updates/sec
Reliability
Connections drop frequently
Persistent with health checks
Backpressure
None (events dropped)
Built-in flow control
Setting Up a gRPC Connection
Prerequisites
You need access to a gRPC endpoint. The major providers offering Yellowstone gRPC:
Helius: gRPC access on their dedicated node plans. Helius has become the most popular choice for Solana gRPC due to their reliability and documentation.
Triton One: The original Yellowstone developers. Their infrastructure powers many high-frequency Solana applications.
QuickNode: Offers Yellowstone gRPC as an add-on to their Solana node plans.
Chainstack: Provides gRPC streaming on their dedicated Solana nodes.
Shyft: Offers gRPC streams as part of their data platform with additional parsing layers.
Basic Connection (Node.js)
import { Client } from '@triton-one/yellowstone-grpc';
const client = new Client(
'https://your-grpc-endpoint.example.com',
'your-auth-token'
);
const stream = await client.subscribe();
// Handle incoming updates
stream.on('data', (update) => {
if (update.account) {
console.log('Account updated:', update.account.account.pubkey);
}
if (update.transaction) {
console.log('Transaction:', update.transaction.transaction.signature);
}
});
// Subscribe to account updates for a specific program
await stream.write({
accounts: {
myFilter: {
owner: ['675kPX9MHTjS2zt1qfr1NYHuzeLXfQM9H24wFSUt1Mp8'], // Raydium AMM
filters: []
}
},
transactions: {},
slots: {},
blocks: {},
blocksMeta: {}
});
Subscription Filters
The power of Yellowstone gRPC is in its filtering. You can subscribe to exactly the data you need:
By account owner (program): Monitor all accounts owned by a specific program. This is how you watch all Raydium pools, all Pump.funbonding curves, or all token accounts for a specific mint.
By account pubkey: Monitor specific accounts by their public key. Useful for tracking a specific liquidity pool, a whale's token account, or a program's state account.
By memcmp filter: Match accounts whose data contains specific bytes at a specific offset. This lets you filter for token accounts holding a specific mint, or pool accounts containing a specific token pair.
By transaction reference: Monitor transactions that reference specific accounts in their account keys list. This captures all interactions with a specific program or account.
Common Streaming Patterns
Pattern 1: New Token Detection
To detect new tokens as they are created on Pump.fun:
When a new token is created, you receive the full transaction data including the mint address, deployer wallet, initial bonding curve parameters, and metadata URI — all within milliseconds of the transaction being processed.
Pattern 2: Whale Wallet Monitoring
Track a list of whale wallets for any token swaps:
Every transaction involving any of these wallets — swaps, transfers, program interactions — arrives at your client in real time. This is the same approach that powers copy-trading bots and smart money tracking tools.
Pattern 3: Liquidity Pool Monitoring
Monitor specific DEX pools for trades, liquidity additions, or removals:
// Monitor a specific Raydium pool account
await stream.write({
accounts: {
poolWatch: {
account: ['specific_pool_account_pubkey'],
owner: [],
filters: []
}
},
transactions: {},
slots: {},
blocks: {},
blocksMeta: {}
});
Every time the pool state changes (a swap occurs, liquidity is added or removed), you receive the updated account data. By parsing the pool's data layout, you can calculate the new price, reserves, and any other pool metrics in real time.
Performance Considerations
Connection Management
gRPC connections should be treated as long-lived. Do not open and close connections for each query. Instead:
Open a single connection at application startup
Implement reconnection logic with exponential backoff
Use gRPC keepalive pings to detect dead connections
Handle the GOAWAY frame gracefully (the server is shutting down — reconnect to another node)
Backpressure Handling
If your application cannot process updates as fast as they arrive, the gRPC stream will buffer them. If the buffer overflows, you will lose updates. To prevent this:
Process updates asynchronously — push them to an internal queue and process from the queue
Use a worker pool for CPU-intensive parsing
Drop or batch updates you do not need (e.g., if you only care about swaps, skip all other transaction types)
Filtering at the Source
The most important performance optimization is subscribing only to the data you need. Every additional filter you add reduces the volume of data your client must process. A common mistake is subscribing to all transactions for a program and filtering client-side — this works for low-throughput programs but will overwhelm your client for high-throughput ones like Jupiter or Raydium.
Not every application needs raw gRPC access. Several services provide higher-level abstractions:
Helius Webhooks: Helius lets you configure webhooks that trigger on specific on-chain events. You define the filter (program, account, transaction type) and Helius sends an HTTP POST to your endpoint when the event occurs. Simpler to set up than gRPC but higher latency (~200-500ms).
Shyft Callbacks: Similar to webhooks but with built-in transaction parsing. Shyft decodes the transaction data into human-readable format before sending it to your callback URL.
Jito Block Engine: For MEV-sensitive applications, Jito's block engine provides a separate stream of pending transactions from Jito validators, allowing you to see transactions before they are confirmed.
Production gotchas we learned the hard way
The setup above gets you a working stream. Keeping it alive and leak-free for months is where the real lessons are. These are the things that actually broke our pipeline at scale:
Reuse one client across reconnects — never new Client() per reconnect. The intuitive reconnection pattern (catch the error, construct a fresh client, re-subscribe) leaks sockets. Each new client opens new HTTP/2 connections and the old ones don't always close, so your file descriptors and memory climb until the process dies hours later. Construct the client once; on disconnect, just re-issue the subscription on the existing client.
Your TCP peer count is a multiple of your client count. A single Yellowstone client typically opens 2–3 TCP connections (HTTP/2 subchannels), so if you run two regional streams you'll see ~4–6 established peers, not 2. We alert on this directly — a peer count of 0 means the stream is dead, and a count climbing well past the expected multiple means a connection leak. Don't write a health check that assumes one client = one connection.
Watch RSS, not just V8 heap. The native (NAPI) layer of the gRPC client allocates off-heap. We hit a slow off-heap memory creep that never showed up in heap snapshots — the Node heap looked flat while the process RSS marched toward the OOM killer. If you can't pin the source, a scheduled restart every few hours is a legitimate mitigation; we run one and it's been the difference between stable and a 3am page.
Delete your reference to the raw protobuf message once you've extracted what you need. It's easy to stash the decoded update (or a field off it) on a long-lived object for later — and accidentally pin the entire message graph. At firehose volume that's gigabytes of retained memory in minutes. Copy out the primitive fields you need and let the message go.
Low-latency "deshred"-style streams only carry top-level instructions. Some providers offer a sub-150ms pre-confirmation stream (Triton's SubscribeDeshred and similar). It's fantastic for latency-critical signals, but it carries only the transaction's top-level instructions — inner/CPI instructions aren't there. That means bundled launches (where the real action is in inner instructions) are invisible on the deshred path; you still need the full transaction stream to see them. Use deshred for the latency-critical subset, not as your source of truth.
Filter at the source or drown. Worth repeating because it's the #1 cause of "my client can't keep up": subscribing broadly and filtering client-side works for a quiet program and falls over for Jupiter or Raydium. Push every filter you can into the subscription request.
Build vs. buy: skip the pipeline entirely
If you need the data rather than the infrastructure, you don't have to run any of this. The whole point of MadeOnSol's API is that we already run the dual-region gRPC pipeline, handle every gotcha above, and expose the result as plain REST + webhooks + a WebSocket firehose: live KOL/smart-money trades, the all-DEX trade stream, Pump.fun deployer events, and token risk, pushed as events land (measured detection latency on /benchmarks). For most teams, consuming a real-time Solana data API is hours of work; standing up and babysitting your own Yellowstone consumer is an ongoing operational commitment. Build it if real-time infra is your product; buy it if it's a means to an end. If DEX trades are the part you need, see normalized real-time Solana DEX data for bots, terminals and scanners. Our guide to embedding a Solana memecoin data API covers the access patterns — REST, WebSocket, webhooks, MCP — and the white-label path for shipping it inside your own product.
When to Use gRPC vs. Other Approaches
Use Case
Best Approach
Trading bot (sub-100ms latency needed)
gRPC direct
Analytics dashboard (1-5s updates fine)
WebSocket subscriptions
Alert system (notifications on events)
Webhooks (Helius/Shyft)
Historical analysis
RPC with pagination
Portfolio tracking
Polling + caching
gRPC is the right choice when latency matters and you need to process a high volume of updates reliably. For most analytics and monitoring use cases, webhooks or WebSocket subscriptions are simpler and sufficient.
Final Thoughts
Solana gRPC streaming through Yellowstone and Geyser plugins represents the lowest-latency, highest-reliability way to consume on-chain data. It is the infrastructure layer that powers the fastest trading bots, the most responsive dashboards, and the most accurate copy-trading systems on Solana.
The learning curve is steeper than RPC polling or WebSocket subscriptions, but the payoff is significant. If your application requires real-time data with guarantees about delivery and ordering, gRPC is the production-grade solution.
Start with a provider like Helius or Triton for managed gRPC access, build a simple subscriber for your use case, and iterate from there. The ecosystem's tooling has matured to the point where setting up a production gRPC consumer takes hours, not weeks.
FAQ
How much does gRPC access cost compared to standard RPC?
gRPC endpoints are significantly more expensive than standard RPC because they require dedicated validator infrastructure. Most providers offer gRPC on their highest-tier plans — expect to pay $200-500/month for a dedicated gRPC endpoint. Standard RPC plans start at $0-50/month. The cost is justified if your application requires sub-10ms latency and guaranteed event delivery.
Can I run my own Yellowstone gRPC node?
Yes, but it requires running a full Solana validator with the Geyser plugin installed. This means significant hardware (256GB+ RAM, fast NVMe storage, high-bandwidth connection) and operational expertise. For most teams, using a managed gRPC provider is more cost-effective than self-hosting. Self-hosting makes sense if you need custom filtering logic or want to avoid third-party dependencies. Bear in mind that the validator client itself moves fast — major releases can shift behavior and even cause network instability, as we documented in our writeup of the Agave 4.0 upgrade and the outages it caused.
When a connection drops, you miss updates during the disconnection period. Yellowstone supports replay from a specific slot number, allowing you to request all updates from the slot where you lost connection. Your client should track the last processed slot and use it as the starting point when reconnecting. This ensures no events are missed.
Most providers only offer gRPC streaming for mainnet-beta. If you need gRPC on devnet for testing, you will likely need to run your own validator with the Yellowstone plugin. An alternative for testing is to use mainnet gRPC with read-only subscriptions (monitoring without trading) to validate your parsing logic before deploying to production.