All articles
Strategies·April 17, 2026·7 min read

Jito vs Yellowstone gRPC: Which Data Pipeline for Solana Bots

Jito vs Yellowstone gRPC: bundles solve inclusion, Geyser streaming solves ingestion. Where each fits in a Solana bot pipeline, and when you need both.

A surprising number of teams building Solana bots ask "should we use Jito or Yellowstone gRPC" as if they're two vendors competing for the same job. They're not. Jito sits at the tail end of your pipeline, deciding whether your transaction lands and in what order. Yellowstone gRPC sits at the front, deciding how fast you learn something worth reacting to. Confusing the two is how teams end up with a bot that ingests data beautifully and then submits transactions through a plain RPC endpoint that gets outbid every single time.

What Yellowstone gRPC actually is

Yellowstone is Triton One's Geyser plugin exposed over gRPC (the "Dragon's Mouth" interface), and it's become the de facto standard for streaming Solana state changes. Instead of polling getAccountInfo or getProgramAccounts in a loop, you open a persistent gRPC stream and subscribe to filtered updates: specific accounts, all accounts owned by a program, transactions touching a given address, slot and block metadata. The validator pushes updates to you as it processes them, at processed commitment if you want the earliest (and least final) view.

This is ingestion. Yellowstone doesn't help you get a transaction on-chain — it has no concept of submission at all. It tells you what already happened, as close to real time as a validator's internal state allows.

A minimal subscribe request for account updates on a specific AMM pool looks like this in TypeScript against a Yellowstone endpoint:

const request: SubscribeRequest = {
  accounts: {
    pool: {
      account: [POOL_PUBKEY],
      owner: [],
      filters: [],
    },
  },
  slots: {},
  transactions: {},
  transactionsStatus: {},
  blocks: {},
  blocksMeta: {},
  entry: {},
  accountsDataSlice: [],
  commitment: CommitmentLevel.PROCESSED,
};

const stream = await client.subscribe();
stream.write(request);
stream.on("data", (update) => {
  if (update.account) handlePoolUpdate(update.account);
});

The gotcha nobody mentions in the docs: filter scope matters enormously for latency and cost. Subscribing to owner: [PROGRAM_ID] on a busy program like an AMM factory or a perps engine can push thousands of updates per second down one stream, and most providers meter by bytes or by connection tier. Scope filters to exact accounts wherever you can predict them, and only fall back to owner-based filters when you genuinely don't know which accounts matter yet (new pool creation, for example).

What Jito actually is

Jito is a modified validator client plus an off-chain auction system (the Block Engine) that lets you submit bundles — up to five transactions, executed atomically, in the order you specify, or not at all. You attach a tip, searchers compete on tip size across rolling sub-slot auction windows, and the winning bundles get forwarded to the leader for that slot. Jito also runs ShredStream, which forwards raw shreds to subscribers before the block is fully assembled, giving you a lower-latency (but rawer, undecoded) view of chain activity than any RPC-based feed.

Jito solves two problems Yellowstone doesn't touch at all: atomicity (your arb legs either all execute or none do) and inclusion priority (paying to jump the queue instead of hoping a priority fee is enough). Submitting a bundle looks roughly like this against the Block Engine's JSON-RPC:

const bundle = [tx1.serialize(), tx2.serialize(), tipTx.serialize()];
const res = await fetch(`${BLOCK_ENGINE_URL}/api/v1/bundles`, {
  method: "POST",
  body: JSON.stringify({
    jsonrpc: "2.0",
    id: 1,
    method: "sendBundle",
    params: [bundle.map((b) => bs58.encode(b))],
  }),
});

The gotcha here: a rejected or unlanded bundle gives you almost no signal about why. It might have lost the auction, simulated with an error against state that changed between your simulation and the leader's, or just missed the leader's slot window entirely. There's no on-chain trace of a bundle that never landed. You have to build your own retry-with-backoff and re-simulation logic, and budget tip size dynamically — a flat tip that wins during quiet hours gets steamrolled during a token launch.

