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.
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
- 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.fun bonding 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:
// Subscribe to transactions involving the Pump.fun program
await stream.write({
transactions: {
pumpFunTx: {
accountInclude: ['6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P'], // Pump.fun
accountExclude: [],
accountRequired: []
}
},
accounts: {},
slots: {},
blocks: {},
blocksMeta: {}
});
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:
const whaleWallets = [
'wallet1_pubkey',
'wallet2_pubkey',
// ... more wallets
];
await stream.write({
transactions: {
whaleWatch: {
accountInclude: whaleWallets,
accountExclude: [],
accountRequired: []
}
},
accounts: {},
slots: {},
blocks: {},
blocksMeta: {}
});
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.
Alternatives to Self-Managed gRPC
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.
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.
What happens if my gRPC connection drops?
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.
Is gRPC streaming available for Solana devnet and testnet?
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.