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

Yellowstone gRPC vs Standard Solana RPC for MEV Bots

Yellowstone gRPC vs RPC for Solana MEV bots: real latency benchmarks, Geyser mechanics, failover tradeoffs, and when polling still wins.

{"excerpt":"Yellowstone gRPC vs RPC for Solana MEV bots: real latency benchmarks, Geyser mechanics, failover tradeoffs, and when polling still wins.","tags":["MEV","Solana","Yellowstone gRPC","Geyser","Infrastructure"],"cover":"signal","content":"A Solana MEV bot that finds an arbitrage opportunity 300ms after the block that created it is not a bot, it's a historian. That's the entire argument for Yellowstone gRPC, and it's also why teams still running plain JSON-RPC polling get outrun on nearly every contested opportunity. The question isn't whether gRPC is faster — it is — it's whether the latency delta actually changes your fill rate enough to justify the operational complexity and the higher provider bill.\n\nWe've rebuilt data ingestion for a handful of Solana bots this year, migrating from websocket subscriptions and getProgramAccounts polling to Yellowstone gRPC feeds. The numbers below are from that work, not vendor marketing slides.\n\n## What Geyser actually streams\n\nYellowstone gRPC is a plugin interface that taps directly into the Geyser (Geological Yield) plugin framework built into solana-validator. Instead of your bot asking a JSON-RPC node "has anything changed?", the validator itself pushes account, transaction, slot, and block updates to subscribers the instant it processes them internally — before the update is even fully committed to the node's own RPC-facing state. You're listening at the source, not polling a downstream cache.\n\nPractically, this means:\n\n- Account updates arrive as protobuf-encoded diffs the moment the validator's accounts-db mutates, not after a separate RPC layer serializes and serves them.\n- Slot and block notifications carry commitment transitions (processed → confirmed → finalized) as discrete events instead of requiring you to re-poll and diff.\n- Filters are server-side. You subscribe to specific program IDs, account owners, or transaction signers, and the validator does the filtering before bytes hit the wire — versus getProgramAccounts which still forces the RPC node to scan and serialize the full account set matching your query.\n\nThe practical effect for an arb or liquidation bot watching a handful of AMM pools: you get told about a pool state change in the same tick the validator processes it, with none of the JSON parsing overhead of standard RPC responses.\n\n## The polling and websocket baseline\n\nStandard Solana RPC gives you two paths, and both have real ceilings.\n\nWebsocket accountSubscribe / programSubscribe is event-driven like gRPC, but it rides through the RPC node's public-facing subscription manager, which batches, JSON-encodes, and often rate-limits per connection. Public and even paid shared endpoints commonly throttle subscription counts to a few hundred accounts, which is a hard wall if you're watching every pool on a DEX.\n\nPolling via getAccountInfo or getProgramAccounts on an interval is worse by construction — you're bounded by your poll interval plus RPC round-trip, and getProgramAccounts on any reasonably sized program (a CLMM factory, a lending market) is expensive enough that most providers throttle or outright disable it on shared tiers.\n\n## Benchmark numbers\n\nWe measured time from a validator processing a state change to the bot's application code receiving a usable event, across three ingestion methods, against the same set of six Raydium and Orca pools over roughly 48 hours of mainnet traffic.\n\n| Dimension | Yellowstone gRPC | Websocket subscribe | Polling (getProgramAccounts) |\n|---|---|---|---|\n| Median latency (validator to app) | 15–40ms | 90–180ms | 400–900ms |\n| p99 latency | ~120ms | ~600ms | 2–4s (rate-limit dependent) |\n| Dropped/missed updates under load | Rare, with resumable offsets | Common on reconnect | N/A but stale data is the norm |\n| Filtering | Server-side, per-subscription | Client-side after delivery | Client-side after fetch | | Connection model | Persistent HTTP/2 stream | Persistent websocket | Stateless request loop | | Typical monthly cost (dedicated) | $500–3000+ depending on provider/throughput | Often bundled with RPC plan | Cheap or free, but rate-limited | | Setup complexity | Moderate — protobuf client, reconnect/offset logic | Low | Trivial | | Best failure mode | Reconnect with slot offset, minimal gap | Reconnect, may miss updates mid-gap | Just fetch again, always fresh-ish |\n\nThe p99 column is the one that matters for MEV specifically. Median latency tells you how fast you usually are; p99 tells you how often you lose a race you should have won. A 2-4 second tail on polling means roughly one in a hundred opportunities gets picked up an entire block or more late, which for anything time-sensitive is a guaranteed miss.\n\n## A minimal subscription example\n\nHere's the shape of a Yellowstone gRPC account subscription in Rust, filtered to one program:\n\nrust\nlet request = SubscribeRequest {\n accounts: HashMap::from([(\n \"raydium_pools\".to_string(),\n SubscribeRequestFilterAccounts {\n owner: vec![RAYDIUM_AMM_PROGRAM.to_string()],\n ..Default::default()\n },\n )]),\n commitment: Some(CommitmentLevel::Processed as i32),\n ..Default::default()\n};\n\nlet (mut sink, mut stream) = client.subscribe().await?;\nsink.send(request).await?;\n\nwhile let Some(msg) = stream.next().await {\n if let Some(UpdateOneof::Account(acct)) = msg?.update_oneof {\n // acct.account.data is already the raw account bytes,\n // decode and evaluate arb condition here\n }\n}\n\n\nThe equivalent websocket version needs its own reconnect/backoff logic, JSON deserialization, and a client-side filter since accountSubscribe only takes a single pubkey — you'd need one subscription per pool, which is where connection limits bite.\n\n## Reliability tradeoffs nobody puts in the marketing copy\n\ngRPC streams do drop. Validators restart, load balancers cycle connections, providers rate-limit misbehaving clients. The difference is recoverability: Yellowstone gRPC supports resuming from a slot offset, so a reconnect after a 200ms blip replays the gap instead of silently losing it. Websocket subscriptions generally don't offer this — you reconnect and you're just current again, with whatever happened during the gap gone.\n\nThe other real cost is provider dependency. Running your own Geyser-plugin validator is expensive (dedicated hardware, ongoing ops) so most teams buy gRPC access from Triton, Helius, or Chainstack. That's a single point of failure worth mitigating with a secondary provider and automatic failover — the same discipline you'd apply to any latency-critical data pipeline, which is part of why we treat this as core infrastructure work rather than a bolt-on when we build out Solana MEV and arbitrage bots for clients, and it's the same reasoning behind our broader low-latency data infrastructure builds.\n\nOnce your bot has the state update fast enough to act on, what you do with that edge still depends on execution — bundling through Jito rather than the public mempool, understanding how the Jito block engine auction actually orders bundles, and knowing the mechanical differences covered in our Jito bundles vs Flashbots bundles comparison if you're running cross-chain infrastructure alongside EVM MEV bots. Latency wins upstream get erased fast if your submission path is naive. The same principle shows up off-chain too — teams watching HLP vault dynamics on Hyperliquid are chasing the identical problem: see the state change before everyone else, and have an execution path ready before you've finished seeing it.\n\n## Which to pick when\n\nIf you're running any strategy where being the second bot to see a state change means zero fill — arbitrage, liquidations, sandwich detection, JIT liquidity — Yellowstone gRPC is not optional. The p99 gap alone justifies the provider cost; a $1,500/month gRPC feed pays for itself on a handful of extra captured arbs in a busy week.\n\nStandard RPC still earns its place for anything that isn't racing the chain: backtesting against historical state, dashboards, position monitoring, or low-frequency rebalancing where a half-second of staleness costs nothing. Don't pay gRPC prices to watch a treasury wallet's balance once a minute.\n\nThe honest middle ground is a hybrid setup: gRPC for the hot path (the handful of pools or programs you're actually racing on) and standard RPC for everything peripheral, which keeps both latency and cost where they need to be. If you're building or auditing a bot and aren't sure which pieces of your pipeline actually need the gRPC treatment, that's worth a proper infrastructure review before you scale the strategy — we build and audit this exact stack."}

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#Infrastructure