All articles
MEV·May 13, 2026·6 min read

Yellowstone gRPC vs Geyser: Streaming Solana Mempool for MEV

Wiring Yellowstone gRPC Solana mempool subscriptions to catch MEV before block inclusion — Geyser vs polling RPC, with real latency and cost tradeoffs.

Solana has no mempool in the Ethereum sense. There is no public pool of pending transactions sitting around waiting to be mined, because leaders forward transactions to each other over Turbine and QUIC and pack them into blocks with sub-second slot times. So when someone says "streaming the Solana mempool for MEV," what they actually mean is: get as close as possible to the flow of account writes and transactions at the moment the leader is processing them, before the block is finalized and broadcast. That "before" window is where the whole game lives, and Yellowstone gRPC is the tool most searchers reach for to see into it.

What Yellowstone gRPC and Geyser actually are

Geyser is the plugin interface baked into the validator. It's a set of callbacks — update_account, notify_transaction, update_slot_status — that fire synchronously inside the validator's banking and replay stages as state changes. A Geyser plugin is a .so you load via --geyser-plugin-config, and it gets fed a firehose of every account write and every transaction the validator sees, at the speed the validator sees them.

Yellowstone gRPC (the yellowstone-grpc project from Triton One, often shipped as the Dragon's Mouth interface) is a Geyser plugin that takes that firehose and exposes it over a gRPC streaming API with server-side filtering. Instead of writing Rust and running your own validator, you open a bidirectional gRPC stream, send a SubscribeRequest describing what you care about, and receive typed protobuf messages. That distinction matters for cost, which I'll get to.

So the mental model is: Geyser = the raw in-process tap; Yellowstone = Geyser packaged as a network service you can subscribe to remotely. They're not competitors. Yellowstone is a Geyser plugin. The real decision is whether you run your own validator with a Geyser plugin, or subscribe to someone else's Yellowstone endpoint.

Why this beats polling RPC

If you're detecting opportunities with getProgramAccounts polling or even WebSocket accountSubscribe, you're already late. Public WebSocket account notifications are debounced and batched, and standard JSON-RPC gives you confirmed state — which is one or more slots behind where the leader already is. For an arb or liquidation, one slot is the difference between landing the transaction and eating a stale-quote revert.

Yellowstone streams processed-level commitment. You see an account write essentially as the banking stage commits it, before confirmation, before the block ships. In practice that's a 100–400ms head start over confirmed WebSocket notifications, and it's push, so you're not burning RPC credits polling a pool 20 times a second and mostly getting the same bytes back. That latency edge is exactly what makes CLMM backruns and JIT plays viable on Solana; the same principle we lean on for JIT liquidity provisioning on Meteora DLMM, where you have to react to a swap's account writes inside the same slot it lands.

Wiring a subscription

A SubscribeRequest lets you filter on the server side by account owner, by specific pubkeys, and by transaction account inclusion. The trick to keeping latency low is filtering hard — every byte the server sends you is a byte you have to deserialize on the hot path. Here's a Rust sketch subscribing to the Raydium AMM program's account writes plus any transaction that touches it:

let request = SubscribeRequest {
    accounts: HashMap::from([("raydium".into(), SubscribeRequestFilterAccounts {
        owner: vec![RAYDIUM_AMM_V4.to_string()],
        ..Default::default()
    })]),
    transactions: HashMap::from([("ray_txns".into(), SubscribeRequestFilterTransactions {
        account_include: vec![RAYDIUM_AMM_V4.to_string()],
        vote: Some(false),
        failed: Some(false),
        ..Default::default()
    })]),
    commitment: Some(CommitmentLevel::Processed as i32),
    ..Default::default()
};

let (mut sink, mut stream) = client.subscribe().await?;
sink.send(request).await?;

while let Some(msg) = stream.next().await {
    match msg?.update_oneof {
        Some(UpdateOneof::Account(a)) => on_account_write(a),   // pool reserves changed
        Some(UpdateOneof::Transaction(t)) => on_txn(t),         // decode instruction data
        Some(UpdateOneof::Ping(_)) => sink.send(ping_response()).await?,
        _ => {}
    }
}

Two things bite people here. First, you must answer pings. Yellowstone sends periodic pings and will drop your stream if you don't echo them — I've watched people blame "server instability" for what was a missing ping handler. Second, account updates and transaction updates race. You'll frequently get the account-write for a pool before the transaction that caused it, or vice versa, because they're emitted from different validator stages. If your strategy needs both, buffer by slot and reconcile, don't assume ordering.

For transaction decoding, remember the payloads are raw. You get the message, the account keys, and instruction data as bytes. You decode instruction discriminators yourself — this is where an Anchor IDL or hand-rolled Borsh layouts for the programs you target earns its keep. Getting that decode layer fast and correct is most of the real work, and it's the part we spend the most time on when building Solana MEV and arbitrage bots.

The cost and latency tradeoff

Here's the honest accounting.

  • Subscribe to a hosted Yellowstone endpoint (Triton, Helius, Shyft, etc.): roughly $500–$2,000/month depending on filter throughput and dedicated vs shared. Zero ops. But you inherit their geography and their egress path, adding 5–30ms of network latency, and you're one hop behind a colocated searcher.
  • Run your own validator with the Geyser plugin: you get the tap in-process, zero network hop, and you can colocate next to leaders. Cost is a real validator box (256GB+ RAM, fast NVMe, decent bandwidth) plus a voting or non-voting node, so $1,500–$4,000/month in hardware alone, plus operational pain. Non-voting is fine and cheaper — you don't need to vote to see the stream.

The latency delta between "hosted Yellowstone in a random datacenter" and "own non-voting node colocated in the same facility as active leaders" is on the order of 20–80ms. For pure arb that survives a slot or two, hosted is completely fine and I'd start there. For time-sensitive sandwich-adjacent or JIT strategies where you're racing other searchers into the same slot, that delta decides who wins, and you'll want your own node. The same reasoning applies on the EVM side of the desk when we build EVM MEV bots and cross-venue arbitrage systems — the streaming source and its physical location is the edge, not the strategy math.

Seeing the opportunity is only half of it. Yellowstone tells you a swap is landing; it does nothing to help your response transaction win. On Solana that means you still need Jito bundles or a low-latency send path, and it's worth reading how Helius, Temporal, and Jito compare for MEV protection and inclusion before you assume detection equals execution. If you want to shave latency further on the ingest side, Jito ShredStream gives searchers an even earlier view — shreds arrive before the assembled block does, which for some strategies beats even processed-commitment Yellowstone.

What I'd actually do

Start with a hosted Yellowstone endpoint, filter aggressively to only the programs you trade, and get your instruction-decode and reconciliation layer rock solid. Measure your end-to-end latency from account-write to transaction-sent. If you're consistently losing races to faster searchers and the money justifies it, then colocate a non-voting node with the Geyser plugin. Don't buy the validator first — most teams discover their bottleneck is decode logic or their send path, not the 30ms of endpoint latency they were obsessing over.

If you're weighing whether to build this in-house or want the decode-and-reconcile layer built right the first time, that's exactly the kind of low-latency Solana MEV infrastructure we build for a living.

Need a bot like this built?

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

Start a project
#MEV#Solana#Yellowstone gRPC#Geyser#low-latency