Where each sits in the pipeline

on-chain state change
   -> Yellowstone gRPC / ShredStream   (you learn about it, 50-400ms)
   -> your strategy logic              (you decide what to do)
   -> Jito bundle / Block Engine       (you submit atomically, pay to win)
   -> leader slot                      (inclusion, or not)

Yellowstone (or Jito's own ShredStream, which competes with Yellowstone specifically on the ingestion side) answers "what just happened." Jito's bundle and auction system answers "how do I act on it without getting front-run in the ten milliseconds it takes for someone else to see the same thing." A bot that only has one of these is missing half the pipeline. If you're also weighing execution routers rather than raw ingestion, the tradeoffs are different again — we cover that ground in our comparison of Jupiter and Meteora as Solana routing layers.

Comparison table

Dimension Yellowstone gRPC Jito
Pipeline stage Ingestion (data in) Submission (transactions out)
Protocol gRPC streaming (Geyser/Dragon's Mouth) JSON-RPC to Block Engine + custom validator client
Primary guarantee Ordered, filtered stream of state changes Atomic multi-tx execution if bundle wins auction
Typical latency ~50-150ms slot-to-client, provider dependent Sub-slot auctions, roughly every ~200ms
Failure mode Dropped connection, backpressure, missed updates Bundle silently doesn't land, no error trace
Cost model Metered by data volume / connection tier Tip auction, variable and competitive
Do you need it for a passive dashboard Yes, this is the whole job No, irrelevant if you're not submitting
Do you need it for MEV/arb bots Yes, for detection Yes, for atomic, front-run-resistant execution

When you need both

Any bot doing more than passive monitoring needs both layers, just for different jobs. A cross-DEX arb bot needs Yellowstone (or ShredStream) to detect a price divergence within tens of milliseconds, and it needs Jito bundles to execute the buy-and-sell legs atomically with a tip baked into the same bundle — otherwise you're broadcasting your own arb to every other searcher watching the mempool-equivalent shred stream. A pure market-data dashboard or a trading UI, on the other hand, only needs the ingestion side; bundle submission is irrelevant if you're not sending transactions. We run into this split constantly when scoping strategy consultation engagements — half the initial design conversation is usually just correctly separating "how do we see it" from "how do we act on it."

One thing that trips up teams migrating from an RPC-polling architecture: your account-update handlers built for Yellowstone's push model don't map cleanly onto the pull-based mental model most people bring from web3.js. Retrofitting a trading dashboard originally built on polling to consume a gRPC stream usually means rewriting the state-reconciliation layer, not just swapping the data source. Budget time for that; it's not a drop-in replacement.

Bundle logic is also a common audit finding. We've reviewed bots where the tip transaction was constructed outside the atomic bundle, meaning a partial fill could pay the tip without executing the arb — an expensive bug that only shows up under specific race conditions. If your bundle-submission code hasn't had a second set of eyes on it, a code review and audit pass before mainnet is cheaper than the first bad slot. The same atomicity-under-adversarial-conditions problem shows up outside Solana too, similar in spirit to how CLOB settlement and oracle resolution interact on Polymarket — different chain, same category of "what happens between decision and finality" bug.

Verdict

Don't pick one. If you're building anything that submits transactions competitively on Solana, you need Yellowstone gRPC (or ShredStream) for detection and Jito for execution — they're sequential stages, not alternatives. The only real decision is which ingestion source to pair with Jito: use Yellowstone gRPC when you need decoded, filterable account and transaction data and can tolerate 50-150ms; use Jito's own ShredStream when you're latency-obsessed and willing to handle raw shred decoding yourself. And if your bot only watches state and never submits — a monitoring tool, a research dashboard, a backtester — skip Jito entirely; it adds submission complexity and tip-auction cost you'll never use. Get the architecture question straight before writing a line of strategy code, and if you want a second opinion on where your pipeline should split, talk to us about the strategy consultation before you build the wrong half twice.

Need a bot like this built?

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

Start a project
#Solana#MEV#Jito#Yellowstone gRPC#trading bots