// Guide
The Complete Guide to Solana gRPC from zero to streaming.
Everything you need to go from knowing nothing about gRPC to building real-time Solana applications that process transactions the instant they confirm. This guide covers the protocol, the architecture, the tooling, and the patterns used by the fastest trading bots on the network.
What is gRPC?
gRPC is a high-performance remote procedure call framework originally developed by Google. Unlike traditional REST APIs where the client sends an HTTP request and waits for a response, gRPC operates over HTTP/2 and uses Protocol Buffers (protobuf) as its serialization format. This means data is encoded in a compact binary format rather than verbose JSON text, and the underlying transport supports multiplexing multiple requests over a single TCP connection without head-of-line blocking. The result is dramatically lower overhead per message — both in bandwidth and in CPU time spent encoding and decoding.
The feature that makes gRPC transformative for blockchain applications is bidirectional streaming. A standard HTTP request is fire-and-forget: you ask, you wait, you get a response. With gRPC streaming, you open a persistent connection to the server, and data flows continuously in both directions. The server can push new data to your client the instant it becomes available — no polling, no reconnecting, no missed events. For a blockchain like Solana that produces a new slot roughly every 400 milliseconds, this persistent push model is the difference between seeing a transaction 5ms after it confirms and seeing it 800ms later through a polled JSON-RPC call.
For Solana specifically, gRPC matters because the chain produces an enormous volume of data. A single slot can contain thousands of transactions across hundreds of programs. Polling an RPC node for this data with getBlock or getTransaction is slow, rate-limited, and wasteful. gRPC gives you a firehose: a constant stream of everything happening on the network, delivered the moment the validator processes it, in an efficient binary format that your client can deserialize in microseconds.
Solana's Geyser Plugin Architecture
Solana validators are responsible for processing transactions, executing programs, and reaching consensus. But they also expose a plugin interface called Geyser that allows external code to receive a copy of all the data the validator processes — in real time, as it happens. Think of it as a tap on the validator's internal data pipeline. Every transaction, every account update, every slot notification gets forwarded to any registered Geyser plugin before the validator moves on to the next slot.
Yellowstone is the most widely used Geyser plugin. Developed by Triton, it takes the raw data from the Geyser interface and exposes it as a gRPC server. This means any gRPC client — written in Rust, Node.js, Python, Go, or any language with gRPC support — can connect to a Yellowstone-enabled node and receive a continuous stream of on-chain events. The data pipeline looks like this:
The types of data available through the Geyser plugin are comprehensive. Transaction notifications include the full transaction with all instructions, signatures, and execution results. Account notificationsfire whenever an account's data or lamport balance changes, giving you real-time state updates for any on-chain account. Slot notifications tell you when the validator processes, confirms, or finalizes a slot. Block metadata provides summary information about completed blocks. Entry notifications (available in newer versions) give you sub-block granularity, letting you see individual entries within a slot as they are processed.
This architecture is what makes low-latency Solana applications possible. Instead of polling an RPC endpoint and hoping you catch every event, you subscribe once and receive a continuous, ordered stream of everything happening on the chain. The challenge is that running your own Yellowstone node is operationally complex and expensive — which brings us to the setup section.
Setting Up a gRPC Client
The self-hosted approach
If you want to run your own Yellowstone gRPC endpoint, you need a full Solana validator or RPC node with the Yellowstone Geyser plugin compiled and loaded. This is not a trivial undertaking. The plugin is written in Rust and must be compiled against the exact version of the Solana validator you're running — a version mismatch between the plugin and the validator will crash your node on startup. You'll need a Rust toolchain, the protobuf compiler, and familiarity with Solana's build system.
The hardware requirements are steep. A production Solana RPC node typically needs 256GB or more of RAM, high-end NVMe storage (4TB+ recommended for accounts and ledger data), and a multi-core CPU capable of handling the validator's processing load alongside the Geyser plugin's data serialization work. Running Yellowstone on top adds memory overhead for buffering and gRPC connection state. You're looking at a monthly infrastructure cost of $1,500 to $3,000 depending on your provider and colocation choices.
Beyond the initial setup, there's ongoing operational burden. Solana releases new validator versions frequently, and each upgrade requires recompiling the Yellowstone plugin. The Geyser plugin configuration file needs careful tuning — buffer sizes, connection limits, and filter parameters all affect performance and stability. If the plugin falls behind the validator (backpressure), it can cause the validator itself to stall, which means you need monitoring, alerting, and a runbook for remediation. For teams whose core competency is building trading bots, not operating infrastructure, this operational overhead is a significant distraction.
Using a provider (Subglow)
The alternative is connecting to a managed gRPC provider that handles the validator, the Geyser plugin, and the infrastructure for you. With Subglow, the entire setup is three lines of code. You get the same real-time stream of on-chain events, but you also get server-side filtering (only the programs you care about) and pre-parsed JSON output (no Borsh deserialization on your end). The connection is authenticated with an API key, and you're streaming within seconds of signing up.
const client = new Subglow({
url: "grpc.subglow.io:443",
apiKey: process.env.SUBGLOW_API_KEY,
filter: ["pump_fun", "raydium"],
});
client.subscribe((tx) => {
console.log(tx.program, tx.type, tx.parsed);
});That's the complete client. No protobuf compilation, no Rust toolchain, no validator operations. You receive structured JSON events for only the programs you specified — everything else is filtered at the source before it reaches your network.
Subscribing to Transaction Streams
Yellowstone gRPC exposes several subscription types, each serving a different use case. Understanding which subscription to use — and how to configure it — is critical for building efficient real-time applications.
Transaction subscriptions
The most common type. You subscribe to transactions that involve specific programs, specific accounts, or all transactions on the network. Each notification includes the full transaction with all instructions, signatures, log messages, and execution status. This is what you use for trading bots, analytics, and most real-time applications.
Account subscriptions
Watch specific accounts for state changes. Every time an account's data is modified — whether it's a token balance change, a program state update, or a lamport transfer — you receive a notification with the new account data. Useful for monitoring wallets, tracking liquidity pool reserves, or watching program state.
Slot subscriptions
Track the chain's progress in real time. Receive notifications when slots are processed, confirmed, and finalized. Essential for monitoring your application's lag relative to the chain tip and for implementing confirmation-level logic in your trading systems.
Here's a practical example: subscribing to all Pump.fun transactions through Subglow. This captures every token creation, buy, sell, and migration event on the Pump.fun bonding curve program.
const client = new Subglow({
url: "grpc.subglow.io:443",
apiKey: process.env.SUBGLOW_API_KEY,
filter: ["pump_fun"],
});
client.subscribe((event) => {
if (event.type === "token_create") {
console.log("New token:", event.parsed.name, event.parsed.symbol);
console.log("Creator:", event.parsed.creator);
console.log("Mint:", event.parsed.mint);
}
if (event.type === "buy") {
console.log("Buy:", event.parsed.sol_amount, "SOL");
console.log("Bonding curve:", event.parsed.bonding_curve_pct + "%");
}
});Filtering Strategies
The Solana network processes tens of millions of transactions per day. The vast majority of these are irrelevant to any given application — system program transfers, token program operations, oracle updates, governance votes, and countless other activities. How you filter this firehose determines both your application's performance and your infrastructure costs.
Client-side filtering
The naive approach: subscribe to everything, then discard what you don't need in your application code. This is how most raw Yellowstone connections work. The problem is that you receive the entire Solana firehose — every transaction from every program — and your client must deserialize, inspect, and discard over 99% of it. This consumes enormous bandwidth (gigabytes per hour), wastes CPU cycles on deserialization of data you immediately throw away, and increases your application's memory footprint. For latency-sensitive applications like trading bots, the time spent processing irrelevant transactions directly delays your reaction to relevant ones.
Server-side filtering (Subglow's approach)
The efficient approach: filtering happens at the source, before data leaves the infrastructure. When you connect to Subglow with a filter for Pump.fun and Raydium, our infrastructure processes the full Solana stream internally and only forwards transactions that match your specified programs. Your client receives a fraction of the total data volume, and every event it receives is relevant. This reduces bandwidth by 95-99%, eliminates wasted CPU, and means your bot's decision loop starts processing actionable data immediately rather than sifting through noise.
Program ID filters
The most common filter type. Subglow supports named filters for the most popular DeFi programs: pump_fun for Pump.fun bonding curve events, raydium for Raydium v4/v5 AMM swaps and pool events, and jupiter for Jupiter aggregated swap routes. You can combine multiple filters in a single subscription — for example, subscribing to both Pump.fun and Raydium to capture tokens as they launch on the bonding curve and then migrate to a Raydium AMM pool.
Custom filters (Pro tier)
For applications that need data from programs beyond the built-in set, Subglow's Pro tier supports custom Program ID filters. Supply any valid Solana program address, and transactions involving that program will be included in your stream. This is useful for monitoring newer protocols, custom on-chain programs, or niche DeFi applications that aren't covered by the standard filter set.
Parsing Transaction Data
Raw Solana transactions are not human-readable. The instruction data for each program is encoded using Borsh (Binary Object Representation Serializer for Hashing), a compact binary serialization format. To understand what a transaction actually does — whether it's a token buy, a pool creation, or a liquidity add — you need to deserialize the instruction data using the program's IDL (Interface Definition Language) and then map instruction discriminators to their corresponding operation types.
This is harder than it sounds. Each program has its own serialization schema. Pump.fun's instruction format is different from Raydium's, which is different from Jupiter's. You need the correct IDL for each program version, you need to handle edge cases like CPI (cross-program invocation) inner instructions, and you need to maintain your deserialization code as programs upgrade. Many teams spend weeks building and debugging Borsh deserializers before they can reliably extract meaningful data from raw transactions.
Subglow handles all of this server-side. Instead of receiving raw bytes and building your own deserialization pipeline, you receive pre-parsed JSON with labeled fields. Here's the difference:
// Raw Borsh bytes
Buffer <66 06 3d 12 aa 01 c8 f4 02 00 00 00 00 00 00 00 40 4b 4c 00 00 00 00 00 8a 02 00 00 00 00 00 00 e8 03 00 00 00 00 00 00 01 00 00 00 f4 01 00 00>
Requires the program's IDL, a Borsh deserializer, discriminator mapping, and account resolution to interpret.
// Subglow parsed JSON
{
"program": "pump_fun",
"type": "buy",
"signature": "3xF9...kQ2v",
"slot": 284391204,
"parsed": {
"mint": "7xKXtg...sgAsU",
"sol_amount": 2.45,
"token_amount": 1284903,
"bonding_curve_pct": 34.2,
"buyer": "Dv3F8...9xKp"
},
"slot_lag_ms": 4
}Ready to consume. Every field labeled, amounts converted, accounts resolved. Feed directly into your trading logic.
Building a Real-Time Application
Let's put everything together and build a practical example: a Pump.fun new token monitor that watches for token creations, evaluates them against a set of criteria, and alerts you when something interesting launches. This is the foundation of most sniper bots — they start by watching for token create events, then decide whether to enter a position.
The flow is straightforward. Connect to Subglow's gRPC endpoint, subscribe to Pump.fun events, filter for token_create events, evaluate the token's metadata, and take action.
const client = new Subglow({
url: "grpc.subglow.io:443",
apiKey: process.env.SUBGLOW_API_KEY,
filter: ["pump_fun"],
});
client.subscribe((event) => {
if (event.type !== "token_create") return;
const { name, symbol, creator, mint } = event.parsed;
const creatorHistory = await getCreatorStats(creator);
if (creatorHistory.rugs > 2) return;
if (name.length < 3 || symbol.length < 2) return;
console.log(`New token: ${name} (${symbol})`);
console.log(`Creator: ${creator} (history: ${creatorHistory.launches} launches)`);
console.log(`Mint: ${mint}`);
await sendAlert({ name, symbol, creator, mint });
});This example demonstrates the core pattern: receive a structured event, inspect its fields using plain JavaScript object access (no deserialization), apply your business logic, and act. The event.parsed object already contains the token name, symbol, creator wallet, and mint address as typed fields. You can extend this with on-chain lookups, social sentiment analysis, or direct trade execution — the streaming foundation stays the same.
For a production sniper bot, you would add trade execution logic after the filtering step: construct a swap instruction, sign it, and submit it to a bundle service or the validator directly. The speed advantage is significant — because Subglow delivers the event pre-parsed and server-filtered, your bot can begin evaluating the token within single-digit milliseconds of slot confirmation.
Performance Optimization
Receiving real-time data is only half the challenge. How you process that data determines whether your application can keep up with Solana's throughput. Here are the patterns that production-grade trading systems use.
Keep streams persistent
Never tear down and re-establish a gRPC connection for each query. The TCP handshake, TLS negotiation, and HTTP/2 connection setup add hundreds of milliseconds of latency. Open your stream once at application startup and keep it open for the lifetime of your process. Implement reconnection logic that fires automatically if the stream drops, with exponential backoff to avoid thundering herd problems.
Process events asynchronously
Your event handler should return as fast as possible. If you need to make external calls (checking creator history, looking up token metadata, submitting trades), push the event into an async processing queue and let the handler return immediately. This prevents slow processing of one event from delaying the receipt of subsequent events. In Node.js, this means avoiding await in your hot path unless absolutely necessary.
Use connection pooling
If your application needs multiple independent streams — for example, one for Pump.fun events and one for Raydium pool creates — use separate gRPC connections for each. This isolates backpressure: a slow consumer on one stream won't affect the delivery rate of another. With Subglow, each connection authenticates independently, so you can allocate different processing resources to each stream based on its priority.
Monitor slot lag
Every Subglow event includes a slot_lag_ms field indicating the time between slot confirmation and event delivery. Track this metric. If it starts climbing, it means either your client is processing too slowly (building backpressure) or there's a network issue. A healthy stream should maintain single-digit millisecond lag. Double- digit lag warrants investigation; triple-digit lag means your bot is making decisions on stale data.
Common Pitfalls
Every team building on Solana gRPC runs into these issues eventually. Understanding them upfront saves you hours of debugging in production.
Not handling reconnections
gRPC streams will drop. Networks have hiccups, servers restart for upgrades, and load balancers rotate connections. If your application treats the stream as a permanent fixture and doesn't implement reconnection logic, it will silently stop receiving data after the first disconnection. Always implement an automatic reconnection handler with exponential backoff. Log every disconnect with the reason code so you can distinguish transient network issues from authentication failures or server-side errors.
Blocking the event loop
In Node.js, synchronous operations in your event handler block the entire event loop. This means while your code is doing CPU-intensive work — parsing large JSON objects, computing trade parameters, or performing crypto operations — incoming gRPC events pile up in the buffer. If the buffer fills, you experience backpressure and eventually dropped events. Move heavy computation to worker threads or a separate process. Keep your event handler lightweight: receive the event, make a fast decision, and offload everything else.
Over-filtering
It's tempting to create very narrow filters to minimize data volume. But overly specific filters can cause you to miss events you need. For example, filtering only for Pump.fun buy events means you miss token_create events — you can't snipe a token if you don't know it was created. Start with broader filters and narrow them once you understand the full event landscape for your use case.
Ignoring backpressure
gRPC has built-in flow control. If your client can't consume events as fast as the server produces them, the server will slow down delivery (backpressure). If this continues, the server may eventually disconnect your client. Backpressure is a signal that your processing pipeline is the bottleneck, not the network. The fix is faster processing, not a bigger buffer. Profile your event handler, identify the bottleneck, and optimize or parallelize it.
Not monitoring stream health
A gRPC stream can be technically connected but functionally broken — receiving events with increasing delay, or receiving events from a stale fork. Implement health checks that go beyond “is the connection open.” Track the slot number of incoming events and compare it to the network tip. Track event delivery rate and alert if it drops below expected thresholds. Track slot_lag_ms and alert if it exceeds your tolerance. A bot trading on data that's 500ms stale is worse than a bot not trading at all.
Next Steps
You now have a solid understanding of how Solana gRPC works, how the Geyser plugin architecture delivers real-time data, and how to build applications on top of it. Here's where to go from here.
API Reference
Complete documentation for the Subglow gRPC API, including all subscription types, filter options, and response schemas.
Read the docs →Sniper Bot Guide
Step-by-step guide to building a Pump.fun sniper bot using Subglow's filtered gRPC streams.
Build a sniper →Copy Trading Guide
Learn how to track whale wallets and mirror trades in real time using account and transaction subscriptions.
Set up copy trading →Plans & Pricing
Compare Sniper, Pro, and Dedicated tiers. Find the plan that fits your trading operation.
View pricing →Start streaming in 5 minutes.
Create an account, grab your API key, and connect to real-time Solana data. Free trial available — no credit card required.